Cách sử dụng lệnh Nohup trong Linux

Tác giả sysadmin, T.Một 26, 2024, 08:59:26 SÁNG

« Chủ đề trước - Chủ đề tiếp »

0 Thành viên và 2 Khách đang xem chủ đề.

Cách sử dụng lệnh Nohup trong Linux


Khởi chạy các tiến trình không bị treo máy. Lệnh Linux nohupcho phép các quy trình quan trọng tiếp tục chạy ngay cả khi cửa sổ đầu cuối khởi chạy chúng bị đóng. Chúng tôi chỉ cho bạn cách sử dụng lệnh đáng kính này trên Linux ngày nay.

1. HUP và SIGHUP

Unix, tổ tiên của Linux, được tạo ra trước khi PC được phát minh. Máy tính là những thiết bị lớn và đắt tiền. Mọi người tương tác với họ qua các đường dây nối tiếp cục bộ trong cùng một tòa nhà hoặc từ xa qua kết nối modem chậm. Ban đầu, họ gõ hướng dẫn trên máy điện báo, dần dần được thay thế bằng thiết bị đầu cuối câm.

Chúng được gọi là ngu ngốc vì sức mạnh xử lý nằm trong máy tính mà bạn kết nối chứ không phải thiết bị đầu cuối bạn đang gõ. Các chương trình đang chạy trên máy tính --- ở bất cứ nơi nào có thể được đặt --- chứ không phải trên thiết bị trên bàn của bạn.

Nếu có điều gì đó xảy ra làm đứt kết nối giữa thiết bị đầu cuối của bạn và máy tính, máy tính sẽ phát hiện hiện tượng rớt đường truyền và gửi tín hiệu HUP hoặc treo tín hiệu đến các chương trình bạn đang chạy. Các chương trình ngừng thực hiện khi nhận được tín hiệu.

Chức năng đó vẫn tồn tại trong Linux ngày nay. Trên PC của bạn, cửa sổ terminal là mô phỏng của terminal vật lý. Nếu bạn có các tiến trình đang chạy được khởi chạy từ cửa sổ terminal đó và bạn đóng cửa sổ đó thì SIGHUP

tín hiệu được gửi đến các chương trình để chúng được thông báo về HUP và biết rằng chúng nên chấm dứt.

Có một hiệu ứng xếp tầng diễn ra. Nếu các tiến trình đã khởi chạy bất kỳ tiến trình con nào thì SIGHUP cũng được truyền xuống dòng này để chúng biết rằng chúng nên chấm dứt.

Lệnh nohup khởi chạy các tiến trình con nhưng từ chối chuyển tín hiệu SIGHUP cho chúng. Điều đó nghe có vẻ như là một vấn đề nhưng thực ra đây là một chức năng hữu ích.

2. Lệnh nohup

Nếu bạn muốn quá trình tiếp tục ngay cả khi cửa sổ đầu cuối khởi chạy nó bị đóng, bạn cần có cách chặn SIGHUP để chương trình không bao giờ nhận được nó. (Trên thực tế, cửa sổ terminal không khởi chạy các tiến trình, chúng được khởi chạy bởi phiên shell bên trong cửa sổ terminal.) Giải pháp đơn giản và hiệu quả cho vấn đề đó là đặt một tiến trình khác giữa phiên shell và chương trình, và thực hiện điều đó chương trình lớp giữa không bao giờ truyền tín hiệu SIGHUP.

Đó là những gì nohup làm được. Nó khởi chạy các chương trình cho bạn để chúng là tiến trình con của nohup, không phải tiến trình con của shell. Vì chúng không phải là tiến trình con của shell nên chúng sẽ không trực tiếp nhận được SIGHUP từ shell. Và nếu nohup không truyền SIGHUP cho chương trình con, chương trình sẽ không nhận được SIGHUP.

Điều này rất hữu ích, chẳng hạn như khi bạn có một quy trình chạy dài mà bạn cần cho phép chạy cho đến khi hoàn thành. Nếu bạn vô tình đóng cửa sổ terminal và shell của nó, bạn cũng sẽ chấm dứt quá trình. Việc sử dụng nohup để khởi chạy quy trình sẽ tách biệt quy trình khỏi nohuptín hiệu. Nếu bạn đang làm việc từ xa trên máy tính qua SSH và không muốn một quy trình nhạy cảm chấm dứt nếu kết nối từ xa không thành công, bạn nên bắt đầu quy trình trên máy tính từ xa bằng nohup.

3. Sử dụng nohup

Chúng tôi đã tạo một chương trình không làm được điều gì hữu ích nhưng nó sẽ chạy và chạy cho đến khi bị chấm dứt. Nó in thời gian ra cửa sổ terminal cứ sau ba giây. Nó được gọi là long-proc cho "quá trình dài".

Mã nguồn [Chọn]
./long-proc

Nếu đây là một chương trình đã làm được điều gì đó hữu ích và chúng tôi muốn nó tiếp tục chạy ngay cả khi cửa sổ đầu cuối và shell bị đóng, thì chúng tôi sẽ khởi chạy nó bằng nohup.

Mã nguồn [Chọn]
nohup ./long-proc

Quá trình này được tách rời khỏi stdin và stdout do đó nó không thể nhận bất kỳ đầu vào nào cũng như không thể ghi vào cửa sổ đầu cuối. Ngoài ra, vì nó vẫn đang chạy nên bạn sẽ không quay lại dấu nhắc lệnh. Tất cả những gì nohup làm được là làm cho quá trình không bị ảnh hưởng bởi việc đóng thiết bị đầu cuối. Nó không biến quá trình này thành một tác vụ nền.

