Linux запустить процесс в фоне

Обновлено: 02.07.2024

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

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

Как запустить процесс в фоне Linux

Для выполнения команды в фоновом режиме достаточно добавить в конце символ амперсанда (&):

В выводе терминала будут отображены порядковый номер задачи (в квадратных скобках) и идентификатор процесса:


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

Здесь >/dev/null 2>&1 обозначает, что stdout будет перенаправлен на /dev/null, а stderr — к stdout.


Узнать состояние всех остановленных и выполняемых в фоновом режиме задач в рамках текущей сессии терминала можно при помощи утилиты jobs c использованием опции -l:

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


В любое время можно вернуть процесс из фонового режима на передний план. Для этого служит команда fg:

Если в фоновом режиме выполняется несколько программ, следует также указывать номер. Например:


Для завершения фонового процесса применяют команду kill с номером программы:


Как перевести процесс в фоновый режим

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

  1. Остановить выполнение команды, нажав комбинацию клавиш Ctrl+Z.
  2. Перевести процесс в фоновый режим при помощи команды bg.


Работа процессов в фоне

Запуск скрипта в фоне linux - это одно, но надо чтобы он ещё работал после закрытия терминала. Закрытие терминала путем нажатия на крестик в верхнем углу экрана влечет за собой завершение всех фоновых процессов. Впрочем, есть несколько способов сохранить их после того как связь с интерактивной оболочкой прервется. Первый способ — это удаление задачи из очереди заданий при помощи команды disown:

Как и в предыдущих случаях, при наличии нескольких одновременно выполняемых процессов следует указывать номер того, относительно которого будет выполнено действие:


Убедиться, что задачи больше нет в списке заданий, можно, использовав уже знакомую утилиту jobs -l. А чтобы просмотреть перечень всех запущенных процессов (в том числе и отключенных) применяется команда

Второй способ сохранить запущенные процессы после прекращения работы терминала — команда nohup. Она выполняет другую команду, которая была указана в качестве аргумента, при этом игнорирует все сигналы SIGHUP (те, которые получает процесс при закрытии терминала). Для запуска команды в фоновом режиме нужно написать команду в виде:


Как видно на скриншоте, вывод команды перенаправляется в файл nohup.out. При этом после выхода из системы или закрытия терминала процесс не завершается. Существует ряд программ, которые позволяют запускать несколько интерактивных сессий одновременно. Наиболее популярные из них — Screen и Tmux.

  • Screen либо GNU Screen — это терминальный мультиплексор, который позволяет запустить один рабочий сеанс и в рамках него открыть любое количество окон (виртуальных терминалов). Процессы, запущенные в этой программе, будут выполняться, даже если их окна невидимы или программа прекратила работу.
  • Tmux — более современная альтернатива GNU Screen. Впрочем, возможности Tmux не имеют принципиальных отличий — в этой программе точно так же можно открывать множество окон в рамках одного сеанса. Задачи, запущенные в Tmux, продолжают выполняться, если терминал был закрыт.

Выводы

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

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

Что если выполнение команды займет много времени, а вы хотите выполнить другие команды в это время? В вашем распоряжении несколько вариантов. Самая очевидная и простая опция - запустить новый сеанс командной строки и запустить в нем команду. Другой вариант - запуск команды в фоновом режиме.

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

В этой статье мы поговорим о фоновых процессах Linux. Мы покажем вам, как запустить команду в фоновом режиме и как держать процесс запущенным после завершения сеанса командной строки.

Запускаем команду Linux в фоновом режиме

Чтобы выполнить команду в фоновом режиме, добавьте символ амперсанда ( & ) в конец команды:

ID задания (окруженное скобками) и ID процесса напечатаются в терминале:

/dev/null 2>&1 означает перенаправление stdout на /dev/null и stderr на stdout .

Используйте утилиту jobs для отображения статуса всех остановленных и фоновых заданий в текущем сеансе командной строки:

На выходе отображается номер задания, идентификатор процесса, состояние задания и команда, с помощью которой оно было запущено:

Чтобы вывести фоновый процесс на передний план, используйте команду fg :

Если у вас несколько фоновых заданий, укажите % и ID задания после команды:

Чтобы завершить фоновый процесс, используйте команду kill , за которой следует ID процесса:

Перенос процесса с переднего плана в фоновый режим

Перемещение выполняющегося процесса с переднего плана в фоновый режим:

  • Остановите процесс, нажав Ctrl+Z .
  • Переместите остановленный процесс в фоновый режим, набрав bg .

Поддерживание фоновых процессов в рабочем состоянии после выхода оболочки

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

Если у вас несколько фоновых заданий, укажите % и ID задания после команды:

