Ctrl-C от питона до bash - PullRequest
       1

Ctrl-C от питона до bash

1 голос
/ 06 октября 2019

У меня есть скрипт оболочки bash, который вызывает скрипт Python в бесконечном цикле:

while true; do python testomat.py ; done  

Скрипт Python testomat.py:

try:
    do_something()
except KeyboardInterrupt:
    print 'exit'
finally:
    raise SystemExit

У меня проблемаэто то, что я не могу остановить это на Ctrl-C. Мой единственный шанс: Ctrl-z, а затем kill -TERM %1, при условии, что у меня нет других запущенных заданий. Должен ли Python каким-то образом распространять Ctrl-C на родительский или как я смогу это остановить?

Я знаю, что мог бы запустить бесконечный цикл внутри Python, но на самом деле я делаю больше и в сценарии оболочки bashи сценарий Python, который должен продолжать существовать.

Ответы [ 2 ]

2 голосов
/ 06 октября 2019

Установите статус выхода в скрипте Python и перехватите его в скрипте Bash. Я бы использовал 130, так как это то, что используют coreutils, такие как grep и find.

except KeyboardInterrupt:
    sys.exit(130)
while true; do
    python testomat.py
    case $? in
    130) break ;;
    esac
done
0 голосов
/ 06 октября 2019

Вы заметите, что обычно можете прерывать циклы оболочки. Например, этот цикл завершится очень хорошо, когда вы нажмете Ctrl-C:

while true; do sleep 10; done

Родительский процесс - здесь оболочка - может определить, нормально ли завершился дочерний процесс или он был убитсигнал. Если он был убит сигналом, оболочка сочтет сигнал необработанным и остановит цикл и / или скрипт. Если дочерний объект получает сигнал, но выходит нормально, оболочка посчитает, что он обработан, и продолжит.

Когда процесс хочет выполнить некоторую очистку, он обязательно обрабатывает сигнал и, следовательно, не уничтожается. Таким образом, каноническое поведение Unix заключается в том, что когда очистка завершена, удалить обработчик сигнала и заново убить себя:

import time
import os
import signal

try:
  time.sleep(10);
except KeyboardInterrupt:
  print('exit')
  signal.signal(signal.SIGINT, signal.SIG_DFL)
  os.kill(os.getpid(), signal.SIGINT)

Поскольку причина смерти правильно передается обратно в оболочку, вы теперь будетевозможность Ctrl-C из вашего while true; do python yourfile.py; done цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...