Bây giờ bạn có phải khởi động lại chỉ để kết thúc quá trình không? Không. Để dừng một nohup tiến trình mà bạn chưa khởi chạy dưới dạng tiến trình nền, hãy nhấn tổ hợp phím Ctrl+C.


Đầu ra từ chương trình đã được ghi lại cho chúng tôi trong một tệp có tên "Nohup.out." Chúng tôi có thể xem xét nó với lệnh less.

Mã nguồn [Chọn]
less nohup.out
Mọi thứ thường được gửi đến cửa sổ terminal đều được ghi lại trong tệp. Các lần chạy tiếp theo nohupsẽ được thêm vào tệp "nohup.out" hiện có.


Một cách hữu ích hơn để chạy quy trình là khởi chạy nó để nó có thể chịu được việc đóng cửa sổ đầu cuối, đồng thời nohup biến nó thành một tác vụ nền. Để làm điều này, chúng tôi thêm ký hiệu " &" vào cuối dòng lệnh.

Mã nguồn [Chọn]
nohup ./long-proc &

Bạn sẽ cần nhấn "Enter" một lần nữa để quay lại dấu nhắc lệnh. Chúng tôi được cho biết mã số công việc của quy trình là 1---số trong ngoặc " []"--- và ID quy trình là 13115.

Chúng ta có thể sử dụng một trong hai cách này để chấm dứt quá trình. "Ctrl+C" hiện không hoạt động vì chương trình không có bất kỳ liên kết nào với cửa sổ terminal hoặc shell.

Nếu bạn quên mã số công việc là gì, bạn có thể sử dụng jobs lệnh để liệt kê các tác vụ nền đã được khởi chạy từ cửa sổ terminal đó.


Để kết thúc nhiệm vụ của mình, chúng ta có thể sử dụng kill lệnh và số công việc, trước dấu phần trăm " %", như thế này:

Mã nguồn [Chọn]
kill %1
Nếu bạn đã đóng cửa sổ terminal, bạn sẽ cần tìm ID tiến trình và sử dụng nó với kill lệnh. Lệnh pgrep sẽ tìm ID tiến trình cho các tiến trình khớp với đầu mối tìm kiếm mà bạn cung cấp. Chúng tôi sẽ tìm kiếm tên quy trình.


Bây giờ chúng ta có thể sử dụng ID tiến trình để kết thúc quá trình.


Lần tiếp theo bạn nhấn "Enter", bạn sẽ được thông báo rằng quá trình này đã bị chấm dứt.

Bây giờ chúng ta hãy xem điều gì không kết thúc quá trình. Chúng tôi sẽ khởi chạy lại nó và sau đó đóng cửa sổ terminal.


Nếu chúng ta mở một cửa sổ terminal mới và tìm kiếm quy trình của mình bằng pgrep, chúng ta sẽ thấy nó vẫn đang chạy. Đóng cửa sổ terminal khởi chạy quá trình không có hiệu lực.


Có thể chuyển nhiều lệnh tới nohup, nhưng tốt hơn hết là khởi chạy chúng riêng lẻ. Nó làm cho việc thao tác chúng như các công việc nền trở nên dễ dàng hơn. Các lệnh sẽ không chạy cùng lúc, chúng sẽ được thực thi lần lượt. Việc thực hiện không đồng thời, nó tuần tự. Để chúng chạy đồng thời, bạn cần khởi chạy chúng một cách riêng biệt.

Phải nói rằng, để khởi chạy nhiều quy trình cùng một lúc, hãy sử dụng nohupđể khởi chạy shell Bash và sử dụng -c tùy chọn (lệnh) với chuỗi lệnh. Sử dụng dấu ngoặc đơn " '" để bao bọc danh sách lệnh và ký hiệu kép " &&" để phân tách các lệnh.

Mã nguồn [Chọn]
nohup bash -c 'ls /bin && ls /sbin'

Nếu bạn sử dụng less để xem qua tệp "nohup.out", bạn sẽ thấy đầu ra từ quy trình đầu tiên, sau đó là đầu ra từ quy trình thứ hai.


Đầu ra từ cả hai lệnh đã được ghi lại trong tệp "nohup.out". Nó không đan xen, đầu ra từ quy trình thứ hai chỉ bắt đầu khi quy trình đầu tiên kết thúc.


Nếu bạn muốn sử dụng tệp của riêng mình thay vì "nohup.out", bạn có thể chuyển hướng lệnh vào tệp bạn chọn.

Mã nguồn [Chọn]
nohup bash -c 'ls /bin && ls /sbin' > myfile.txt

Lưu ý rằng thông báo không còn có nội dung "đang thêm đầu ra vào nohupo.out" mà là "chuyển hướng thiết bị xuất chuẩn sang thiết bị xuất chuẩn" và chúng tôi đang chuyển hướng thiết bị xuất chuẩn sang tệp "myfile.txt" của mình.

Chúng ta có thể xem bên trong tệp "myfile.txt" với lệnh less.


Như trước đây, nó chứa đầu ra từ cả hai lệnh.


Thật buồn cười là lịch sử của một tiện ích đôi khi có thể khiến nó có vẻ như không liên quan gì đến thời hiện đại. Lệnh là một trong số đó nohup. Một thứ gì đó được tạo ra để đối phó với tình trạng ngắt kết nối trên các dòng nối tiếp vẫn hữu ích đối với người dùng Linux ngày nay trên các máy cực kỳ mạnh mẽ.