Библиотека subprocess

Вызов внешних команд

Простейший вариант использования использует subprocess.call функцию. Он принимает список в качестве первого аргумента. Первым элементом в списке должно быть внешнее приложение, которое вы хотите вызвать. Другие элементы в списке являются аргументами, которые будут переданы этому приложению.

 subprocess.call([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])

 

Для команд оболочки, установленной shell=True и обеспечить команду в виде строки , а не списка.

 subprocess.call('echo "Hello, world"', shell=True)

 

Обратите внимание , что две команды выше возврата только exit status подпроцесса. Кроме того, обратите внимание при использовании shell=True , так как она обеспечивает проблемы безопасности (см здесь ).

Если вы хотите , чтобы иметь возможность получить стандартный вывод подпроцесса, то подставим subprocess.call с subprocess.check_output.Для более опытных пользователей, обратитесь к этим .

Больше гибкости с Popen

Использование subprocess.Popen дает более мелкозернистую контроль над запущенными процессами , чем subprocess.call .

Запуск подпроцесса

 process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])

 

Сигнатура Popen очень похожа на call функцию; Однако, Popen немедленно вернуться вместо того , чтобы ждать подпроцесса для завершения , как call делает.

Ожидание завершения подпроцесса

 process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
process.wait()

 

Чтение вывода из подпроцесса

 process = subprocess.Popen([r'C:\path\to\app.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# This will block until process completes
stdout, stderr = process.communicate()
print stdout
print stderr

 

Интерактивный доступ к запущенным подпроцессам

Вы можете читать и писать на stdin и stdout , даже в то время как подпроцесс не завершена. Это может быть полезно при автоматизации функций в другой программе.

Запись в подпроцесс

 process = subprocess.Popen([r'C:\path\to\app.exe'], stdout = subprocess.PIPE, stdin = subprocess.PIPE)


process.stdin.write('line of input\n') # Write input

line  = process.stdout.readline() # Read a line from stdout

# Do logic on line read.

 

Тем не менее, если вам нужно только один набор входных и выходных, а не динамическое взаимодействие, вы должны использовать communicate() , а не прямой доступом stdin и stdout .

Чтение потока из подпроцесса

Если вы хотите видеть вывод подпроцесса построчно, вы можете использовать следующий фрагмент:

 process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE)
while process.poll() is None:
    output_line = process.stdout.readline()

 

в случае, если выходные данные подкоманды не имеют символа EOL, приведенный выше фрагмент не работает. Затем вы можете прочитать вывод за символом следующим образом:

 process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE)
while process.poll() is None:
    output_line = process.stdout.read(1)

 

1 указывается в качестве аргумента к read методу говорит чтение для чтения 1 знака времени. Вы можете указать, чтобы прочитать столько символов, сколько вы хотите, используя другой номер. Отрицательное число или 0 указывает на read для чтения в виде одной строки до EOF не встречается ( см здесь ).

В обоих указанных выше фрагментов, то process.poll() не является None до подпроцесса отделки. Это используется для выхода из цикла, когда больше нет выходных данных для чтения.

Же процедура может быть применена к stderr подпроцесса.

Как создать аргумент списка команд

Метод подпроцесса , что позволяет запускать команды нуждается в команде в виде списка ( по крайней мере , с помощью shell_mode=True ).

Правила для создания списка не всегда просты, особенно для сложных команд. К счастью, есть очень полезный инструмент , который позволяет делать это: shlex.Самый простой способ создания списка для использования в качестве команды заключается в следующем:

 import shlex
cmd_to_subprocess = shlex.split(command_used_in_the_shell)

 

Простой пример:

 import shlex
shlex.split('ls --color -l -t -r')

out: ['ls', '--color', '-l', '-t', '-r'] 

Синтаксис

Параметры

Примечания