Бывает так, что из-под питонячего кода нужно вызвать какой-то исполняемый файл(*.sh). Бывает так, что этот исполняемый файл (*.sh) должен выполнить какой-то питонячий скрипт. Бывает так, что исполняемый файл надо остановить.
Тут логично, что при остановке исполняемого файла, питоновский скрипт тоже должен остановиться. Но это не так...
# Под катом:
cat fruits.py
import subprocess
like_fruit = subprocess.Popen("start_import_fruits.sh", stdout=log.stream, stderr=subprocess.STDOUT) # выполняем скрипт с помощью Popen
... # (тут извне приходит сигнал "ОСТАНОВИТЕ выброс экзотических фруктов!")
like_fruit.poll() # провереям завершение дочерних процессов и устанавливаем код возврата
if like_fruit.returncode is None: # код возврата None тогда, когда дочерний процесс еще не завершился
like_fruit.kill() # сейчас хотим убить дочерний процесс
...
cat start_import_fruits.sh
./import_fruits.py
cat import_fruits.py
# здесь долгий процесс импорта экзотических фруктов
Если посмотрим на состояние выполнения дочернего процесса (ps aux | grep start_import_fruits.sh), то увидим, что после kill'a он будет убит (ведь kill() посылает SIGKILL сигнал).
Но если внутри start_import_fruits.sh запускается долгий импорт фруктов из холодильника(под названием import_fruits.py), то даже после убийства start_import_fruits.sh импорт не завершиться. Все потому что import_fruits.py не будет убит. И об этом надо помнить.
Чтобы убить процессы, порожденные start_import_fruits.sh, можно, например, после основного убийства сделать дополнительное: запустить отдельный скрипт, который убьет то, что было порождено start_import_fruits.sh. Либо можно сохранять порождаемые pid'ы в определнной директории, а потом разом всех убивать. Либо смотреть все порождаемые родителем процессы в /proc/<number>/stat и тоже кого-то убивать. В итоге, по-любому, нужно будет дополнительного кого-то убить, например так:
ps aux | grep import_fruits.py| grep -v 'grep' | awk '{ print $2 }'` | xargs sudo kill -9
Для тех, кто еще с моим фруктами...
(с) http://www.flickr.com/photos/27495785@N05/3179853645/sizes/l/in/photostream/
А ты не пробовала убивать дочерние процессы из .sh скрипта при получении им SIGTERM?
ОтветитьУдалитьПо идее, что-то вроде:
....
trap "kill import_fruits.py; exit" TERM
./import_fruits.py
....
По идее, когда ты скажешь скрипту kill - он сам прибьет питон по 15 сигналу
хм. ну да, так тоже можно
Удалить