Модуль Python Subprocess
Subprocess — это встроенный модуль, который позволяет нам запускать новые системные процессы, подключаться к их потокам ввода/вывода/ошибок и получать их коды возврата.
import subprocess
Запуск системной команды
Функция run используется для выполнения системной команды.
subprocess.run(['echo', 'Hello World!'])
Hello World!
Если вы хотите выполнить команду как одну строку, а не как список, используйте:
subprocess.run('echo Hello World!', shell=True)
Hello World!
Обе команды автоматически выведут результат в терминал.
ПРЕДУПРЕЖДЕНИЕ
Избегайте использования `shell=True` с недоверенным вводом (риск внедрения команд оболочки).
Захват вывода
Чтобы захватить вывод, установите capture_output в True:
result = subprocess.run(
['echo', 'Hello World!'],
capture_output=True,
text=True
)
output = result.stdout
error = result.stderr
returncode = result.returncode
output = "Hello World!\n"
error = ""
returncode = 0
Здесь text=True указывает функции считывать вывод как текст, а не как байты.
Код возврата returncode 0 указывает на успех; любое ненулевое значение указывает на ошибку.
Проверка ошибок
Хотя мы можем проверить успех, используя код возврата, существует более питонический способ сделать это:
try:
result = subprocess.run(
['ls', 'my_dir'],
check=True,
)
print('Finished without errors.')
except subprocess.CalledProcessError:
print('Error: Directory does not exist.')
Error: Directory does not exist.
Если check установлено в True, а код возврата не равен 0 (неуспешная операция), subprocess вызовет исключение subprocess.CalledProcessError, которое можно обработать обычным способом с помощью блока except.
Запуск команд с таймаутом
Вы можете установить таймаут для процесса. Если он займет больше указанного времени, будет вызвано исключение subprocess.TimeoutExpired:
try:
subprocess.run(['sleep', '10'], timeout=5)
except subprocess.TimeoutExpired:
print('Process took too long!')
Process took too long!
Запись вывода в файл
Вы можете перенаправить вывод в файл, установив stdout (и stderr, если необходимо) в файловый объект:
with open('output.txt', 'w') as f:
subprocess.run(['ls', '-l'], stdout=f, stderr=f)
Здесь как обычный вывод, так и ошибки появятся в файле в том порядке, в котором они генерируются.
Примечание: text=True полезен, когда вы хотите обрабатывать вывод как строку в Python. Он не является строго необходимым при прямом перенаправлении вывода в файл.