subprocess.Popen и communication () не выполняют программу, в то время как Terminal выполняет - PullRequest
0 голосов
/ 15 марта 2019

У меня есть процедура, которую я запускаю каждое утро, где я хочу запустить последовательность программ.Это выглядит примерно так.(содержание programCaller.py)

programs = [
    'program 1',
    'program 2',
    'program 3'
    ]

for program in programs:
    print('Executing: ' + program)
    p = subprocess.Popen('/path/to/directory/' + program)
    p.communicate()

Все работало отлично примерно неделю назад.Он общался в режиме реального времени (перк, который я изо всех сил пытался получить в Windows, так как я запускаю его на Mac), и если программа не работает, он переходит к следующему.

Теперь он не будет просто запускаться из IDLE.Тем не менее, он работает просто отлично с терминала "./programCaller.py".

Все программы, конечно же, имеют строки Шебанга и разрешение.Я перепробовал все варианты shell = True, исполняемый, стандартный вывод и другие аргументы, но это не сработает.

Что он делает, так это то, что он мгновенно заканчивает выполнение, давая мне подсказку «>>>», как будто это было сделано.И он не работает в фоновом режиме, так как я протестировал очень простую программу, которая отправляет мне письмо, и она этого не делает.

Что-то должно было измениться, и, возможно, он использует другой исполняемый файл, но это тихий сбой.

1 Ответ

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

Если это стартовый вызов, вы должны убедиться, что programCaller.py правильно вызывается с нужным вам питоном, поэтому "/path/to/Python/python" programCaller.py Я не знаю, как это работает для Mac, но в Windows я бы посоветовал вам использовать https://pypi.org/project/auto-py-to-exe/ для создания exe-файла на основе programCaller.py.

Также, если вы хотите отсортировать отладку, добавьте time.sleep() или print(p) после p.communicate() только для того, чтобы убедиться, что подпроцесс был создан правильно.Я предлагаю это, потому что если у вас другая версия Python, вы можете пропустить некоторые внешние библиотеки.

Что-то более сложное будет:

try:
    p = subprocess.Popen('/path/to/directory/' + program)
    stdout, stderr = p.communicate()
    print(stdout)
    print(stderr)
except KeyboardInterrupt:
    p.kill()
    print("KeyboardInterrupt: killing process")
except Exception as e:
    print(e)

, если подпроцесс не нуженвход:

try:
    p = subprocess.Popen('/path/to/directory/' + program)
    output = p.stdout.readline()
    if output:
        sys.stdout.flush()
        print(output)
except KeyboardInterrupt:
    p.kill()
    print("KeyboardInterrupt: killing process")
except Exception as e:
    print(e)
...