Убедитесь, что задание удалено из таблицы активных заданий с помощью команды jobs -l . Чтобы перечислить все запущенные процессы, включая процессы, от которых отказались, воспользуйтесь командой ps aux . Другой способ сохранить процесс запущенным после выхода из оболочки - использовать nohup .

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

Вывод команды перенаправляется в файл nohup.out .

Если вы выйдете из системы или закроете терминал, процесс не будет завершен.


Запуск команд Linux в фоновом режиме

В данной заметке мы рассмотрим, как запускать команды Linux в фоновом режиме. То есть, когда после запуска какой-либо команды, она начинает свою работу в фоне, а вы продолжаете работать в терминале.

Видео

Видео-версия. Наше видео про запуск команд в фоновом режиме.

Что такое приоритетный и фоновый режимы

Обычно все команды Linux запускаются в оболочке (в командной строке) в приоритетном режиме, называемом foreground. В этом режиме оболочка ожидает завершения работы команды, прежде чем пользователь сможет ввести новую команду.

Можно запускать команды Linux в фоновом режиме — background, при котором не нужно ожидать завершения команды, чтобы запустить другую команду.

Пользователь может запускать несколько команд в фоновом режиме одновременно. То есть эти команды будут выполняться параллельно. При этом окно терминала доступно для ввода новых команд.

Как запустить команду в фоновом режиме

Чтобы запустить команду в фоновом режиме, нужно в конец команды через пробел добавить знак амперсанда &

Синтаксис запуска команды в фоновом режиме можно записать следующим образом:

Пример запуска команды в фоновом режиме

Рассмотрим пример. Предположим, нам нужно распаковать большой tar-архив. Выполняем команду:

Распаковка архива выполняется в фоновом режиме, а мы можем вводить в терминале новые команды.

Запуск команды в фоновом режиме

Как вы можете видеть, на экран выводятся символы [1] 7958
[1] — это номер, который оболочка назначила нашему фоновому заданию, чтобы мы могли идентифицировать его и управлять им (см. ниже как).
7958 — это идентификатор (PID) процесса, который был создан.

Как вывести задание из фонового режима

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

Команда fg , запущенная без аргументов, выводит из фонового режима последний запущенный фоновый процесс.

Например, запустим две команды в фоновом режиме и выполним команду fg . В результате мы выведем вторую команду из фонового режима.

Перевод в приоритетный режим. Команда fg

Можно указать номер конкретного задания, которое нужно вывести из фонового режима:

Просмотр заданий, работающих в фоновом режиме

Для просмотра заданий, работающих в фоновом режиме, используется команда jobs

Использование команды jobs

Символом плюс + помечается последнее запущенное задание. Если использовать команду fg без аргументов, то она будет применена именно к этому заданию.
Символом минус — помечается задание, которое было запущено перед последним.

Перевод задания в фоновый режим

Чтобы перевести задание, которое в данный момент работает в приоритетном режиме, в фоновый режим, используется команда bg

Так как задание работает в приоритетном режиме, то вы не можете вводить команды, поэтому сначала нужно приостановить выполнение задания. Для этого используется сочетание клавиш Ctrl+Z

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

Команда bg

Заключение

Мы кратко рассмотрели, как запускать команды Linux в фоновом режиме. Использование фонового режима позволяет запускать одновременно несколько процессов из одного окна терминала (экземпляра оболочки). Особенно это удобно, когда команда должна выполняться длительное время и не требует постоянного наблюдения. Пользователь при этом может продолжать пользоваться командной строкой.

image


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

До сих пор мы вводили имена скриптов в командную строку и нажимали Enter, что приводило к немедленному запуску программ, но это — не единственный способ вызова сценариев. Сегодня мы поговорим о том как скрипт может работать с сигналами Linux, о различных подходах к запуску скриптов и к управлению ими во время работы.

Сигналы Linux

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

Код сигнала
Название
Описание
1
SIGHUP
Закрытие терминала
2
SIGINT
Сигнал остановки процесса пользователем с терминала (CTRL + C)
3
SIGQUIT
Сигнал остановки процесса пользователем с терминала (CTRL + \) с дампом памяти
9
SIGKILL
Безусловное завершение процесса
15
SIGTERM
Сигнал запроса завершения процесса
17
SIGSTOP
Принудительная приостановка выполнения процесса, но не завершение его работы
18
SIGTSTP
Приостановка процесса с терминала (CTRL + Z), но не завершение работы
19
SIGCONT
Продолжение выполнения ранее остановленного процесса

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

