Linux nohup что это

Обновлено: 02.07.2024

Если вы пользуетесь Linux с ранних дней появления этой ОС (или если, вроде меня, начинали с Unix), то вам не надо очень быстро и в больших количествах изучать то новое, что появляется в системе по мере её развития и усложнения. Вы можете разбираться с новым постепенно, в режиме обычной работы. Но если вы только начинаете знакомство с Linux, то вам будет непросто сразу в ней разобраться, сразу понять её особенности. Среди тех, кому приходится изучать Linux с нуля, те, кто пользуется Raspberry Pi, те, кого расстроило то, что Microsoft забросила Windows XP, те, кто развернул облачную среду для своего IoT-проекта, похожего на Skynet.

Недавно сын спросил меня о том, как сделать так, чтобы что-то работало бы на Linux-компьютере даже тогда, когда осуществлён выход из системы. Я подумал, что это — хороший вопрос, и что на него, в зависимости от того, о чём именно идёт речь, может и не быть простого ответа.




Есть четыре ситуации, которые можно рассмотреть, отвечая на этот вопрос:

  1. Нужно запустить некую программу, выполнение которой, как заранее известно, займёт много времени.
  2. Была запущена некая программа, а потом стало понятно, что её выполнение займёт много времени. После этого решено было выйти из системы, не прерывая работу этой программы.
  3. Нужно написать скрипт или другую программу, которая может отключиться от терминала и работать сама по себе (такие программы называют демонами).
  4. Нужно, чтобы некая программа работала бы всё время, даже сразу после перезагрузки системы, когда в неё ещё не входили.

Я сосредоточусь на первых двух пунктах списка, но дам некоторые подсказки касательно двух других вариантов. Итак, программа, которая сама отключается от терминала, это — демон. Этот механизм можно создать самостоятельно, а можно и у кого-нибудь позаимствовать. Сделать так, чтобы программа выполнялась бы всё время, может быть сложно, а может быть и не очень сложно. В большинстве Linux-дистрибутивов есть файл /etc/rc.local , который запускается с root-правами при запуске системы (как минимум — при нормальном запуске). Сюда можно добавлять команды для автозапуска каких-нибудь программ. Если же требуется, например, создавать собственные сервисы, то тут нужно учитывать особенности системы, знать о том, что именно в ней используется — SystemV, Upstart, OpenRC или Systemd. Возможно, придётся столкнуться и с чем-то другим. Но это — отдельная большая тема.

Обеспечение работы программ после выхода из системы

Вернёмся к первым двум пунктам нашего списка. Представьте, что вам надо запустить программу remote_backup , и вы знаете о том, что вы её запустите (возможно, войдя в систему по ssh), а потом отключитесь, но при этом она должна продолжать работать. Или вы, возможно, хотите обезопасить себя и сделать так, чтобы она продолжала бы работать даже в том случае, если вы случайно выйдете из системы. В любом случае, при обычном запуске программы из командной строки выход из системы означает остановку программы. Или не означает?

Для этого нужно просто запустить программу так, чтобы она не зависела бы от текущей сессии пользователя. Если вы используете bash и всё у вас настроено правильно, то сделать это можно очень просто. Если для запуска программы в фоновом режиме используется & , то работать она будет и после выхода из системы. То же самое касается и приостановки работающей программы ( CTRL + Z ) с последующим переводом её в фоновый режим с помощью команды bg . Тут мы видим очередной пример гибкости Linux, возможности решить одну и ту же задачу множеством способов.

Если вы работаете с bash, это значит, что вы можете настраивать оболочку, в том числе — параметр huponexit . Попробуйте выполнить следующую команду:


Если окажется, что опция huponexit выключена, это значит, что обычный перевод программы в фоновый режим позволит ей пережить завершение вашей сессии. Конечно, если то же самое попробовать в какой-нибудь другой системе, это может не сработать и вам придётся выяснять причины такого поведения системы.

Если вам известно о том, что вы пользуетесь bash с выключенной опцией huponexit , это значит, что запустить программу в фоне вы можете, просто добавив после команды запуска знак & :


