Làm cách nào để sử dụng lệnh nohup mà không nhận nohup.out?


309

Tôi có một vấn đề với lệnh nohup.

Khi tôi điều hành công việc của mình, tôi có rất nhiều dữ liệu. Đầu ra nohup.out trở nên quá lớn và quá trình của tôi chậm lại. Làm thế nào tôi có thể chạy lệnh này mà không nhận được nohup.out?


Câu trả lời:


612

Các nohuplệnh chỉ viết để nohup.outnếu đầu ra nếu không sẽ đi đến nhà ga. 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 nohuptự động đóng đầu vào của nó. Trên các hệ thống khác, đặc biệt là BSD và macOS, đó 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. 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 và bạn đang chạy bash, ksh hoặc zsh, bạn có thể làm như vậy bằng cách chạy disownmà không có đối số là lệnh tiếp theo. Điều đó có nghĩa là quá trình nền 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 được chuyển tiếp đến nó từ shell. (Lưu ý sự khác biệt: một disownquá trình ed được không có tín hiệu chuyển tiếp đến nó tự động bằng vỏ mẹ của nó - nhưng không nohup, nó vẫn sẽ nhận được một HUPtín hiệu được gửi qua các phương tiện khác, chẳng hạn như một hướng dẫn killlệnh A. nohup'Quá trình ed bỏ qua bất kỳ và tất cả các HUPtín hiệu, bất kể chúng được gửi như thế nào.)

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.

Các đường ống là đơn giản nhất trong số này ... command1 | command2sắp xếp cho đầu ra tiêu chuẩn của command1nguồn cấp dữ liệu 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 bị 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 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>>logfilethê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>&1có 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>&1có 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 nohupphát hiện ra rằng không có 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/nullbị 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ệ".


1
Về nohup"nếu quá trình sau này cố gắng đọc bất cứ điều 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ì đó." có vẻ không đúng Thay vào đó, nohup đóng đầu vào tiêu chuẩn (chương trình sẽ không thể đọc bất kỳ đầu vào nào, ngay cả khi nó được chạy ở nền trước. Nó không bị dừng, nhưng sẽ nhận được mã lỗi hoặc EOF).
Tim

1
@ Tim - câu trả lời là đúng cho Linux, nhưng không phải cho BSD hay OS X, mà nohuplàm không đầu vào chặt chẽ tiêu chuẩn tự động. Lưu ý rằng đó nohupkhông phải là shell dựng sẵn mà là tiện ích nhị phân.
Mark Reed

nohup là một phần của coreutils. Bạn có nghĩa là việc triển khai nohuplà khác nhau đối với linux và đối với BSD hoặc OS X?
Tim

Đúng. Tên "coreutils" dùng để chỉ gói GNU. Nhưng BSD, OS X, SmartOS / Illumos và nhiều Unix thương mại - về cơ bản, những cái đã tồn tại lâu hơn GNU - có các tiện ích cốt lõi không phải GNU. awklà khác biệt, sedlà khác biệt, nohuplà khác biệt ...
Mark Reed

Tại sao bạn viết "thêm an toàn" bởi </dev/null? Đồng thời xem 0>/dev/null unix.stackexchange.com/a/266247
Tim

68
nohup some_command > /dev/null 2>&1&

Đó là tất cả những gì bạn cần làm!


4
Có một câu trả lời khác gần như có điều tương tự, nhưng cuối cùng họ không có thêm "&".
11101101b

10
Việc &trên sẽ giúp bạn không cần sử dụng ctrl-c, nếu điều đó quan trọng với bạn.
SunSparc

1
Khả năng chạy trong BG rất hữu ích
ist_lion

Điều này chỉ hữu ích nếu bạn không băn khoăn về việc nắm bắt some_commandđầu ra, bao gồm cả lỗi.
wulfgarpro

12

Bạn đã thử chuyển hướng cả ba luồng I / O:

nohup ./yourprogram > foo.out 2> foo.err < /dev/null &

1
Không phải là >/ dev / null chứ không phải </ dev / null?
Scott Chu

3
@ScottChu < /dev/nullchuyển hướng đầu vào tiêu chuẩn cho nohup. Linux không yêu cầu điều này nhưng POSIX cho phép hành vi nohupkhông thể chạy trên nền nếu đầu vào tiêu chuẩn của nó được kết nối với thiết bị đầu cuối. Ví dụ về các hệ thống như vậy là BSD và OS X.
Mikko Rantalainen

8

Bạn có thể muốn sử dụng chương trình tách ra . Bạn sử dụng nó như thế nohupnhưng nó không tạo ra nhật ký đầu ra trừ khi bạn nói với nó. Đây là trang người đàn ông:

NAME
       detach - run a command after detaching from the terminal

SYNOPSIS
       detach [options] [--] command [args]

       Forks  a  new process, detaches is from the terminal, and executes com‐
       mand with the specified arguments.

OPTIONS
       detach recognizes a couple of options, which are discussed below.   The
       special  option -- is used to signal that the rest of the arguments are
       the command and args to be passed to it.

       -e file
              Connect file to the standard error of the command.

       -f     Run in the foreground (do not fork).

       -i file
              Connect file to the standard input of the command.

       -o file
              Connect file to the standard output of the command.

       -p file
              Write the pid of the detached process to file.

EXAMPLE
       detach xterm

       Start an xterm that will not be closed when the current shell exits.

AUTHOR
       detach was written by Robbert Haarman.  See  http://inglorion.net/  for
       contact information.

Lưu ý tôi không có liên kết với tác giả của chương trình. Tôi chỉ là một người dùng hài lòng của chương trình.


2
Liên kết không bị hỏng và git repo đã cũ. Nó không bao gồm v0.2.3 hiện tại.
Dan D.

5

Lệnh sau sẽ cho phép bạn chạy một cái gì đó trong nền mà không nhận được nohup.out:

nohup command |tee &

Theo cách này, bạn sẽ có thể nhận được đầu ra của bàn điều khiển trong khi chạy tập lệnh trên máy chủ từ xa: nhập mô tả hình ảnh ở đây


4
sudo bash -c "nohup /opt/viptel/viptel_bin/log.sh $* &> /dev/null"  &

Chuyển hướng đầu ra của sudo khiến sudo reask cho mật khẩu, do đó cần một cơ chế khó xử để thực hiện biến thể này.


1

Nếu bạn có trình bao BASH trên mac / linux trước mặt, bạn hãy thử các bước dưới đây để hiểu thực tế về chuyển hướng:

Tạo tập lệnh 2 dòng có tên zz.sh

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • Đầu ra của lệnh echo đi vào filestream STDOUT (mô tả tệp 1).
  • Đầu ra của lệnh lỗi đi vào filestream STDERR (mô tả tệp 2)

Hiện tại, chỉ cần thực thi tập lệnh sẽ gửi cả STDOUT và STDERR đến màn hình.

./zz.sh

Bây giờ bắt đầu với chuyển hướng tiêu chuẩn:

zz.sh > zfile.txt

Trong phần trên, "echo" (STDOUT) đi vào zfile.txt. Trong khi đó "lỗi" (STDERR) được hiển thị trên màn hình.

Trên đây là giống như:

zz.sh 1> zfile.txt

Bây giờ bạn có thể thử ngược lại và chuyển hướng "lỗi" STDERR vào tệp. Lệnh STDOUT từ "echo" đi đến màn hình.

zz.sh 2> zfile.txt

Kết hợp hai điều trên, bạn nhận được:

zz.sh 1> zfile.txt 2>&1

Giải trình:

  • ĐẦU TIÊN, gửi STDOUT 1 đến zfile.txt
  • THEN, gửi chính STDERR 2 đến STDOUT 1 (bằng cách sử dụng & 1 con trỏ).
  • Do đó, cả 1 và 2 đều đi vào cùng một tệp (zfile.txt)

Cuối cùng, bạn có thể đóng gói toàn bộ bên trong lệnh nohup & để chạy nó trong nền:

nohup zz.sh 1> zfile.txt 2>&1&

1

Bạn có thể chạy lệnh dưới đây.

nohup <your command> & >  <outputfile> 2>&1 &

ví dụ: tôi có lệnh nohup bên trong tập lệnh

./Runjob.sh > sparkConcuurent.out 2>&1
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.