Сигнал SIGINT приводит к временной остановке работы. Ядро Linux перестаёт выделять оболочке процессорное время. Когда это происходит, оболочка уведомляет процессы, отправляя им сигнал SIGINT .

Bash-скрипты не контролируют эти сигналы, но они могут распознавать их и выполнять некие команды для подготовки скрипта к последствиям, вызываемым сигналами.

Отправка сигналов скриптам

Оболочка bash позволяет вам отправлять скриптам сигналы, пользуясь комбинациями клавиш на клавиатуре. Это оказывается очень кстати если нужно временно остановить выполняющийся скрипт или завершить его работу.

Завершение работы процесса

Комбинация клавиш CTRL + C генерирует сигнал SIGINT и отправляет его всем процессам, выполняющимся в оболочке, что приводит к завершению их работы.

Выполним в оболочке такую команду:


После этого завершим её работу комбинацией клавиш CTRL + C .


Завершение работы процесса с клавиатуры

Временная остановка процесса

Комбинация клавиш CTRL + Z позволяет сгенерировать сигнал SIGTSTP , который приостанавливает работу процесса, но не завершает его выполнение. Такой процесс остаётся в памяти, его работу можно возобновить. Выполним в оболочке команду:


И временно остановим её комбинацией клавиш CTRL + Z .


Приостановка процесса

Число в квадратных скобках — это номер задания, который оболочка назначает процессу. Оболочка рассматривает процессы, выполняющиеся в ней, как задания с уникальными номерами. Первому процессу назначается номер 1, второму — 2, и так далее.

Если вы приостановите задание, привязанное к оболочке, и попытаетесь выйти из неё, bash выдаст предупреждение.

Просмотреть приостановленные задания можно такой командой:


Список заданий

В колонке S , выводящей состояние процесса, для приостановленных процессов выводится T . Это указывает на то, что команда либо приостановлена, либо находится в состоянии трассировки.

Если нужно завершить работу приостановленного процесса, можно воспользоваться командой kill . Подробности о ней можно почитать здесь.

Выглядит её вызов так:

Перехват сигналов

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

Команда trap позволяет скрипту реагировать на сигналы, в противном случае их обработка выполняется оболочкой без его участия.

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


Перехват сигналов

Каждый раз, когда вы нажимаете клавиши CTRL + C , скрипт выполняет команду echo , указанную при вызове trace вместо того, чтобы позволить оболочке завершит его работу.

Перехват сигнала выхода из скрипта

Перехватить сигнал выхода из скрипта можно, использовав при вызове команды trap имя сигнала EXIT :


Перехват сигнала выхода из скрипта

При выходе из скрипта, будь то нормальное завершение его работы или завершение, вызванное сигналом SIGINT , сработает перехват и оболочка исполнит команду echo .

Модификация перехваченных сигналов и отмена перехвата

Для модификации перехваченных скриптом сигналов можно выполнить команду trap с новыми параметрами:


Модификация перехвата сигналов

После модификации сигналы будут обрабатываться по-новому.

Перехват сигналов можно и отменить, для этого достаточно выполнить команду trap , передав ей двойное тире и имя сигнала:


Если скрипт получит сигнал до отмены перехвата, он обработает его так, как задано в действующей команде trap . Запустим скрипт:


И нажмём CTRL + C на клавиатуре.


Сигнал, перехваченный до отмены перехвата

Первое нажатие CTRL + C пришлось на момент исполнения скрипта, когда перехват сигнала был в силе, поэтому скрипт исполнил назначенную сигналу команду echo . После того, как исполнение дошло до команды отмены перехвата, команда CTRL + C сработала обычным образом, завершив работу скрипта.

Выполнение сценариев командной строки в фоновом режиме

Иногда bash-скриптам требуется немало времени для выполнения некоей задачи. При этом вам может понадобиться возможность нормально работать в командной строке, не дожидаясь завершения скрипта. Реализовать это не так уж и сложно.

Если вы видели список процессов, выводимый командой ps , вы могли заметить процессы, которые выполняются в фоне и не привязаны к терминалу.
Напишем такой скрипт:


Запустим его, указав после имени символ амперсанда ( & ):


Это приведёт к тому, что он будет запущен как фоновый процесс.


Запуск скрипта в фоновом режиме


Список процессов

При таком подходе, если выйти из терминала, скрипт, выполняющийся в фоне, так же завершит работу.

Что если нужно, чтобы скрипт продолжал работать и после закрытия терминала?

Выполнение скриптов, не завершающих работу при закрытии терминала

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

Применим эту методику при запуске нашего скрипта:


Вот что будет выведено в терминал.


Команда nohup

Обратите внимание на то, что при запуске нескольких скриптов из одной и той же директории то, что они выводят, попадёт в один файл nohup.out .