Но надёжнее будет явным образом выразить намерение, касающееся работы программы после выхода из системы. Сделать так может понадобиться хотя бы из-за того, что при использовании только что описанного метода после выхода из системы нельзя будет видеть никаких выходных данных программы. Если же вы достаточно предусмотрительны, то программу вы можете запустить с использованием nohup :


Если вы хотите передать nohup ещё и какие-то аргументы — перечислите их в конце команды, как это обычно делается при работе с другими программами. Nohup решает следующие задачи:

  1. Перенаправляет stderr в stdout .
  2. Перенаправляет stdout в nohup.out (местоположение этого файла в разных версиях nohup может различаться, в частности, он может находиться по адресу

Причина, по которой выполняются все эти перенаправления, заключается в том, что nohup обнаруживает то, что каждый из потоков подключён к терминалу. Если что-то уже перенаправлено в файл, nohup не будет это менять. То есть, например, можно поступить так:


В последнем случае входные данные будут поступать из конвейера, поэтому nohup это менять не будет. А весь вывод программы ( stdout и stderr ) попадёт в /tmp/backupstatus.log .

Исследование nohup

Если вы хотите своими глазами увидеть то, как nohup воздействует на программы, войдите на Linux-сервер по ssh и выполните следующие команды:


До тех пор, пока не истекут 60 секунд, нажмите клавишу клавиатуры, вводящую символ «тильда» (

). Затем нажмите клавишу, вводящую точку. В SSH тильда — это экранирующий символ (если он находится в начале строки). Воспользуйтесь командой

? если хотите узнать подробности об этом. Теперь сделайте небольшой перерыв, выпейте чего-нибудь, и вернитесь к компьютеру через несколько минут. Войдите в систему. Файла /tmp/test.txt вы не найдёте (если только он уже не был создан, но и в таком случае его содержимое позволит сделать правильные выводы). Это говорит нам о том, что завершение сессии остановило программу, ожидающую истечения 60 секунд для продолжения работы.

А теперь попробуйте такую конструкцию:


Она сообщит оболочке о том, что ей не надо ждать завершения программы. Если вы пользуетесь bash, то это будет работать в том случае, если опция huponexit выключена. Вы можете поэкспериментировать, включая ( shopt -s huponexit ) и выключая ( shopt -u huponexit ) эту опцию.

И, наконец, можно выполнить ту же команду с использованием nohup :


Но даже команда nohup не идеальна. Если программа, которую мы выполняем, сама перехватывает флаг nohup , то команда nohup нам не поможет. Правда, большинство программ не перехватывают этот флаг и nohup будет работать независимо от используемой оболочки и от её настроек.

Есть множество других способов достижения того же результата. Например, можете исследовать возможности команды at , которая запускает другие программы в заданное время (скажем — через секунду после текущего момента). При запуске программ будет использоваться sh, а не bash (без выполнения некоторых действий), но они будут работать в автономном режиме.

Отсутствие планирования

Правда, существует пара ситуаций, в которых nohup нам не поможет. Первая — это когда не планировалось запускать программу в фоновом режиме. Как быть, если что-то было запущено, а потом стало ясно, что операция будет выполняться достаточно долго? Что делать, если понадобилось срочно куда-то отойти? Может случиться и так, что нужно запустить программу, вручную ввести в неё какие-то данные, а потом перевести в фоновый режим.

Возможно, вы знаете о том, что работающую программу можно приостановить, воспользовавшись комбинацией клавиш CTRL + Z . Bash сообщит, что создано задание, и даст его номер. Потом, используя команду bg , можно перевести это задание в фоновый режим. Если, например, заданию присвоен номер 3 , то соответствующая команда будет выглядеть так:


Если опция huponexit выключена, то больше ничего делать не надо. Но в общем случае нужно сообщить оболочке о том, что надо либо не отправлять заданию команды HUP , либо убрать его из таблицы заданий. Для решения обеих этих задач можно воспользоваться командой disown , встроенной в bash.

При использовании disown без опций будет осуществлено удаление именованного задания из таблицы заданий. Если вы не хотите заходить так далеко, воспользуйтесь опцией -h для того чтобы оболочка не передавала бы конкретному заданию сигнал HUP . Можно ещё воспользоваться опцией -a , позволяющей воздействовать на все задания, или опцией -r , которая позволяет обращаться ко всем работающим заданиям. Это — стандартная возможность bash (то есть — справку по ней можно найти в справке по bash), поэтому работать она будет не во всех командных оболочках. После того, как вы обработали фоновую задачу с помощью disown , вы можете спокойно выходить из системы.

Постоянные сессии

Как это обычно бывает в Linux, существует несколько способов решения одной и той же задачи. Для работы с сессиями можно воспользоваться screen или tmux. Работа с этими утилитами похожа на работу с VNC, когда можно выйти из системы, а потом, войдя в неё, обнаружить, что всё, с чем до этого работали, никуда не делось. Если вы решаете множество задач с использованием командной строки, то можете попробовать byobu (это даст вам приятный интерфейс для screen) или tmux.

Использование tmux

Если вы хотите это испытать — войдите в систему как обычно и запустите screen, tmux или byobu. Снова запустите тестовый скрипт (с & в конце команды или без использования этого символа). Потом воспользуйтесь вышеописанным фокусом

. для «убийства» сессии. Далее, снова войдите в систему и перезапустите ту же программу (то есть — screen, tmux или byobu). Перед вами окажется экран, выглядящий таким же, каким он был в тот момент, когда вы вышли из системы. Это, в целом, довольно полезная возможность. Кроме того, она позволяет организовать работу с несколькими окнами, но в нашем случае это значения не имеет.

Проблема богатства возможностей

Мощь Linux отчасти основана на том, что у пользователей этой ОС есть множество способов решения одной и той же задачи. В этом же кроются и проблемы Linux. Причём, эти проблемы возникают не, например, тогда, когда нужно настроить миниатюрный компьютер Raspberry Pi, находящийся под полным контролем одного человека. Настоящие сложности появляются в ситуациях, когда нужно развернуть что-то на множестве компьютеров, за которыми работают разные пользователи, и на которых, возможно, даже установлены разные дистрибутивы.

Конечно, если стремиться к разработке универсальных решений, это — далеко не единственная проблема. Если нужно писать скрипты, которые смогут успешно работать в самых разных Posix-системах, можно почитать документацию GNU по autoconf. Там можно найти много полезного.

Как вы запускаете Linux-программы, которые должны работать после выхода из системы?

В этом отрывке рассмотрены команды управления процессами. Вы научитесь замораживать процессы, размораживать, отправлять в фоновый режим, изменять приоритет, просматривать запущенные процессы и жестоко их убивать. Введено понятие сигналов. Рассмотрены такие команды, как bg, fg, jobs, kill, nohup, nice, renice, ps и top.




Навигация по основам Linux от основателя Gentoo:
Часть I
Часть II
    (вступление)
  1. Управление процессами (итоги и ссылки)

Управление процессами

Запуск xeyes

Для изучения управления процессами, какой-нибудь процесс необходимо сначала запустить. Убедитесь, что у вас запущен X (графический сервер — прим. пер.) и выполните следующую команду:

$ xeyes -center red

Вы увидите всплывающее окошко xeyes и красные глаза, следящие за курсором мыши. Также, обратите внимание, что у вас не появилось приглашения для ввода команд в терминале.

Остановка процесса

Чтобы вернуть приглашение, вы должны нажать Control-C (часто пишется как Ctrl-C или ^C):

Вы получили назад свое приглашение, но и окно xeyes исчезло. Фактически, процесс был «убит». Вместо завершения по Control-C, мы можем просто остановить процесс с помощью Control-Z:

$ xeyes -center red
Control-Z
$

На этот раз вы получите приглашение bash'a, а окно xeyes останется сверху. Если вы с ним немного поиграете, возможно заметите, что глаза заморожены на одном месте. Если окно xeyes будет перекрыто другим окном и затем снова открыто, вы увидите, что оно даже не перерисовалось. Процесс не делает ничего. Он на самом деле остановлен.

fg и bg

Чтобы процесс «растормошить» и запустить обратно, мы можем вывести его на передний план используя команду fg (от англ. foreground — прим. пер.):

$ fg
(test it out, then stop the process again)
Control-Z
$

А теперь продолжим его в фоне с помощью команды bg (от англ. backgroud — прим. пер.):

$ bg
[1]+ xeyes -center red &amp
$

Прекрасно! Процесс xeyes сейчас запущен в фоновом режиме, а мы снова имеем приглашение bash.

Использование "&"

Если нам нужно сразу запустить xeyes в фоновом режиме (вместо использования Control-Z и bg), мы можем просто добавить "&amp" (амперсанд) в конец команды xeyes:

$ xeyes -center blue &amp
[2] 16224

Несколько фоновых процессов

Теперь в фоне у нас одновременно работают красные и синие xeyes. Мы можем просмотреть список заданий с помощью jobs:

Число в левой колонке — это порядковый номер задания, который bash присваивает ему при запуске. Плюс (+) у второго задания значит, что это «текущее задание», оно будет выведено на передний план при вводе fg. Вы также можете вывести на передний план конкретное задание указывая его номер; например, fg 1 сделает таковым красный xeyes. Следующая колонка это идентификатор процесса или сокращенно pid, любезно добавленный в вывод благодаря опции -l. Наконец, состояние обоих процессов «Running» (выполняется) и их командная строка справа.

Введение в сигналы

SIGTERM и SIGINT

Если вы хотите убить процесс, есть несколько вариантов. По-умолчанию, kill отправляет SIGTERM, который отличается от SIGINT отправляемого по Control-C, но обычно имеет тот же эффект:

Полное убийство

Процесс может игнорировать оба сигнала, SIGTERM и SIGINT, либо по своему усмотрению, либо потому, что он остановлен, либо еще как-то «застрял». В этом случае, может быть необходимо использование большого молотка — сигнала SIGKILL. Процесс не может игнорировать SIGKILL:

$ kill 16224
$ jobs -l

nohup

Терминал в котором вы запускаете задания, называется терминалом управления заданиями. Некоторые шеллы (но не bash по-умолчанию), отправляют сигнал SIGHUP фоновым заданиям когда вы выходите, заставляя их завершаться. Для защиты процессов от такого поведения, используйте nohup когда запускаете процесс:

$ nohup make &
[1] 15632
$ exit

Используем ps для вывода списка процессов

Команда jobs, которую мы использовали ранее выводит только те процессы, которые были запущены в вашей сессии bash. Чтобы увидеть все процессы в вашей системе, используйте ps совместно с опциями a и x:

Здесь приведены только первые 5 процессов, поскольку обычно список процессов очень длинный. Команда дает вам «слепок» всего, что в данный момент выполняется на машине, однако в нем много лишней информации. Если бы вы, не указали ax, вы бы получили список только тех процессов, которые принадлежат вам, и которые есть в управляющем терминале. Команда ps x покажет все ваши процессы, даже те, которых нет в управляющем терминале. Если использовать ps a, то будет получен список процессов из терминалов всех пользователей.

Просмотр «леса» и «деревьев»

Вы также можете просмотреть и другую информацию о каждом процессе. Опция --forest позволяет легко просмотреть иерархию процессов и даст вам представление о том, как различные процессы в системе взаимосвязаны между собой. Если один процесс запускает другой процесс, то запущенный будет называться его потомком. В выводе --forest, родители находятся слева, а потомки появляются как ветки справа:

«u» и «l» опции ps

Опции u и l могут быть использованы в любой комбинации с опциями a, x с целью получения более подробной информации о процессах:

$ ps au
$ ps al

Использование top

Если вы обнаружили, что запускаете ps несколько раз подряд, пытаясь рассмотреть происходящие изменения, возможно вам стоит воспользоваться top. Программа top отображает постоянно обновляющийся список процессов, наряду с другой полезной информацией:

Каждый процесс имеет свое значение приоритета, которое Linux использует для разделения времени CPU. Вы можете указать приоритет процесса при его запуске, с помощью команды nice:

$ nice -n 10 oggenc /tmp/song.wav

С тех пор, как приоритет стал называться nice, он стал легче для запоминания, так, большее значение nice делает «хорошо» (nice — хорошо, замечательно; прим. пер.) другим процессам, позволяя им получить более приоритетный доступ к времени CPU. По-умолчанию, процессы запускаются с приоритетом 0, поэтому установка приоритета в 10 для oggenc значит, что он будет давать больше времени поработать другим процессам. Как правило, это означает, что oggenc даст возможность другим процессам выполняться со своей обычной скоростью, не зависимо от того, сколько времени процессора хочет сам oggenc. Вы могли видеть эти «уровни любезности» в колонке NI у ps и top ранее.

renice

Команда nice может изменять приоритет процессов только во время их запуска. Если вам необходимо изменить приоритет работающего процесса, воспользуйтесь командой renice:


$ renice 10 641
641: old priority 0, new priority 10

Об авторах

Daniel Robbins

Дэниэль Роббинс — основатель сообщества Gentoo и создатель операционной системы Gentoo Linux. Дэниэль проживает в Нью-Мехико со свой женой Мэри и двумя энергичными дочерьми. Он также основатель и глава Funtoo, написал множество технических статей для IBM developerWorks, Intel Developer Services и C/C++ Users Journal.

Chris Houser

Крис Хаусер был сторонником UNIX c 1994 года, когда присоединился к команде администраторов университета Тэйлора (Индиана, США), где получил степень бакалавра в компьютерных науках и математике. После он работал во множестве областей, включая веб-приложения, редактирование видео, драйвера для UNIX и криптографическую защиту. В настоящий момент работает в Sentry Data Systems. Крис также сделал вклад во множество свободных проектов, таких как Gentoo Linux и Clojure, стал соавтором книги The Joy of Clojure.

Aron Griffis

Эйрон Гриффис живет на территории Бостона, где провел последнее десятилетие работая в Hewlett-Packard над такими проектами, как сетевые UNIX-драйвера для Tru64, сертификация безопасности Linux, Xen и KVM виртуализация, и самое последнее — платформа HP ePrint. В свободное от программирования время Эйрон предпочитает размыщлять над проблемами программирования катаясь на своем велосипеде, жонглируя битами, или болея за бостонскую профессиональную бейсбольную команду «Красные Носки».

Favorite

Добавить в избранное

Главное меню » Операционная система Linux » Команда Nohup в Linux позволяет запускать команды даже после выхода из системы

(1 оценок, среднее: 5,00 из 5)

Команда Nohup в Linux позволяет запускать команды даже после выхода из системы

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

Nohup означает «no hang up». Это чрезвычайно полезная команда для запуска процесса даже после выхода из системы.

Одно из наиболее распространенных применений можно найти в выполнении команд, требующих времени, через соединение SSH. Если вы считаете, что ваш SSH-сеанс может прерваться, вы можете использовать команду с nohup следующим образом:

Что такое команда nohup?

Nohup можно рассматривать как обертку. Префикс вашей команды с nohup:

Цель Nohup в том чтобы перехватить и предотвратить SIGHUP сигналы от достижения команды.

О nohup говорить особо нечего, у него нет длинного списка опций. Есть только –help и –version.

Пример использования команды Nohup

Выполнение скрипта с помощью nohup так же просто, как это.


Обратите внимание, что nohup не развил процесс в фоновом режиме. Nohup предназначен только для перехвата сигналов SIGHUP. После запуска команды вы можете продолжить и закрыть свой терминал. Он предупредит вас, что процесс запущен. Подтвердите, что хотите убить его.

Когда вы закрыли свой терминал, все дочерние процессы получили сигнал SIGHUP. Nohup помешал этому сигналу достичь нашей команды. На следующем рисунке показана информация о нашей команде, пока терминал еще работал.

Вы видите PPID? Это идентификатор родительского процесса. Когда вы запросили закрыть терминал, все дочерние элементы PPID получили сигнал SIGHUP. Nohup не дал этому сигналу дойти до нашего сценария. Родительский процесс завершен, и наш сценарий осиротел. Когда процесс становится осиротевшим, он автоматически получает 1 (systemd или init) в качестве родителя.

Как видите, продемонстрировать использование nohup не сложно. Очень простая команда. Вы можете разветвлять процесс в фоновом режиме следующим образом:

Вы также можете решить, куда будет перенаправлен вывод:

Обратите внимание, что если вы выключите или перезагрузите систему Linux, она убьет команду. Когда вы запрашиваете завершение работы или перезагрузку, все процессы получают SIGTERM, а затем SIGKILL . Эти сигналы не будут перехвачены Nohup.

Nohup через соединение SSH

Одна из распространенных проблем заключается в том, что иногда SSH «зависает» при выходе из системы. Это связано с тем, что SSH часто отказывается терять любой поток данных в фоновые процессы и из них. Затем он будет «зависать», пока процесс не будет завершен.

Эту проблему часто можно решить, перенаправив все 3 потока данных.

Мы надеемся, что эта быстрая статья помогла вам лучше использовать сеансы SSH. Если у вас есть вопросы или предложения, пожалуйста, оставьте комментарий ниже.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Nohup означает «no hang up». Это чрезвычайно полезная команда для запуска процесса даже после выхода из системы.

Одно из наиболее распространенных применений можно найти в выполнении команд, требующих времени, через соединение SSH. Если вы считаете, что ваш SSH-сеанс может прерваться, вы можете использовать команду с nohup следующим образом:

Что такое команда nohup?

Nohup можно рассматривать как обертку. Префикс вашей команды с nohup:

Цель Nohup в том чтобы перехватить и предотвратить SIGHUP сигналы от достижения команды.

О nohup говорить особо нечего, у него нет длинного списка опций. Есть только –help и –version.

Пример использования команды Nohup

Выполнение скрипта с помощью nohup так же просто, как это.



Обратите внимание, что nohup не развил процесс в фоновом режиме. Nohup предназначен только для перехвата сигналов SIGHUP. После запуска команды вы можете продолжить и закрыть свой терминал. Он предупредит вас, что процесс запущен. Подтвердите, что хотите убить его.


Когда вы закрыли свой терминал, все дочерние процессы получили сигнал SIGHUP. Nohup помешал этому сигналу достичь нашей команды. На следующем рисунке показана информация о нашей команде, пока терминал еще работал.



Вы видите PPID? Это идентификатор родительского процесса. Когда вы запросили закрыть терминал, все дочерние элементы PPID получили сигнал SIGHUP. Nohup не дал этому сигналу дойти до нашего сценария. Родительский процесс завершен, и наш сценарий осиротел. Когда процесс становится осиротевшим, он автоматически получает 1 (systemd или init) в качестве родителя.

Как видите, продемонстрировать использование nohup не сложно. Очень простая команда. Вы можете разветвлять процесс в фоновом режиме следующим образом:

Вы также можете решить, куда будет перенаправлен вывод:

Обратите внимание, что если вы выключите или перезагрузите систему Linux, она убьет команду. Когда вы запрашиваете завершение работы или перезагрузку, все процессы получают SIGTERM, а затем SIGKILL . Эти сигналы не будут перехвачены Nohup.

Nohup через соединение SSH

Одно из применений, которое часто приходит на ум сразу, когда вы изучаете nohup – это возможность запуска процесса на удаленном компьютере через SSH. Логично, что выполнение команды с nohup позволит вам выйти из вашего SSH-соединения, и процесс все равно будет запущен.

Одна из распространенных проблем заключается в том, что иногда SSH «зависает» при выходе из системы. Это связано с тем, что SSH часто отказывается терять любой поток данных в фоновые процессы и из них. Затем он будет «зависать», пока процесс не будет завершен.

Эту проблему часто можно решить, перенаправив все 3 потока данных.

Мы надеемся, что эта быстрая статья помогла вам лучше использовать сеансы SSH. Если у вас есть вопросы или предложения, пожалуйста, оставьте комментарий ниже.

Читайте также: