як виконати команду bash в сценарії python


Відповіді:


17

Відповідь @ milne працює, але subprocess.call()дає мало відгуків.

Я вважаю за краще використовувати, subprocess.check_output()щоб ви могли проаналізувати, що було надруковано на stdout:

 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, ви можете подивитися на плумбум . З цим ви можете зробити (IMO) більш читабельним:

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сторінка керівництва: модуль підпроцесу забезпечує більш потужні засоби для нерестування нових процесів та отримання їх результатів; використання цього модуля переважно, ніж використання цієї функції.
Антон

1
@alper Так, ти міг. Як я зазначив, це потенційна небезпека для безпеки, тому я не знаю, чому ви вважаєте, що це рекомендується. І sudoпокликання лише зробить це більш суворим. Можливо, використання python-apt є кращим рішенням (я сам цього не вивчав).
Антон

1
@alper у такому випадку серйозно погляньте на плюмбум , варто швидше досягти цього.
Антон

1
@alper Якщо ви перебуваєте на Python3, вам потрібно це зробити, на Python2 ви цього не зробите. Будь ласка, не використовуйте тут коментарі як систему чату. Якщо у вас є питання, поставте його як таке.
Антон

8

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

Приклад:

bashCommand = "sudo apt update"
output = subprocess.check_output(['bash','-c', bashCommand])

7

The підпроцесу призначений для цього:

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
Ви забули квадратні дужки
Milind Dumbare

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

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

ця помилка трапляється лише тоді, коли я запускаю її в зошиті з юпітером
aquagremlin

можливо, я почну нове запитання, оскільки це ot
aquagremlin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.