Як я можу використовувати команду 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Процес ігнорує будь-які 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 та багато комерційних Unixes - в основному ті, які були довше, ніж 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.
Mikko Rantalainen

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

Якщо перед вами mac / linux перед вами оболонка BASH, спробуйте виконати наступні кроки, щоб зрозуміти перенаправлення практично:

Створіть дворядковий сценарій під назвою zz.sh

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • Вихід команди echo надходить у файл потоку STDOUT (дескриптор файлу 1).
  • Вихід команди помилки переходить у файловий потік 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.