Коли ви закриєте вікно терміналу, емулятор термінала надсилає SIGHUP до процесу, який він працює, вашої оболонки. Потім ваша оболонка пересилає цей SIGHUP до всього, що він працює. У вашій локальній системі це ssh. Потім ssh пересилає SIGHUP на те, що він працює, на віддалену оболонку. Тоді ваша віддалена оболонка відправляє SIGHUP на всі його процеси, на вашу фонову програму.
Є два шляхи навколо цього.
- Від'єднайте фонову програму від вашої оболонки.
- Використовуйте
disown
команду після фонового процесу. Це змусить оболонку забути про неї.
- Префікс вашої команди за допомогою
nohup
( nohup $python program.py &
). Це здійснює те саме, але за допомогою проміжного процесу. В основному він ігнорує сигнал SIGHUP, а потім розгортає та виконує вашу програму, яка успадковує налаштування, а потім виходить. Оскільки він роздвоєний, запущена програма не є дочірньою оболонкою, і оболонка не знає про неї. І якщо він не встановить обробник сигналу для SIGHUP, він все одно зберігає дії ігнорування.
- Використовуйте
logout
замість того, щоб закривати вікно терміналу. Коли ви використовуєте logout
, це не SIGHUP, і тому оболонка не надсилатиме SIGHUP жодному зі своїх дітей.
Крім того, ви повинні переконатися, що ваша програма не записує в термінал через STDOUT або STDERR, оскільки обидва вони більше не існуватимуть, коли термінал вийде. Якщо ви не переспрямовуєте їх на щось подібне /dev/null
, програма все одно запуститься, але якщо вона спробує записати на них, вона отримає SIGPIPE, а дія SIGPIPE за замовчуванням - це вбити процес).