Từ https://stackoverflow.com/a/10408906/738947
nohup chỉ ghi vào nohup.out
nếu đầu ra khác với thiết bị đầu cuối. Nếu bạn chuyển hướng đầu ra của lệnh ở một nơi khác - bao gồm /dev/null
- đó là nơi nó sẽ đi.
nohup command >/dev/null 2>&1 # doesn't create nohup.out
Nếu bạn đang sử dụng nohup
, điều đó có thể có nghĩa là bạn muốn chạy lệnh dưới nền bằng cách đặt một lệnh khác &
vào cuối của toàn bộ:
nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out
Trên Linux, chạy một công việc cũng nohup
tự động đóng đầu vào của nó. Trên các hệ thống khác, đặc biệt là BSD và OS X, đó không phải là trường hợp, vì vậy khi chạy trong nền, bạn có thể muốn đóng thủ công đầu vào của nó. Mặc dù đóng đầu vào không ảnh hưởng đến việc tạo hay không nohup.out
, nhưng nó tránh được một vấn đề khác: nếu một quá trình nền cố gắng đọc bất cứ thứ gì từ đầu vào tiêu chuẩn, nó sẽ tạm dừng, chờ bạn đưa nó trở lại nền trước và gõ một cái gì đó. Vì vậy, phiên bản cực kỳ an toàn trông như thế này:
nohup command </dev/null >/dev/null 2>&1 & # completely detached from terminal
Tuy nhiên, lưu ý rằng điều này không ngăn lệnh truy cập trực tiếp vào thiết bị đầu cuối, cũng như không loại bỏ nó khỏi nhóm quy trình của trình bao của bạn. Nếu bạn muốn thực hiện cái sau, bạn có thể làm như vậy bằng cách chạy disown
không có đối số là lệnh tiếp theo, tại thời điểm đó, quá trình không còn được liên kết với "công việc" shell và sẽ không có bất kỳ tín hiệu nào (không chỉ HUP
) được chuyển tiếp đến nó từ vỏ.
Giải trình:
Trong các hệ thống Unixy, mọi nguồn đầu vào hoặc mục tiêu của đầu ra đều có một số được liên kết với nó được gọi là "mô tả tệp" hoặc viết tắt là "fd". Mỗi chương trình đang chạy ("process") đều có bộ này và khi một tiến trình mới khởi động, nó có ba trong số chúng đã mở: "đầu vào tiêu chuẩn", là fd 0, mở cho quá trình đọc, trong khi "đầu ra tiêu chuẩn" (fd 1) và "lỗi tiêu chuẩn" (fd 2) được mở để ghi vào đó. Nếu bạn chỉ chạy một lệnh trong cửa sổ đầu cuối, thì theo mặc định, mọi thứ bạn nhập sẽ chuyển đến đầu vào tiêu chuẩn của nó, trong khi cả đầu ra tiêu chuẩn và lỗi tiêu chuẩn của nó đều được gửi đến cửa sổ đó.
Nhưng bạn có thể yêu cầu shell thay đổi vị trí của bất kỳ hoặc tất cả các mô tả tệp đó trước khi khởi chạy lệnh; đó là những gì chuyển hướng ( <
, <<
, >
, >>
) và ống ( |
) khai thác làm.
Đường ống là đơn giản nhất trong số này ... command1 | command2
sắp xếp cho đầu ra tiêu chuẩn của command1
nguồn cấp trực tiếp vào đầu vào tiêu chuẩn của command2
. Đây là một sự sắp xếp rất tiện dụng đã dẫn đến một mẫu thiết kế cụ thể trong các công cụ UNIX (và giải thích sự tồn tại của lỗi tiêu chuẩn, cho phép một chương trình gửi tin nhắn đến người dùng mặc dù đầu ra của nó đang đi vào chương trình tiếp theo trong đường ống) . Nhưng bạn chỉ có thể chuyển đầu ra tiêu chuẩn sang đầu vào tiêu chuẩn; bạn không thể gửi bất kỳ mô tả tập tin nào khác đến một đường ống mà không cần một chút tung hứng.
Các toán tử chuyển hướng thân thiện hơn ở chỗ chúng cho phép bạn chỉ định bộ mô tả tệp nào sẽ chuyển hướng. Vì vậy, 0<infile
đọc đầu vào tiêu chuẩn từ tệp có tên infile
, trong khi 2>>logfile
thêm lỗi tiêu chuẩn vào cuối tệp có tên logfile
. Nếu bạn không chỉ định một số, thì đầu vào chuyển hướng mặc định thành fd 0 ( <
giống như 0<
), trong khi chuyển hướng đầu ra mặc định thành fd 1 ( >
giống như 1>
).
Ngoài ra, bạn có thể kết hợp các mô tả tệp với nhau: 2>&1
có nghĩa là "gửi lỗi tiêu chuẩn bất cứ nơi nào có đầu ra tiêu chuẩn". Điều đó có nghĩa là bạn nhận được một luồng đầu ra duy nhất bao gồm cả lỗi tiêu chuẩn và lỗi tiêu chuẩn xen kẽ mà không có cách nào để tách chúng nữa, nhưng điều đó cũng có nghĩa là bạn có thể bao gồm lỗi tiêu chuẩn trong một đường ống.
Vì vậy, chuỗi >/dev/null 2>&1
có nghĩa là "gửi đầu ra tiêu chuẩn đến /dev/null
" (là một thiết bị đặc biệt chỉ cần loại bỏ bất cứ thứ gì bạn viết cho nó) "và sau đó gửi lỗi tiêu chuẩn đến bất cứ nơi nào có đầu ra tiêu chuẩn" (mà chúng tôi chỉ chắc chắn là như vậy /dev/null
). Về cơ bản, "vứt bỏ bất cứ điều gì lệnh này ghi vào một trong hai mô tả tập tin".
Khi nohup
phát hiện ra rằng không phải lỗi tiêu chuẩn cũng như đầu ra của nó được gắn vào một thiết bị đầu cuối, nó không bận tâm để tạo ra nohup.out
, nhưng giả sử rằng đầu ra đã được chuyển hướng nơi người dùng muốn nó đi đến.
Thiết /dev/null
bị cũng hoạt động cho đầu vào; nếu bạn chạy một lệnh với </dev/null
, thì bất kỳ nỗ lực nào của lệnh đó để đọc từ đầu vào tiêu chuẩn sẽ ngay lập tức gặp phải phần cuối của tệp. Lưu ý rằng cú pháp hợp nhất sẽ không có tác dụng tương tự ở đây; nó chỉ hoạt động để trỏ một bộ mô tả tệp đến một cái khác mở theo cùng một hướng (đầu vào hoặc đầu ra). Shell sẽ cho phép bạn thực hiện >/dev/null <&1
, nhưng điều đó sẽ tạo ra một quy trình với bộ mô tả tệp đầu vào mở trên luồng đầu ra, vì vậy thay vì chỉ nhấn vào cuối tệp, bất kỳ nỗ lực đọc nào cũng sẽ gây ra lỗi "mô tả tệp không hợp lệ".
root
? Sử dụng tài khoản không có đặc quyền.