Ответ 1
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<
), а по умолчанию для перенаправления вывода на fd 1 (>
совпадает с 1>
).
Кроме того, вы можете объединить файловые дескрипторы вместе: 2>&1
означает "отправлять стандартную ошибку везде, где идет стандартный вывод". Это означает, что вы получаете один поток вывода, который включает как стандартную, так и стандартную ошибку, смешанные без возможности их отделить, но это также означает, что вы можете включить стандартную ошибку в канал.
Таким образом, последовательность >/dev/null 2>&1
означает "отправить стандартный вывод на /dev/null
" (который является специальным устройством, которое просто отбрасывает все, что вы ему пишете) ", а затем отправлять стандартную ошибку туда, куда идет стандартный вывод" (который мы просто убедились, что /dev/null
). В принципе, "отбросьте всю эту команду, записывая в любой дескриптор файла".
Когда nohup
обнаруживает, что ни его стандартная ошибка, ни вывод не подключены к терминалу, он не беспокоится о создании nohup.out
, но предполагает, что выход уже перенаправлен туда, куда пользователь хочет, чтобы он ушел.
Устройство /dev/null
также работает для ввода; если вы запустите команду с </dev/null
, то любая попытка этой команды читать со стандартного ввода мгновенно встретит конец файла. Обратите внимание, что синтаксис слияния не будет иметь такого же эффекта здесь; он работает только для указания дескриптора файла на другой, который открывается в том же направлении (вход или выход). Оболочка позволит вам сделать >/dev/null <&1
, но это завершает создание процесса с дескриптором входного файла, открытым в выходном потоке, поэтому вместо того, чтобы просто поражать конец файла, любая попытка чтения вызовет смертельный "неверный дескриптор файла" ".