Ctrl C не убивает зацикленный подпроцесс в Python - PullRequest
2 голосов
/ 21 марта 2019

Существует ли правильный способ создания сценария, который циклически просматривает файлы в папке и выполняет подпроцесс, который можно внешне убить с помощью Ctrl C?У меня есть что-то вроде следующего, встроенного в конвейер, и я не могу Ctrl C это из командной строки, когда основной процесс убит.

Пример сценария:

import subprocess
import os
import sys

input_directory = sys.argv[1]

for file in os.listdir(os.path.abspath(input_directory)):
    output = file + "_out.out"
    command = ['somescript.py', file, output]
    try:
        subprocess.check_call(command)
    except:
        print "Command Failed"

Затем я бы запустил программу:

Example_script.py /path/to/some/directory/containing/files/

Во время цикла, если я вижу, что команда не выполнена, я хочу использовать Ctrl CТем не менее, он не работает и продолжает запускать дополнительные подпроцессы, несмотря на то, что основной скрипт был разрушителем с помощью Ctrl C. Есть ли правильный способ написать что-то вроде этого, которое может убить дочерние элементы (дополнительный подпроцесс) с помощью Ctrl C?

Любая помощь или указание мне в направлении очень ценится.В настоящее время я ищу хороший способ сделать.

Ответы [ 3 ]

5 голосов
/ 21 марта 2019

То, что у вас есть в вашем блоке try / кроме, слишком допустимо, так что при нажатии Ctrl + C исключение KeyboardInterrupt также обрабатывается тем же обработчиком исключений как тот, который print "Command Failed", и как он теперь правильно обрабатывается там, поток программы продолжается через цикл for. Что вы должны сделать, это:

  1. Замените except: на except Exception:, чтобы исключение KeyboardInterrupt не было перехвачено, так что при каждом нажатии Ctrl + C программа будет завершена (включая подпроцессы, которые не застряли в каком-либо состоянии без завершения);
  2. После оператора print, break вне цикла, чтобы предотвратить дальнейшее выполнение, если это то поведение, которое вы хотите, чтобы эта программа выполняла.
0 голосов
/ 21 марта 2019

Вы можете поймать KeyboardInterrupt, таким образом, вы можете иметь дело с Ctrl + C любым удобным для вас способом.

import subprocess
import os
import sys

input_directory = sys.argv[1]

for file in os.listdir(os.path.abspath(input_directory)):
    output = file + "_out.out"
    command = ['somescript.py', file, output]
    try:
        subprocess.check_call(command)
    except KeyboardInterrupt as e:
        print "Interrupted"
        sys.exit(1)
    except:
        print "Command Failed"

Однако я согласен с другими авторами в том, что ваше исключение слишком расплывчато, и вы должны быть более конкретными в том, что может и не может быть неудачным.

0 голосов
/ 21 марта 2019

Я думаю, Ctrl + Z также может помочь вам перенести выполнение в фоновый режим и приостановить.

...