如何在python脚本中执行bash命令


Answers:


16

@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为函数指定关键字参数,则不会调用此方法或其他Shell (对于subprocess.call(),也是如此),如果没有必要,则不要这样做,因为它会带来安全隐患),它将直接调用命令。

如果您发现自己从Python进行了大量(不同的)命令调用,则可能需要研究一下plumbum。这样,您就可以使(IMO)更具可读性:

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

res = sudo[apt["update"]]()
chain = echo["hello"] | cut["-c", "2-"]
chain()

建议使用(os.popenos.system),例如:res = os.popen('sudo apt update').read()吗?@Anthon
alper

1
@alper阅读0324 python.org/dev/peps/pep-0324。这解释了制作的基本原理subprocess虽然os.systemos.popen已经存在。这样的PEP并非不容易被接受。有几个人对此的想法比您或我想的要多得多。并且subprocess自2003年以来有所改进,其他版本仍在向后兼容。您是否在os.system手册页上加了红色:子流程模块提供了更强大的功能,用于生成新流程并检索其结果;使用该模块优于使用此功能。
Anthon '18年

1
@alper是的,您可以。正如我指出的那样,这是潜在的安全隐患,所以我不知道您为什么建议这样做。调用sudo只会使情况变得更加严峻。也许使用python-apt是更好的解决方案(我自己还没有研究过)。
Anthon '18年

1
在这种情况下,@ alper认真看一下,值得一提。
安东

1
@alper如果您使用的是Python3,则不需要这样做,而在Python2上则不需要。请不要在此处将评论用作聊天系统。如果您有任何疑问,请直接发布。
Anthon '18

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
您忘了方括号
Milind Dumbare 2015年

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 '19

subprocess.check_call([“ sudo”,“ apt”,“ update”])
aquagremlin

在<module>()----> 1 subprocess.check_call([[sudo],“ apt”,“ update”])中的CalledProcessError Traceback(最近一次呼叫最近)<ipython-input-21-33ce645708e7>检查/调用中的lib / python2.7 / subprocess.pyc(* popenargs,** kwargs)188如果cmd为None:189 cmd = popenargs [0]-> 190升高CalledProcessError(retcode,cmd)191返回0192 CalledProcessError:Command '['sudo','apt','update']'返回非零退出状态1
aquagremlin

仅当我在Jupyter笔记本中运行该错误时才会发生
aquagremlin '19

也许我会开始一个新的问题,因为这是其他时间
aquagremlin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.