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

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


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

Все о процессах

Всякий раз, когда программа выполняется в Linux или Unix-подобной операционной системе, запускается процесс. «Процесс» — это название внутреннего представления исполняемой программы в памяти компьютера. Для каждой активной программы существует процесс. На самом деле, существует процесс почти для всего, что запущено на вашем компьютере. Сюда входят компоненты графической среды рабочего стола (GDE), такие как GNOME или KDE, а также системные демоны, которые запускаются при запуске.

Почему почти все, что запущено? Что ж, встроенные функции Bash, такие как cd, pwd и alias, не требуют запуска (или «порождения») процесса при их запуске. Bash выполняет эти команды в экземпляре оболочки Bash, которая запущена в окне вашего терминала. Эти команды выполняются быстро именно потому, что для их выполнения не требуется запускать процесс. (Вы можете ввести help в окне терминала, чтобы просмотреть список встроенных модулей Bash.)

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

Грязный пример

Мы запустим простую трассировку ping. Мы собираемся пинговать домен How-To Geek. Это будет выполняться как процесс переднего плана.

ping linux-console.net

Получаем ожидаемые результаты, прокручивая окно терминала вниз. Мы не можем ничего делать в окне терминала, пока выполняется ping. Чтобы завершить команду, нажмите Ctrl+C.

Ctrl+C

Видимый эффект Ctrl+C выделен на снимке экрана. ping выдает краткую сводку, а затем останавливается.

Давайте повторим это. Но на этот раз мы нажмем Ctrl+Z вместо Ctrl+C. Задача не будет прекращена. Это станет фоновой задачей. Нам вернули управление окном терминала.

ping linux-console.net
Ctrl+Z

Видимый эффект от нажатия Ctrl+Z выделен на снимке экрана.

На этот раз нам говорят, что процесс остановлен. Остановлено не значит прекращено. Это как машина на остановке. Мы его не разобрали и не выбросили. Он все еще в пути, стоит на месте, ждет своего часа. Теперь процесс является фоновым заданием.

Команда jobs выведет список заданий, которые были запущены в текущем сеансе терминала. А поскольку задания (неизбежно) являются процессами, мы также можем использовать команду ps, чтобы увидеть их. Давайте воспользуемся обеими командами и сравним их результаты. Мы будем использовать параметр T (терминал), чтобы перечислить только процессы, которые выполняются в этом окне терминала. Обратите внимание, что нет необходимости использовать дефис - с опцией T.

jobs
ps T

Команда jobs говорит нам:

  • [1]: число в квадратных скобках — это номер задания. Мы можем использовать это для ссылки на задание, когда нам нужно управлять им с помощью команд управления заданием.
  • +: знак плюса + показывает, что это задание будет выполнено, если мы используем команду управления заданием без определенного номера задания. Это называется заданием по умолчанию. Заданием по умолчанию всегда является последнее добавленное в список заданий.
  • Остановлено: процесс не запущен.
  • ping linux-console.net: командная строка, которая запустила процесс.

Команда ps говорит нам:

  • PID: идентификатор процесса. Каждый процесс имеет уникальный идентификатор.
  • TTY: псевдотелетайп (окно терминала), из которого был запущен процесс.
  • STAT: статус процесса.
  • ВРЕМЯ: количество процессорного времени, потребляемого процессом.
  • КОМАНДА: команда, которая запустила процесс.

Это общие значения для столбца STAT:

  • D: Непрерывный сон. Процесс находится в состоянии ожидания, обычно ожидая ввода или вывода, и его нельзя прервать.
  • Я: бездействует.
  • Р: Бегу.
  • S: прерывистый сон.
  • T: остановлен по сигналу управления заданием.
  • Z: зомби-процесс. Процесс был остановлен, но его родительский процесс не «очистил».

За значением в столбце STAT может следовать один из следующих дополнительных индикаторов:

  • <: задача с высоким приоритетом (неприятная для других процессов).
  • Н: низкий приоритет (удобно для других процессов).
  • L: у процесса есть страницы, заблокированные в памяти (обычно используемые процессами реального времени).
  • s: лидер сеанса. Лидер сеанса — это процесс, запустивший группы процессов. Оболочка является лидером сеанса.
  • l: многопоточный процесс.
  • +: процесс переднего плана.

Мы видим, что Bash имеет состояние Ss. Заглавная буква «S» говорит нам, что оболочка Bash спит, и ее можно прервать. Как только он нам понадобится, он ответит. Строчная буква «s» говорит нам, что оболочка является лидером сеанса.

Команда ping имеет состояние T. Это говорит нам о том, что ping был остановлен сигналом управления заданием. В этом примере это был Ctrl+Z, который мы использовали, чтобы перевести его в фоновый режим.

Команда ps T имеет состояние R, что означает выполнение. Значок + указывает, что этот процесс является членом группы переднего плана. Таким образом, команда ps T выполняется на переднем плане.

Команда bg

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

Если мы выполним команду bg, мы возобновим нашу команду ping:

bg

Команда ping возобновляется, и мы снова видим вывод прокрутки в окне терминала. Имя команды, которая была перезапущена, отображается для вас. Это выделено на скриншоте.

