CLI AI

Как оставить команду работать после выхода из SSH

2026-05-29

Запустить команду в фоне после выхода из SSH проще всего командой nohup ./import.sh > import.log 2>&1 & — это годится, когда вы заранее знаете, что процесс переживёт сессию. Но есть ещё пять ситуаций, которые эта команда не решает: например, вы забыли про nohup уже после запуска, или процесс должен пережить не только разрыв SSH, но и перезагрузку.

1. Знаю заранее, что процесс будет долгим

clai
$ clai запусти этот скрипт так, чтобы он пережил разрыв ssh, и пиши вывод в файл→ nohup ./import.sh > import.log 2>&1 &

nohup перехватывает SIGHUP, который приходит процессу при закрытии терминала. & уводит в фон. Перенаправление обязательно: иначе вывод уедет в nohup.out в текущем каталоге, и вы будете искать его потом.

2. Уже запустил и забыл про nohup

clai
$ clai отвяжи запущенный процесс от терминала, я забыл про nohup→ Ctrl+Z; bg; disown -h %1

Ctrl+Z приостанавливает, bg возобновляет в фоне, disown -h убирает задачу из списка оболочки, чтобы ей не послали SIGHUP. Это спасательный вариант, когда процесс уже час работает и убивать его жалко.

3. Нужно полностью отвязать от сессии

clai
$ clai запусти команду в отдельной сессии, полностью отвязанной от терминала→ setsid --fork ./import.sh > import.log 2>&1

setsid создаёт новую сессию и группу процессов, поэтому процесс не получит сигналов терминала вообще. Более радикально, чем nohup: у процесса не остаётся управляющего терминала.

4. Нужно вернуться и посмотреть, что там

clai
$ clai запусти в фоне так, чтобы я мог потом подключиться и посмотреть→ tmux new -d -s import './import.sh'

-d создаёт сессию отсоединённой. Позже tmux attach -t import возвращает вас к живому терминалу процесса. Это единственный вариант из списка, где можно не только смотреть, но и взаимодействовать.

5. Пусть за процессом следит systemd

clai
$ clai запусти это как временную службу systemd, чтобы был лог и статус→ systemd-run --user --unit=import ./import.shRunning as unit: import.service; invocation ID: 74282bc256f144cdb323c19fc09452af

Получаете журнал через journalctl --user -u import, статус через systemctl --user status import и автоматический перезапуск при желании. Лучший вариант для того, что должно пережить и вашу сессию, и перезагрузку.

6. Проверить, что процесс действительно отвязан

clai
$ clai проверь, отвязан ли процесс от терминала→ ps -o pid,ppid,sid,tty,comm -p 12345

Если в колонке TTY стоит ?, управляющего терминала нет и разрыв связи процессу не страшен. Если там pts/0 — он всё ещё привязан к вашей сессии и умрёт вместе с ней.

Грабли

  • nohup без перенаправления пишет в nohup.out. Файл создаётся в текущем каталоге, а если туда нельзя писать — в домашнем. Задавайте путь явно.
  • disown не защищает от SIGHUP уже отправленного. Он снимает задачу с учёта оболочки. Если вы уже закрыли терминал, поздно.
  • tmux и screen умирают при перезагрузке. Для того, что должно пережить ребут, нужен systemd-юнит, а не мультиплексор.

Похожие вопросы

nohup или tmux? nohup — «запустил и забыл», вывод в файл. tmux — когда нужно вернуться к живому процессу и что-то ему ввести.

Почему процесс всё равно умер после выхода? Либо это был не SIGHUP, а завершение по родителю, либо процесс сам завершился по ошибке. Смотрите лог, который вы, надеюсь, перенаправили.

Как посмотреть вывод уже запущенного фонового процесса? Если вывод шёл в файл — tail -f. Если никуда — можно подсмотреть через strace -p PID -e write или дескрипторы в /proc/PID/fd.

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

CliAI не напомнит вам добавить nohup, но выберет нужный инструмент под ситуацию ещё до запуска. Установите одной строкой.