subprocess.run(["ls", "-l"]) # Run command
subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command
pexpect.run("ls -l") # Run command as normal
child = pexpect.spawn('scp foo user@example.com:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword')
import subprocess
p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
print line,
retval = p.wait()
11条答案
按热度按时间oalqel3c1#
下面总结了调用外部程序的方法以及每种方法的优缺点:
os.system("some_command with args")
将命令和参数传递给系统的shell。这很好,因为您实际上可以以这种方式一次运行多个命令,并设置管道和输入/输出重定向。例如:不过,虽然这很方便,但您必须手动处理shell字符(如空格等)的转义。另一方面,这也允许您运行简单的shell命令,而不是实际的外部程序。请参阅文档。
stream = os.popen("some_command with args")
会做同样的事情os.system
只是它提供了一个类似文件的对象,您可以使用它访问该进程的标准输入/输出。popen还有另外3种变体,它们处理i/o的方式都略有不同。如果您将所有内容作为字符串传递,那么您的命令将传递给shell;如果你把它们作为一个列表来传递,那么你就不必担心会漏掉任何东西。请参阅文档。这个
Popen
类subprocess
模块。这是为了取代os.popen
但缺点是,由于如此全面,情况稍微复杂一些。例如,你会说:而不是:
但是将所有的选项放在一个统一的类中而不是4个不同的popen函数中是很好的。请参阅文档。
这个
call
从subprocess
模块。这基本上就像Popen
类并接受所有相同的参数,但它只是等待命令完成并给出返回代码。例如:请参阅文档。
如果您使用的是python3.5或更高版本,那么可以使用新的
subprocess.run
函数,它与上面的函数非常相似,但更加灵活,并返回CompletedProcess
对象。os模块还具有c程序中的所有fork/exec/spawn函数,但我不建议直接使用它们。
这个
subprocess
模块应该是您所使用的。最后,请注意,对于所有方法,您传递的最终命令将由shell作为字符串执行,并且您负责转义它。如果您传递的字符串的任何部分都不能被完全信任,则会产生严重的安全隐患。例如,如果用户正在输入字符串的某些/任何部分。如果不确定,请仅对常量使用这些方法。要给您一个暗示,请考虑以下代码:
想象一下,用户输入了“我妈妈不爱我&&rm-rf/”这样就可以删除整个文件系统。
8fq7wneg2#
有许多不同的库允许您使用python调用外部命令。对于每个库,我都给出了一个描述,并展示了一个调用外部命令的示例。我用的命令是
ls -l
(列出所有文件)。如果您想了解更多关于我列出的任何库的信息,并链接每个库的文档。资料来源:
子流程:https://docs.python.org/3.5/library/subprocess.html
shlex公司:https://docs.python.org/3/library/shlex.html
操作系统:https://docs.python.org/3.5/library/os.html
上海:https://amoffat.github.io/sh/
铅:https://plumbum.readthedocs.io/en/latest/
期望值:https://pexpect.readthedocs.io/en/stable/
面料:http://www.fabfile.org/
特使:https://github.com/kennethreitz/envoy
命令:https://docs.python.org/2/library/commands.html
以下是所有库:
希望这能帮助您决定使用哪个库:)
子流程
子进程允许您调用外部命令并将它们连接到它们的输入/输出/错误管道(stdin、stdout和stderr)。子进程是运行命令的默认选择,但有时其他模块更好。
操作系统
操作系统用于“操作系统相关功能”。它也可以用来调用外部命令
os.system
以及os.popen
(注意:还有一个子流程popen)。操作系统将始终运行shell,对于不需要或不知道如何使用的人来说,它是一个简单的选择subprocess.run
.嘘
sh是一个子进程接口,它允许您像调用函数一样调用程序。如果要多次运行命令,这很有用。
铅
plumbum是一个用于“脚本式”python程序的库。您可以调用函数之类的程序,如中所示
sh
. 如果你想在没有外壳的情况下运行管道,铅是很有用的。预期
pexpect允许您生成子应用程序,控制它们并在它们的输出中找到模式。对于在unix上需要tty的命令,这是一个更好的替代子进程的方法。
织物
fabric是一个python2.5和2.7库。它允许您执行本地和远程shell命令。fabric是在安全shell(ssh)中运行命令的简单替代方法
特使
特使被称为“人类的子进程”。它是用来作为一个方便的 Package 周围
subprocess
模块。命令
commands
包含的 Package 函数os.popen
,但它已从python3中删除subprocess
是更好的选择。编辑是基于j.f.塞巴斯蒂安的评论。
vwhgwdsa3#
注意,这是危险的,因为命令没有被清除。我把‘os’和‘sys’模块的相关文档交给google。有一系列函数(exec和spawn)将执行类似的操作。
f8rj6qna4#
我建议使用subprocess模块而不是os.system,因为它可以为您进行shell转义,因此更安全。
1mrurvl15#
也可以查看“pexpect”python库。
它允许交互控制外部程序/命令,甚至ssh、ftp、telnet等。您可以键入以下内容:
des4xlb06#
如果要返回命令的结果,可以使用
os.popen
. 但是,由于版本2.6支持子流程模块,这一点已被弃用,其他答案已经很好地涵盖了子流程模块。46qrfjad7#
关于从调用进程分离子进程(在后台启动子进程)的一些提示。
假设您想从一个cgi脚本开始一个长任务。也就是说,子进程的寿命应该比cgi脚本执行进程长。
子流程模块文档中的经典示例是:
这里的想法是,您不希望在longtask.py完成之前在“callsubprocess”行中等待。但不清楚在示例中的“这里有更多代码”一行之后会发生什么。
我的目标平台是freebsd,但是开发是在windows上进行的,所以我首先在windows上面对这个问题。
在windows上(windows 在longtask.py完成其工作之前,父进程不会完成。这不是你想要的cgi脚本。这个问题不是python特有的;在php社区中,问题是相同的。
解决方案是将分离的进程创建标志传递给windowsapi中的底层createprocess函数。如果碰巧安装了pywin32,可以从win32process模块导入标志,否则应该自己定义:
/upd 2015.10.27@eryksun在下面的评论中指出,语义正确的标志是create\u new\u console(0x00000010)/
在freebsd上,我们还有另一个问题:当父进程完成时,它也会完成子进程。这也不是你想要的cgi脚本。一些实验表明,问题似乎出在共享sys.stdout上。工作方案如下:
我没有检查其他平台上的代码,也不知道freebsd上出现这种行为的原因。如果有人知道,请分享你的想法。在python中google启动后台进程还不能说明什么。
sxpgvts38#
查看标准库中的子流程模块:
优势
subprocess
与。system
是因为它更灵活(你可以得到stdout
,stderr
,真正的状态码,更好的错误处理等等。官方文件建议
subprocess
替代方案模块os.system()
:这个
subprocess
模块提供了更强大的工具来产生新的进程和检索它们的结果;使用该模块比使用此函数更好[os.system()
].中的“用子流程模块替换旧函数”部分
subprocess
文档可能有一些有用的方法。对于3.5之前的python版本,请使用
call
:3htmauhk9#
典型实施:
你可以随心所欲地使用
stdout
管道中的数据。实际上,您可以忽略这些参数(stdout=
以及stderr=
)它会表现得像os.system()
.am46iovg10#
使用标准库
使用子流程模块(python 3):
这是推荐的标准方式。但是,更复杂的任务(管道、输出、输入等)在构造和编写时可能会非常繁琐。
关于python版本的注意事项:如果您仍在使用python2,subprocess.call的工作方式类似。
protip:shlex.split可以帮助您解析
run
,call
,和其他subprocess
如果你不想要(或者你不能!)以列表形式提供:具有外部依赖关系
如果您不介意外部依赖关系,请使用plumbum:
这是最好的
subprocess
Package 器。它是跨平台的,也就是说,它可以在windows和类unix系统上工作。安装方式pip install plumbum
.另一个流行的图书馆是sh:
然而,
sh
放弃了对windows的支持,所以它不像以前那么棒了。安装方式pip install sh
.xmjla07d11#
我总是用
fabric
例如:但这似乎是一个很好的工具:
sh
(python子进程接口)。看一个例子: