Поиск…


Синтаксис

  • subprocess.call (args, *, stdin = None, stdout = None, stderr = None, shell = False, timeout = None)
  • subprocess.Popen (args, bufsize = -1, executable = None, stdin = None, stdout = None, stderr = None, preexec_fn = None, close_fds = True, shell = False, cwd = None, env = None, universal_newlines = False , startupinfo = None, creationflags = 0, restore_signals = True, start_new_session = False, pass_fds = ())

параметры

параметр подробности
args Один исполняемый файл или последовательность исполняемых файлов и аргументов - 'ls' , ['ls', '-la']
shell Выполнить под оболочкой? По умолчанию оболочка для /bin/sh в POSIX.
cwd Рабочий каталог дочернего процесса.

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

Простейшим вариантом использования является использование функции 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']


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow