С https://stackoverflow.com/a/10408906/738947
nohup пишет в nohup.out
только в том случае, если вывод выводится на терминал. Если вы перенаправите вывод команды куда-то еще, в том числе /dev/null
, то вместо этого все и пойдет.
nohup command >/dev/null 2>&1 # doesn't create nohup.out
Если вы используете nohup
, это, вероятно, означает, что вы хотите запустить команду в фоновом режиме, поставив еще один &
в конце всего этого:
nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out
В Linux запуск задания с помощью nohup
автоматически закрывает его ввод. В других системах, особенно в BSD и OS X, это не так, поэтому при работе в фоновом режиме вам может потребоваться закрыть ввод вручную. Хотя закрытие ввода не влияет на создание или отсутствие nohup.out
, это позволяет избежать другой проблемы: если фоновый процесс пытается что-то прочитать из стандартного ввода, он приостановится, ожидая, что вы вернете его на передний план и наберете что-то , Так что особо безопасная версия выглядит так:
nohup command </dev/null >/dev/null 2>&1 & # completely detached from terminal
Однако обратите внимание, что это не мешает команде получить прямой доступ к терминалу и не удаляет ее из группы процессов вашей оболочки. Если вы хотите сделать последнее, вы можете сделать это, запустив disown
без аргумента в качестве следующей команды, после чего процесс больше не ассоциируется с "заданием" оболочки и не будет пересылать какие- либо сигналы (не только HUP
). к нему из скорлупы.
Объяснение:
В системах Unixy каждый источник ввода или цели вывода имеет связанный с ним номер, называемый "дескриптор файла", или для краткости "fd". Каждая запущенная программа ("процесс") имеет свой собственный набор из них, и когда запускается новый процесс, у него уже три из них открыты: "стандартный ввод", который является fd 0, открыт для процесса для чтения, в то время как "стандартный вывод" (fd 1) и "стандартная ошибка" (fd 2) открыты для записи. Если вы просто запускаете команду в окне терминала, то по умолчанию все, что вы вводите, отправляется на его стандартный ввод, в то время как стандартный вывод и стандартная ошибка отправляются в это окно.
Но вы можете попросить, чтобы оболочка изменила место, на которое указывает какой-либо или все эти файловые дескрипторы, перед запуском команды; это то, что делают операторы перенаправления (<
, <<
, >
, >>
) и pipe (|
).
Труба самая простая из этих ... command1 | command2
обеспечивает стандартный вывод команды command1
для подачи непосредственно на стандартный ввод command2
. Это очень удобная схема, которая привела к определенному шаблону проектирования в инструментах UNIX (и объясняет существование стандартной ошибки, которая позволяет программе отправлять сообщения пользователю, даже если ее выходные данные передаются следующей программе в конвейере), Но вы можете только передать стандартный вывод на стандартный ввод; Вы не можете отправлять любые другие файловые дескрипторы в канал без каких-либо манипуляций.
Операторы перенаправления более удобны тем, что позволяют указать, какой дескриптор файла следует перенаправить. Таким образом, 0<infile
читает стандартный ввод из файла с именем infile
, а 2>>logfile
добавляет стандартную ошибку в конец файла с именем logfile
. Если вы не укажете число, то по умолчанию перенаправление ввода будет равно fd 0 (<
равно 0<
), а по умолчанию перенаправление равно 1 (>
равно 1>
).
Кроме того, вы можете объединить дескрипторы файлов вместе: 2>&1
означает «отправлять стандартную ошибку, куда идет стандартный вывод». Это означает, что вы получаете один поток вывода, который включает как стандартную ошибку вывода, так и стандартную ошибку, смешанную без возможности их разделения, но это также означает, что вы можете включить стандартную ошибку в канал.
Таким образом, последовательность >/dev/null 2>&1
означает «отправлять стандартный вывод в /dev/null
» (это специальное устройство, которое просто выбрасывает все, что вы пишете в него) », а затем отправлять стандартную ошибку везде, куда идет стандартный вывод "(который мы только что убедились, был /dev/null
). По сути, «выбросить все, что эта команда записывает в любой дескриптор файла».
Когда nohup
обнаруживает, что ни его стандартная ошибка, ни выходные данные не подключены к терминалу, он не пытается создать nohup.out
, но предполагает, что выходные данные уже перенаправлены туда, куда его хочет пользователь.
Устройство /dev/null
работает для ввода; если вы запускаете команду с </dev/null
, то любая попытка этой команды прочитать данные со стандартного ввода мгновенно встретит конец файла. Обратите внимание, что синтаксис слияния не будет иметь такой же эффект здесь; он работает только для указания дескриптора файла на другой, открытый в том же направлении (ввод или вывод). Оболочка позволит вам сделать >/dev/null <&1
, но это приведет к созданию процесса с открытым дескриптором входного файла в выходном потоке, поэтому вместо простого нажатия на конец файла любая попытка чтения вызовет фатальную ошибку. ошибка "неверный дескриптор файла".