Просмотр заданий

Команда jobs позволяет просматривать текущие задания, которые выполняются в оболочке. Напишем такой скрипт:


И временно остановим комбинацией клавиш CTRL + Z .


Запуск и приостановка скрипта

Запустим тот же скрипт в фоновом режиме, при этом перенаправим вывод скрипта в файл так, чтобы он ничего не выводил на экране:


Выполнив теперь команду jobs , мы увидим сведения как о приостановленном скрипте, так и о том, который работает в фоне.


Получение сведений о скриптах

Ключ -l при вызове команды jobs указывает на то, что нам нужны сведения об ID процессов.

Перезапуск приостановленных заданий

Для того, чтобы перезапустить скрипт в фоновом режиме, можно воспользоваться командой bg .


Нажмём CTRL + Z , что временно остановит его выполнение. Выполним следующую команду:


Теперь скрипт выполняется в фоновом режиме.

Если у вас имеется несколько приостановленных заданий, для перезапуска конкретного задания команде bg можно передать его номер.

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

Планирование запуска скриптов

Linux предоставляет пару способов запуска bash-скриптов в заданное время. Это команда at и планировщик заданий cron .

Вызов команды at выглядит так:


Эта команда распознаёт множество форматов указания времени.

  • Стандартный, с указанием часов и минут, например — 10:15.
  • С использованием индикаторов AM/PM, до или после полудня, например — 10:15PM.
  • С использованием специальных имён, таких, как now , noon , midnight .
  • Стандартный формат указания даты, при котором дата записывается по шаблонам MMDDYY , MM/DD/YY , или DD.MM.YY .
  • Текстовое представление даты, например, Jul 4 или Dec 25 , при этом год можно указать, а можно обойтись и без него.
  • Запись вида now + 25 minutes .
  • Запись вида 10:15PM tomorrow .
  • Запись вида 10:15 + 7 days .


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

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

Для того чтобы посмотреть список заданий, ожидающих выполнения, можно воспользоваться командой atq :


Список заданий, ожидающих выполнения

Удаление заданий, ожидающих выполнения

Удалить задание, ожидающее выполнения, позволяет команда atrm . При её вызове указывают номер задания:


Удаление задания

Запуск скриптов по расписанию

Планирование однократного запуска скриптов с использованием команды at способно облегчить жизнь во многих ситуациях. Но как быть, если нужно, чтобы скрипт выполнялся в одно и то же время ежедневно, или раз в неделю, или раз в месяц?

В Linux имеется утилита crontab , позволяющая планировать запуск скриптов, которые нужно выполнять регулярно.

Crontab выполняется в фоне и, основываясь на данных в так называемых cron-таблицах, запускает задания по расписанию.

Для того, чтобы просмотреть существующую таблицу заданий cron , воспользуйтесь такой командой:


При планировании запуска скрипта по расписанию crontab принимает данные о том, когда нужно выполнить задание, в таком формате:


Например, если надо, чтобы некий скрипт с именем command выполнялся ежедневно в 10:30, этому будет соответствовать такая запись в таблице заданий:


Здесь универсальный символ « * », использованный для полей, задающих день месяца, месяц и день недели, указывает на то, что cron должен выполнять команду каждый день каждого месяца в 10:30.

Если, например, надо, чтобы скрипт запускался в 4:30PM каждый понедельник, понадобится создать в таблице заданий такую запись:


Нумерация дней недели начинается с 0, 0 означает воскресенье, 6 — субботу. Вот ещё один пример. Здесь команда будет выполняться в 12 часов дня в первый день каждого месяца.


Нумерация месяцев начинается с 1.
Для того чтобы добавить запись в таблицу, нужно вызвать crontab с ключом -e :


Затем можно вводить команды формирования расписания:


Благодаря этой команде скрипт будет вызываться ежедневно в 10:30. Если вы столкнётесь с ошибкой «Resource temporarily unavailable», выполните нижеприведённую команду с правами root-пользователя:


Организовать периодический запуск скриптов с использованием cron можно ещё проще, воспользовавшись несколькими специальными директориями:


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

Запуск скриптов при входе в систему и при запуске оболочки

Автоматизировать запуск скриптов можно, опираясь на различные события, такие, как вход пользователя в систему или запуск оболочки. Тут можно почитать о файлах, которые обрабатываются в подобных ситуациях. Например, это следующие файлы:


Для того, чтобы запускать скрипт при входе в систему, поместите его вызов в файл .bash_profile .

А как насчёт запуска скриптов при открытии терминала? Организовать это поможет файл .bashrc .

Итоги

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

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