Но у нас есть проблема. Задача работает в фоновом режиме и не принимает ввод. Так как же нам это остановить? Ctrl+C ничего не делает. Мы можем видеть это, когда набираем его, но фоновая задача не получает эти нажатия клавиш, поэтому она продолжает весело пинговаться.

Фактически, сейчас мы находимся в странном смешанном режиме. Мы можем печатать в окне терминала, но то, что мы набираем, быстро сметается прокручивающимся выводом команды ping. Все, что мы печатаем, вступает в силу на переднем плане.

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

Команда fg

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

Если мы введем fg, наша команда ping будет переведена на передний план. Вводимые нами символы смешиваются с выводом команды ping, но оболочка обрабатывает их так, как если бы они были введены в командной строке, как обычно. И на самом деле, с точки зрения оболочки Bash, именно это и произошло.

fg

И теперь, когда команда ping снова запущена на переднем плане, мы можем использовать Ctrl+C, чтобы остановить ее.

Ctrl+C

Нам нужно подавать правильные сигналы

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

Но, беспорядочно это или нет, наш пример выполнил:

  • Перевод процесса в фоновый режим.
  • Восстановление рабочего состояния процесса в фоновом режиме.
  • Возвращение процесса на передний план.
  • Завершение процесса.

Когда вы используете Ctrl+C и Ctrl+Z , вы отправляете сигналы процессу. Это сокращенные способы использования команды kill. kill может отправлять 64 различных сигнала. Используйте kill -l в командной строке, чтобы вывести их список. kill — не единственный источник этих сигналов. Некоторые из них вызываются автоматически другими процессами в системе.

Вот некоторые из часто используемых.

  • SIGHUP: сигнал 1. Автоматически отправляется процессу, когда терминал, в котором он запущен, закрывается.
  • SIGINT: сигнал 2. Отправлен в процесс, для которого вы нажали Ctrl+C. Процесс прерывается и сообщается о прекращении.
  • SIGQUIT: сигнал 3. Отправляется процессу, если пользователь отправляет сигнал выхода Ctrl+D.
  • SIGKILL: сигнал 9. Процесс немедленно уничтожается и не будет пытаться корректно закрыться. Процесс не проходит корректно.
  • SIGTERM: Сигнал 15. Это сигнал по умолчанию, отправляемый kill. Это стандартный сигнал завершения программы.
  • SIGTSTP: Сигнал 20. Отправляется процессу, когда вы используете Ctrl+Z. Он останавливает процесс и переводит его в фоновый режим.

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

Дальнейший контроль работы

Процесс, переведенный в фоновый режим с помощью Ctrl+Z, переводится в остановленное состояние. Мы должны использовать команду bg, чтобы снова запустить его. Запустить программу как работающий фоновый процесс очень просто. Добавьте амперсанд & в конец командной строки.

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

пока правда; do echo «Процесс циклического обучения гика»; спать 3; сделанный &

Нам сообщают номер задания и идентификатор процесса. Номер нашей задачи — 1, а идентификатор процесса — 1979. Мы можем использовать эти идентификаторы для управления процессом.

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

лс

Чтобы остановить наш процесс, мы можем использовать jobs, чтобы напомнить себе номер задания, а затем использовать kill.

jobs сообщает, что наш процесс является заданием номер 1. Чтобы использовать этот номер с kill , мы должны поставить перед ним знак процента %.

jobs
kill %1

kill отправляет сигнал SIGTERM, номер сигнала 15, процессу, и он завершается. При последующем нажатии клавиши Enter отображается состояние задания. В нем процесс указан как «завершенный». Если процесс не отвечает на команду kill, вы можете поднять его на ступень выше. Используйте kill с SIGKILL , номер сигнала 9. Просто поместите число 9 между командой kill и номером задания.

kill 9 %1

Что мы рассмотрели

  • Ctrl+C: отправляет SIGINT, сигнал 2, в процесс, если он принимает ввод, и сообщает ему о завершении.
  • Ctrl+D: отправляет SISQUIT, сигнал 3, процессу, если он принимает ввод, и сообщает ему завершить работу.
  • Ctrl+Z: Отправляет SIGSTP, сигнал 20, в процесс и говорит ему остановиться (приостановить) и перейти в фоновый процесс.
  • задания: список фоновых заданий и их номер.
  • bg номер_задания: перезапускает фоновый процесс. Если вы не укажете номер задания, будет использоваться последний процесс, который был преобразован в фоновую задачу.
  • fg номер_задания: переводит фоновый процесс на передний план и перезапускает его. Если вы не укажете номер задания, будет использоваться последний процесс, который был преобразован в фоновую задачу.
  • командная строка &: добавление амперсанда & в конец командной строки выполняет эту команду как фоновую задачу, которая выполняется.
  • kill %job_number: отправляет SIGTERM, сигнал 15, процессу для его завершения.
  • kill 9 %job_number: отправляет SIGKILL, сигнал 9, процессу и резко завершает его.

RELATED: Best Linux Laptops for Developers and Enthusiasts