ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

Фоновые задачи: jobs, fg, bg и nohup

Автор: · Обновлено

Job control — функция интерактивного shell, которая объединяет процессы pipeline в задания и позволяет переключать их между foreground, background и stopped состояниями. Это удобно для временной работы в терминале, но не заменяет диспетчер сервисов.

Запуск в фоне и PID

Амперсанд возвращает управление shell, а $! содержит PID последнего фонового pipeline или процесса в предусмотренной Bash форме.

sleep 120 &
pid=$!
printf 'started pid=%s\n' "$pid"
jobs -l
wait "$pid"

jobs знает только задания текущего shell. В новом терминале список пуст, хотя процесс может продолжать жить. Для общего наблюдения нужны ps, service manager или приложение, которое хранит собственную identity.

Foreground, stop и continue

Foreground job владеет терминалом и получает ввод. Ctrl+Z обычно отправляет SIGTSTP и останавливает группу. bg %1 продолжает её в фоне, fg %1 возвращает на передний план. Номер job %1 не является PID.

sleep 300
# В интерактивном терминале: Ctrl+Z
jobs
bg %1
fg %1

Команды job control могут быть выключены в неинтерактивном shell. Автоматизация не должна зависеть от ручных номеров заданий.

Что решает nohup

nohup настраивает игнорирование SIGHUP для запускаемой команды и при необходимости перенаправляет вывод. Это помогает короткой задаче пережить закрытие терминала, но не предоставляет restart policy, readiness, ограничение ресурсов, ротацию логов или управляемые секреты.

nohup sh -c 'sleep 5; date -Is' >/tmp/nohup-demo.log 2>&1 &
pid=$!
printf '%s\n' "$pid"

Для постоянного процесса используйте systemd service. Для задач сессии можно рассмотреть terminal multiplexer, но его состояние тоже нужно осознанно наблюдать.

Ошибка и диагностика

Частая ошибка — запустить сервер через command &, закрыть SSH и считать его сервисом. Процесс может получить SIGHUP, потерять stdin, писать в закрытый terminal или остаться без владельца. Проверьте PPID, дескрипторы в /proc/PID/fd, журнал и способ рестарта. Если работа постоянная, перенесите её в unit вместо добавления всё большего числа shell-трюков.

Практика

Запустите два sleep в фоне, найдите их через jobs -l, дождитесь одного по PID и завершите второй через TERM. Затем выполните короткую nohup-команду с явным stdout/stderr и после её завершения проверьте файл и status, если процесс остаётся дочерним текущего shell.

Что важно запомнить

Частые вопросы

Почему jobs пуст, хотя ps видит процесс?

Процесс запущен другим shell либо уже отвязан от таблицы заданий текущей сессии. jobs не является системным реестром.

Что делает & в конце pipeline?

Shell запускает весь asynchronous list в фоне и сразу возвращает prompt. Отдельные элементы pipeline остаются одной job-группой.

Нужно ли использовать disown после nohup?

Это разные механизмы. disown удаляет job из таблицы Bash и может менять реакцию shell на HUP; nohup настраивает сам запускаемый процесс. Для сервиса оба хуже явного unit.

Источники