Python Language
Библиотека подпроцессов
Поиск…
Синтаксис
- 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']