Запустить команду в фоне после выхода из SSH проще всего командой nohup ./import.sh > import.log 2>&1 & — это годится, когда вы заранее знаете, что процесс переживёт сессию. Но есть ещё пять ситуаций, которые эта команда не решает: например, вы забыли про nohup уже после запуска, или процесс должен пережить не только разрыв SSH, но и перезагрузку.
1. Знаю заранее, что процесс будет долгим
$ clai запусти этот скрипт так, чтобы он пережил разрыв ssh, и пиши вывод в файл→ nohup ./import.sh > import.log 2>&1 &
nohup перехватывает SIGHUP, который приходит процессу при закрытии терминала. & уводит в фон. Перенаправление обязательно: иначе вывод уедет в nohup.out в текущем каталоге, и вы будете искать его потом.
2. Уже запустил и забыл про nohup
$ clai отвяжи запущенный процесс от терминала, я забыл про nohup→ Ctrl+Z; bg; disown -h %1
Ctrl+Z приостанавливает, bg возобновляет в фоне, disown -h убирает задачу из списка оболочки, чтобы ей не послали SIGHUP. Это спасательный вариант, когда процесс уже час работает и убивать его жалко.
3. Нужно полностью отвязать от сессии
$ clai запусти команду в отдельной сессии, полностью отвязанной от терминала→ setsid --fork ./import.sh > import.log 2>&1
setsid создаёт новую сессию и группу процессов, поэтому процесс не получит сигналов терминала вообще. Более радикально, чем nohup: у процесса не остаётся управляющего терминала.
4. Нужно вернуться и посмотреть, что там
$ clai запусти в фоне так, чтобы я мог потом подключиться и посмотреть→ tmux new -d -s import './import.sh'
-d создаёт сессию отсоединённой. Позже tmux attach -t import возвращает вас к живому терминалу процесса. Это единственный вариант из списка, где можно не только смотреть, но и взаимодействовать.
5. Пусть за процессом следит systemd
$ 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 проверь, отвязан ли процесс от терминала→ 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, но выберет нужный инструмент под ситуацию ещё до запуска. Установите одной строкой.