Как использовать команду nohup в Linux

Опубликовано: 2022-06-25
Ноутбук Linux с приглашением bash
Фатмавати Ачмад Заэнури/Shutterstock.com

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

HUP и SIGHUP

Unix, предок Linux, был создан до изобретения ПК. Компьютеры были большими и дорогими частями оборудования. Люди взаимодействовали с ними по последовательным линиям либо локально в пределах одного здания, либо удаленно по медленным модемным соединениям. Первоначально они печатали свои инструкции на телепринтерах, которые постепенно были заменены тупыми терминалами.

Их называли тупыми, потому что вычислительная мощность находилась в компьютере, к которому вы были подключены, а не в терминале, на котором вы печатали. Программы работали на компьютере — где бы он ни находился, — а не на устройстве на вашем столе.

Если что-то произошло, что разорвало соединение между вашим терминалом и компьютером, компьютер обнаружил обрыв линии и отправил сигнал HUP или отбой программам, которые вы запускали. Программы прекращали выполнение, когда получали сигнал.

Как завершить настольное приложение или фоновый процесс в Linux
СВЯЗАННЫЕ С Как завершить настольное приложение или фоновый процесс в Linux

Эта функциональность живет в Linux и сегодня. Окно терминала на вашем ПК представляет собой эмуляцию физического терминала. Если у вас есть запущенные процессы, которые были запущены из этого окна терминала, и вы закрываете это окно, сигнал SIGHUP отправляется программам, чтобы они были проинформированы о HUP и знали, что они должны завершиться.

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

Команда nohup запускает дочерние процессы, но отказывается передавать им сигналы SIGHUP . Это может показаться проблемой, но на самом деле это полезная функция.

Команда nohup

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

Это то, что делает nohup . Он запускает программы для вас, чтобы они были дочерними процессами nohup , а не дочерними процессами оболочки. Поскольку они не являются дочерними процессами оболочки, они не будут получать SIGHUP напрямую от оболочки. И если nohup не передает SIGHUP своим потомкам, программа вообще не получит SIGHUP .

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

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

Мы создали программу, которая не делает ничего полезного, но она будет работать и работать, пока не будет завершена. Он печатает время в окне терминала каждые три секунды. Это называется long-proc для «долгого процесса».

 ./длинный процесс 

Длинная программа, запускающая окно терминала

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

 nohup ./long-proc 

запуск программы long-proc из nohup

Процесс отделен от стандартного ввода и стандартного stdout , поэтому он не может ни получать stdin , ни записывать в окно терминала. Кроме того, поскольку он все еще работает, вы не вернетесь в командную строку. Все, что делает nohup , — это делает процесс непроницаемым для закрытия терминала. Это не превращает процесс в фоновую задачу.

Теперь вам нужно перезагрузиться, чтобы завершить процесс? Нет. Чтобы остановить процесс nohup , который вы не запустили как фоновый процесс, нажмите комбинацию клавиш Ctrl+C.

Остановка долгого процесса с помощью Ctrl+C

Вывод программы был записан для нас в файл с именем «nohup.out». Мы можем просмотреть его с меньшими затратами.

 меньше 

Открытие файла nohup.out за меньшее время

Все, что обычно отправляется в окно терминала, фиксируется в файле. Последующие запуски nohup будут добавляться к существующему файлу «nohup.out».

Вывод long-proc, записанный в файл nohup.out, отображается в меньшем

Более полезный способ запустить процесс — запустить его с помощью nohup , чтобы он выдержал закрытие окна терминала, и при этом сделать его фоновой задачей. Для этого мы добавляем амперсанд « & » в конец командной строки.

 nohup ./long-proc & 

запуск программы long-proc с помощью nohup и перевод ее в фоновую задачу

Вам нужно будет нажать «Enter» еще раз, чтобы вернуться в командную строку. Нам сообщают, что номер задания процесса — 1 — число в квадратных скобках « [] » — и что идентификатор процесса — 13115.

Мы можем использовать любой из них, чтобы завершить процесс. «Ctrl+C» теперь не работает, потому что программа не имеет никакой связи ни с окном терминала, ни с оболочкой.

Если вы забыли номер задания, вы можете использовать команду jobs , чтобы вывести список фоновых задач, запущенных из этого окна терминала.

 рабочие места 

Список фоновых задач, запущенных из окна терминала

Чтобы убить нашу задачу, мы можем использовать команду kill и номер задания, которому предшествует знак процента « % », например:

 убить %1

Если вы закрыли окно терминала, вам нужно найти идентификатор процесса и использовать его с командой kill . Команда pgrep найдет идентификатор процесса для процессов, которые соответствуют введенному вами ключу поиска. Мы будем искать имя процесса.

 pgrep длинный процесс 

Поиск идентификатора процесса по имени

Теперь мы можем использовать идентификатор процесса, чтобы завершить процесс.

 убить 13115 

Использование команды kill и идентификатора процесса для завершения процесса

В следующий раз, когда вы нажмете «Enter», вы будете проинформированы о том, что процесс завершен.

Теперь давайте посмотрим, что не завершает процесс. Мы перезапустим его, а затем закроем окно терминала.

 nohup ./long-proc 

Закрытие окна терминала с запущенным процессом

Если мы откроем новое окно терминала и найдем наш процесс с помощью pgrep , мы увидим, что он все еще работает. Закрытие окна терминала, запустившего процесс, не дало результата.

 pgrep длинный процесс 

Использование pgrep для поиска процесса по имени

В nohup можно передать несколько команд, но обычно лучше запускать их по отдельности. Это упрощает манипулирование ими как фоновыми заданиями. Команды не будут выполняться одновременно, они будут выполняться одна за другой. Выполнение не параллельное, оно последовательное. Чтобы они работали одновременно, вам нужно запускать их отдельно.

Сказав это, чтобы запустить несколько процессов одновременно, используйте nohup для запуска оболочки Bash и используйте параметр -c (команды) со строкой команд. Используйте одинарные кавычки ' » для переноса списка команд и двойные амперсанды « && » для разделения команд.

 nohup bash -c 'ls /bin && ls /sbin' 

Запуск двух процессов с nohup

Если вы используете less для просмотра файла «nohup.out», вы увидите вывод первого процесса, а затем вывод второго процесса.

 меньше 

Открытие файла nohup.out за меньшее время

Вывод обеих команд был захвачен в файле «nohup.out». Это не переплетается, вывод из второго процесса начинается только после завершения первого процесса.

Содержимое файла nohup.out меньше

Если вы хотите использовать свой собственный файл вместо «nohup.out», вы можете перенаправить команду в файл по вашему выбору.

 nohup bash -c 'ls /bin && ls /sbin' > myfile.txt 

перенаправление вывода из процессов в предоставленный пользователем файл

Обратите внимание, что в сообщении больше не говорится «добавление вывода в nohupo.out», а говорится «перенаправление stderr в stdout», и мы перенаправляем stdout в наш файл «myfile.txt».

Мы можем заглянуть внутрь файла «myfile.txt» с меньшими затратами.

 меньше myfile.txt 

Как и прежде, он содержит выходные данные обеих команд.


Забавно, как история утилиты может иногда создавать впечатление, что она не имеет отношения к современности. Команда nohup — одна из них. Что-то, что было создано, чтобы справляться с разрывами в последовательных линиях, по-прежнему полезно сегодняшним пользователям Linux на невероятно мощных машинах.

СВЯЗАННЫЕ: 37 важных команд Linux, которые вы должны знать