Как выполнить команду Bash в сценарии Python

Ответы:

16

ответ @ милна работает, но subprocess.call() дает мало отзывов.

Я предпочитаю использовать, subprocess.check_output()чтобы вы могли проанализировать, что было напечатано на стандартный вывод:

 import subprocess
 res = subprocess.check_output(["sudo", "apt", "update"])
 for line in res.splitlines():
     # process the output line by line

check_output выдает ошибку при нулевом выходе вызванной команды

Обратите внимание, что это не вызывает bashили другую оболочку, если вы не указали shellаргумент ключевого слова для функции (то же самое верно для subprocess.call(), и вы не должны, если не нужно, так как это создает угрозу безопасности), это напрямую вызывает команда.

Если вы обнаружите, что выполняете много (разных) вызовов команд из Python, возможно, вы захотите взглянуть на plumbum . С этим вы можете сделать (ИМО) более читабельным:

from plumbum.cmd import sudo, apt, echo, cut

res = sudo[apt["update"]]()
chain = echo["hello"] | cut["-c", "2-"]
chain()
Энтон
источник
Это рекомендуется использовать ( os.popenили os.system), напр: res = os.popen('sudo apt update').read()? @Anthon
Alper
1
@alper Читайте 0324 python.org/dev/peps/pep-0324 . Это объясняет обоснование для создания, subprocessхотя os.systemи os.popenуже существовало. Такие PEP нетривиальны, чтобы быть принятыми. Несколько человек думали об этом гораздо больше, чем вы или я. И subprocessулучшилось с 2003 года, остальные просто еще для обратной совместимости. Перед вами os.systemстраница справочника: модуль подпроцесса предоставляет более мощные средства для запуска новых процессов и получения их результатов; использование этого модуля предпочтительнее, чем использование этой функции.
Anthon
1
@alper Да, ты мог бы. Как я уже говорил, это потенциальная угроза безопасности, поэтому я не знаю, почему вы считаете, что это рекомендуется. И призыв sudoтолько сделает это более серьезным. Возможно, использование python-apt - лучшее решение (я сам не рассматривал это).
Антон
1
@alper в этом случае серьезно посмотрите на свинец , с этим стоит поторопиться .
Антон
1
@alper Если вы находитесь на Python3, вам нужно это сделать, на Python2 - нет. Пожалуйста, не используйте комментарии здесь как систему чата. Если у вас есть вопрос, отправьте его как таковой.
Anthon
8

Возможно, вы используете bash в качестве программы с параметром -c для выполнения команд:

Пример:

bashCommand = "sudo apt update"
output = subprocess.check_output(['bash','-c', bashCommand])
бритва
источник
7

Модуль подпроцесса предназначен для этого:

import subprocess
subprocess.call(["sudo", "apt", "update"])

Если вы хотите, чтобы скрипт завершился в случае сбоя команды, вы можете рассмотреть возможность использования check_call()вместо синтаксического анализа кода возврата самостоятельно:

subprocess.check_call(["sudo", "apt", "update"])
Милинд Думбаре
источник
это дало мне следующую трассировку: Traceback (most recent call last): File "/home/Dremor/test.py", line 3, in <module> subprocess.call('sudo', 'yum', 'update') File "/usr/lib64/python3.4/subprocess.py", line 537, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib64/python3.4/subprocess.py", line 767, in __init__ raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer (я использую yum, поскольку я использую Fedora в качестве основной ОС)
Dremor
3
Вы забыли квадратные скобки
Милинд Думбаре
1
Также обратите внимание, что subprocess.call()блокирует, а subprocess.Popen()не блокирует ..
Heemayl
Что вы подразумеваете под "блокировкой"? @heemayl
Alper
2

Также вы можете использовать «os.popen».

Пример:

import os

command = os.popen('ls -al')
print(command.read())
print(command.close())

Выход:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None
ricardo130
источник
0

использовать модуль подпроцесса

import subprocess
command = 'sudo apt update'
subprocess.check_call(command.split())
Фред
источник
почему я получаю сообщение об ошибке
aquagremlin
subprocess.check_call (["sudo", "apt", "update"])
aquagremlin
CalledProcessError Traceback (последний вызов был последним) <ipython-input-21-33ce645708e7> в <module> () ----> 1 subprocess.check_call (["sudo", "apt", "update"]) / usr / lib / python2.7 / subprocess.pyc в check_call (* popenargs, ** kwargs) 188, если cmd отсутствует: 189 cmd = popenargs [0] -> 190 повысить CalledProcessError (retcode, cmd) 191 вернуть 0 192 CalledProcessError: Command '[' sudo ',' apt ',' update ']' вернули ненулевой статус выхода 1
aquagremlin
эта ошибка возникает только тогда, когда я запускаю ее в блокноте
jupyter
возможно я начну новый вопрос, так как это
Aquagremlin