Как использовать команду nohup без получения nohup.out?


309

У меня проблема с командой nohup.

Когда я запускаю свою работу, у меня много данных. Вывод nohup.out становится слишком большим, и мой процесс замедляется. Как я могу запустить эту команду, не получая nohup.out?


Ответы:


612

Команда выполняет 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 и macOS, это не так, поэтому при работе в фоновом режиме может потребоваться закрыть ввод вручную. Хотя закрытие ввода не влияет на создание или нет nohup.out, это позволяет избежать другой проблемы: если фоновый процесс пытается что-то прочитать из стандартного ввода, он приостановится, ожидая, что вы вернете его на передний план и что-то наберете. Так что особо безопасная версия выглядит так:

nohup command </dev/null >/dev/null 2>&1 & # completely detached from terminal 

Однако обратите внимание, что это не мешает команде получить прямой доступ к терминалу и не удаляет ее из группы процессов вашей оболочки. Если вы хотите сделать последнее, и вы запускаете bash, ksh или zsh, вы можете сделать это, запустив disownбез аргумента следующую команду. Это будет означать, что фоновый процесс больше не связан с «заданием» оболочки и не будет передавать ему какие-либо сигналы из оболочки. (Обратите внимание на различие: disownпроцесс ed не получает сигналов, перенаправляемых ему автоматически своей родительской оболочкой - но без nohupнего он все равно будет получать HUPсигнал, отправленный с помощью других средств, таких как ручная killкоманда. nohupПроцесс ed игнорирует все HUPсигналы, независимо от того, как они отправлены.)

Объяснение:

В системах Unixy каждый источник ввода или цели вывода имеет связанный с ним номер, называемый «дескриптором файла», или, для краткости, «fd». Каждая запущенная программа («процесс») имеет свой собственный набор из них, и когда запускается новый процесс, у него уже три из них открыты: «стандартный ввод», который является fd 0, открыт для процесса для чтения, в то время как «стандартный вывод» (fd 1) и «стандартная ошибка» (fd 2) открыты для записи. Если вы просто запускаете команду в окне терминала, то по умолчанию все, что вы вводите, отправляется на его стандартный ввод, в то время как стандартный вывод и стандартная ошибка отправляются в это окно.

Но вы можете попросить оболочку изменить место, на которое указывает какой-либо или все эти файловые дескрипторы, перед запуском команды; это то, что переназначение ( <, <<, >, >>) и трубы ( |делать) операторы.

Труба является самым простым из этих ... 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, но это приведет к созданию процесса с открытым дескриптором входного файла в выходном потоке, поэтому вместо простого нажатия на конец файла любая попытка чтения вызовет фатальную ошибку «неверный дескриптор файла».


1
Что касается того nohup, «если процесс позже попытается что-то прочитать из стандартного ввода, он остановится, ожидая, что вы вернете его на передний план и наберете что-нибудь». кажется неверным. Вместо этого nohup закрывается стандартный ввод (программа не сможет прочитать какой-либо ввод, даже если он запущен на переднем плане. Он не остановлен, но получит код ошибки или EOF).
Тим

1
@ Тим - этот ответ является правильным для Linux, но не для BSD или OS X, на котором nohupделает не близко стандартный ввод автоматически. Обратите внимание, что nohupэто не встроенная оболочка, а бинарная утилита.
Марк Рид

nohup является частью coreutils. Вы имеете в виду, что реализация nohupдля Linux и BSD или OS X различна?
Тим

Да. Название «coreutils» относится к пакету GNU. Но BSD, OS X, SmartOS / Illumos и многие коммерческие Unix - в основном те, что существуют дольше, чем GNU - имеют не-GNU основные утилиты. awkотличается, sedотличается, nohupотличается ...
Марк Рид

Почему вы написали "особо безопасно" </dev/null? Также см. 0>/dev/null Unix.stackexchange.com/a/266247
Тим

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

Это все, что вам нужно сделать!


4
Был другой ответ, который почти имел то же самое, но у них не было лишних «&» в конце.
11101101b

10
Он &не позволит вам использовать его ctrl-c, если это важно для вас.
SunSparc

1
Умение бегать в BG очень полезно
ist_lion

Это полезно, только если вы не беспокоитесь о захвате some_commandвывода, в том числе об ошибке.
Wulfgarpro

12

Вы пытались перенаправить все три потока ввода / вывода:

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

1
Разве это не должно быть >/ dev / null, а не </ dev / null?
Скотт Чу

3
@ScottChu < /dev/nullперенаправляет стандартный ввод для nohup. Linux не требует этого, но POSIX допускает поведение, когда nohupне может работать в фоновом режиме, если его стандартный вход подключен к терминалу. Примерами таких систем являются BSD и OS X.
Микко Ранталайнен

8

Вы можете использовать программу отсоединения . Вы используете это как, nohupно это не производит выходной журнал, если вы не говорите это. Вот справочная страница:

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.

Обратите внимание, я не имею никакого отношения к автору программы. Я всего лишь довольный пользователь программы.


2
Ссылка не битая и этот git repo старый. Это не включает в себя текущий v0.2.3.
Дэн Д.

5

Следующая команда позволит вам запустить что-то в фоновом режиме, не получая nohup.out:

nohup command |tee &

Таким образом, вы сможете получить консольный вывод при запуске скрипта на удаленном сервере: введите описание изображения здесь


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

Перенаправление вывода sudo заставляет sudo повторно запросить пароль, поэтому для этого варианта необходим неуклюжий механизм.


1

Если у вас есть оболочка BASH на вашем Mac / Linux перед вами, попробуйте следующие шаги, чтобы понять перенаправление практически:

Создайте двухстрочный скрипт с именем zz.sh

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • Вывод команды echo поступает в файловый поток STDOUT (дескриптор файла 1).
  • Вывод команды error поступает в файловый поток STDERR (дескриптор файла 2)

В настоящее время простое выполнение сценария отправляет STDOUT и STDERR на экран.

./zz.sh

Теперь начнем со стандартного перенаправления:

zz.sh > zfile.txt

Выше эхо (STDOUT) входит в zfile.txt. Принимая во внимание, что «ошибка» (STDERR) отображается на экране.

Вышеуказанное совпадает с:

zz.sh 1> zfile.txt

Теперь вы можете попробовать обратное, и перенаправить STDERR «ошибка» в файл. STDOUT из команды "echo" отправляется на экран.

zz.sh 2> zfile.txt

Комбинируя два вышеупомянутых, вы получаете:

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

Объяснение:

  • ПЕРВЫЙ, отправьте STDOUT 1 на zfile.txt
  • Затем отправьте STDERR 2 на STDOUT 1 (используя указатель & 1).
  • Следовательно, и 1, и 2 входят в один и тот же файл (zfile.txt).

В конце концов, вы можете упаковать все это в команду nohup и запустить ее в фоновом режиме:

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

1

Вы можете запустить приведенную ниже команду.

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

например, у меня есть команда nohup внутри скрипта

./Runjob.sh > sparkConcuurent.out 2>&1
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.