Поиск по сайту:

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


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

HUP и SIGHUP

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

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

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

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

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

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

Команда nohup

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

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

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

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

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

./long-proc

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

nohup ./long-proc

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

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

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

less nohup.out

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

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

nohup ./long-proc &

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

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

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

jobs

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

kill %1

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

pgrep long-proc

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

kill 13115

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

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

nohup ./long-proc

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

pgrep long-proc

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

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

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

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

less nohup.out

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

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

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

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

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

less myfile.txt

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

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