open atlas
↑ К треку
Командная строка CLI · 07 · 03

Задачи и фоновый запуск

Управление задачами позволяет приостанавливать, переводить в фон и на передний план процессы внутри сессии оболочки. nohup и disown защищают долго выполняющиеся задачи от SIGHUP при закрытии терминала — без них одного фонового запуска недостаточно.

CLI Middle ◷ 22 min
Уровень
ОсновыJuniorMiddleSenior

Ты запускаешь долгую сборку, понимаешь, что нужно сделать что-то ещё в том же терминале, и инстинктивно нажимаешь Ctrl-C — убивая сборку полностью. Или запускаешь задачу в фоне с &, закрываешь терминал, и обнаруживаешь задачу мёртвой. Оба случая можно избежать. В оболочке есть полноценная подсистема управления задачами: приостановить, возобновить, перевести в фон, на передний план и отвязать. Зная эти пять операций, ты перестанешь тратить ни время, ни вычислительные ресурсы.

Цель

После этого урока ты сможешь запускать команду в фоне с &, приостанавливать выполняющуюся команду с Ctrl-Z, проверять задачи с jobs, перемещать задачи между передним планом и фоном с fg и bg, и защищать долго выполняющиеся задачи от закрытия терминала с nohup и disown.

1

& сразу запускает команду в фоновом режиме. Добавь & к любой команде — оболочка переводит дочерний процесс в фоновую группу процессов, печатает номер задачи и PID, и сразу возвращает приглашение.

python train.py &
# [1] 2047

[1]номер задачи, локальный индекс оболочки. 2047 — PID. Процесс выполняется; приглашение доступно. Его stdout и stderr всё ещё идут на терминал, если не перенаправить.

python train.py > train.log 2>&1 &

Теперь вывод идёт в train.log и терминал чистый. Фоновый процесс всё ещё в той же сессии, что и оболочка — он получит SIGHUP при завершении сессии (шаг 5).

2

Ctrl-Z отправляет SIGTSTP группе процессов переднего плана, приостанавливая её. Процесс не убивается — он ставится на паузу (STAT T). Оболочка восстанавливает управление и выводит:

^Z
[1]+  Stopped                 vim notes.txt

Задача теперь остановлена. Её состояние в /proc/<PID>/statusT (остановлен). Она удерживает всю память, открытые файлы и сокеты — ничего не освобождается. Позже можно возобновить.

Почему это важно: Ctrl-Z — способ выйти из интерактивной программы без потери работы. Приостанови vim, выполни команды в оболочке, затем верни vim обратно.

3

jobs выводит все задачи текущей сессии оболочки.

jobs
# [1]-  Stopped    vim notes.txt
# [2]+  Running    python train.py &

+ отмечает текущую задачу (последнюю выведенную на передний план или остановленную). -предыдущую. Задачи адресуются по номеру: %1, %2, или %% для текущей.

fg выводит задачу на передний план. Подключает stdin/stdout к терминалу и помещает процесс обратно в группу процессов переднего плана.

fg %1      # вывести задачу 1 (vim) на передний план
fg         # вывести текущую задачу (отмеченную +) на передний план

bg возобновляет остановленную задачу в фоне. Отправляет SIGCONT, но не перемещает на передний план.

bg %1      # возобновить задачу 1 в фоне
4

nohup делает команду иммунной к SIGHUP. При выходе из системы или закрытии терминала оболочка отправляет SIGHUP всей своей группе процессов. Любая фоновая задача без защиты погибнет. nohup перенаправляет stdin из /dev/null, по умолчанию добавляет stdout+stderr в nohup.out, и устанавливает обработчик игнорирования SIGHUP перед exec командды.

nohup python train.py > train.log 2>&1 &
echo $!    # PID только что запущенной фоновой задачи

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

5

disown убирает задачу из таблицы задач оболочки постфактум. Если забыл использовать nohup, но задача уже запущена — disown разрывает связь оболочка-задача. Оболочка больше не будет отправлять SIGHUP этому процессу при выходе.

./long-script.sh &     # забыли nohup
jobs                   # [1]+  Running  ./long-script.sh
disown %1              # убрать из таблицы задач
jobs                   # (пусто — оболочка больше не отслеживает)

Процесс теперь осиротел с точки зрения оболочки. Linux перепривязывает его к PID 1 (init), который никогда не отправляет SIGHUP. Процесс выполняется до завершения или явного уничтожения.

disown -h оставляет задачу в таблице, но помечает её как не получающую SIGHUP — полезно, если всё ещё хочешь видеть её в jobs.

Разбор примера

Запустить долгий бэкап, проверить на полпути, затем защитить от выхода из системы.

# Запустить бэкап в фоне с захватом вывода
tar czf /backup/home.tar.gz /home/alice > /tmp/backup.log 2>&1 &
echo "PID: $!"

# Проверить прогресс без прерывания
jobs
tail -f /tmp/backup.log   # Ctrl-C выйти из tail, бэкап продолжается

# Понимаешь, что нужно закрыть SSH-сессию.
# Защитить задачу:
disown %%

# Убедиться, что задача отвязана
jobs    # пусто
ps aux | grep tar   # всё ещё выполняется

Если бы использовал nohup при запуске:

nohup tar czf /backup/home.tar.gz /home/alice > /tmp/backup.log 2>&1 &

Оба подхода работают; nohup при запуске проще. disown спасает, когда забыл.

Почему это работает

Управление задачами (&, fg, bg, jobs) — функция интерактивных оболочек. В неинтерактивных скриптах (запущенных через cron, systemd или CI-пайплайны) управление задачами отключено по умолчанию. Фоновый & всё ещё работает для форка процесса, но fg и bg завершатся с ошибкой «no job control». Для долго выполняющихся процессов в таких контекстах используй менеджеры процессов (systemd-юниты, supervisor), а не управление задачами оболочки.

Частая ошибка

Запуск задачи в фоне с & НЕ защищает её от SIGHUP. Это самая распространённая ошибка управления задачами. sleep 3600 & и затем закрытие терминала убивает sleep. Флаг фонового режима означает только «не блокировать приглашение» — он ничего не говорит об иммунитете к SIGHUP. Всегда сочетай & либо с nohup (при запуске), либо с disown (постфактум), когда нужно, чтобы задача пережила закрытие терминала.

Проверь себя
Викторина

Ты запускаешь: python train.py & затем закрываешь терминал. Процесс обучения погибает. Что нужно было сделать?

Итог

& запускает команду в фоне; Ctrl-Z приостанавливает процесс переднего плана (SIGTSTP, STAT T). jobs перечисляет задачи по номерам; fg %n выводит задачу на передний план; bg %n возобновляет остановленную задачу в фоне (SIGCONT). Фоновые задачи всё равно получают SIGHUP при закрытии терминала — одного & недостаточно для защиты. nohup игнорирует SIGHUP при запуске и перенаправляет вывод в nohup.out; disown убирает уже запущенную задачу из таблицы задач оболочки, разрывая связь SIGHUP.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.