社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Stack Overflow 热帖:如何用 Python 调用外部命令

Python开发者 • 5 年前 • 712 次点击  

(给Python开发者加星标,提升Python技能

问题


也许大家在日常工作中遇到过要用 Python 脚本执行外部命令的情况,并且你还不知道怎么调用。


没关系,早在 12 年前就有程序员在 Stack Overflow 上求助提问啦。



本文为大家总结整理其中一些高赞回答,以备不时之需!


解决方法


方法1:我们可以使用 subprocess ,比如要执行 ls -l 命令

import subprocess subprocess.run(["ls", "-l"])

Python3.5 之前的版本,需要使用 call

import subprocess subprocess.call(["ls", "-l"])

方法2:

import os os.system("ls -l") #执行命令os.popen("ls -l").read() #执行并输出命令的执行结果

方法讨论:


问题解决了,那么os.system 和 subprocess 那个解决方法更好一点呢?这里做简单讨论,虽然os.system 和 subprocess 都能完成调用外部命令的功能,但是subprocess 比 system 更灵活(subprocess 我们可以得到 stdout,stderr 以及更好的错误处理等等)。并且官方文档也是更建议 subprocess 模块。


下面是对各种调用外部程序的方法的小总结:


1、os.system("some_command with args"):将命令和参数传给系统shell,这个方法可以一次执行多条命令,并且可以建立管道重定向例如:

os.system("some_command < input_file | another_command > output_file")

尽管这种方式很简便,但是你不得不手工处理一些特殊字符例如空格等。


2、stream=os.popen("some_command with args"):实现的功能和os.system是一样的,但是os.popen会返回一个类文件对象,让你看到命令的执行结果。

stream=os.popen("ls -l")stream.read() #输出ls -l 的结果

3、subprocess的Popen类,建议尽量使用它来代替os.popen,但是使用的时候参数会相对复杂,例如

print(subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read())

而不建议使用

print(os.popen("echo Hello World").read())

4、subprocess模块中的call函数,功能和Popen类相似,并且使用相同的参数,但是它仅仅在命令执行完毕后,返回一个代码,例如

return_code = subprocess.call("echo Hello World", shell=True)0 #执行成功

5、如果使用的是Python3.5及以上版本,可以使用subprocess.run函数,它跟上面介绍的函数基本一样,但是更灵活,会在命令行执行结束后返回一个CompletedProcess对象。

return_code = subprocess.run("echo Hello World", shell=True)


    
return_codeCompletedProcess(args='echo Hello World', returncode=0) #CompletedProcess对象type(return_code)

6、虽然os模块包括fork/exec/spawn等函数,但是并不建议直接使用它们,使用不当可能会导致意外结果。


因此如果有需要执行外部命令的需要,建议使用subprocess,而非os模块。


最后,特别要注意如果你要执行的命令是以字符串的形式作为参数,那么必须小心谨慎,否则会造成严重的后果!比如下面的例子

print(subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read())

看到这段代码能想到什么可怕的事情吗?如果有人给 user_input 传递的是 "my mama didnt love me && rm -rf /",是不是头皮发麻! 所以谨慎再谨慎!!尽量不做交互式输入,而是在程序中,将要执行的命令,写“死”在字符串中,做为常量传递。


拓展思路


下面还整理了一些其它的方法,有兴趣的同学可再深入研究。


sh


sh程序是subprocess的接口,让你像调用函数一样的调用想执行的程序。如果要多次运行一个命令,这很有用。

sh.ls("-l") ls_cmd = sh.Command("ls")

plumbum


plumbum功能和sh类似。

ls_cmd = plumbum.local("ls -l") ls_cmd()

fabric


fabric 是py2.5和2.7的库。可以让你执行本地或远程shell命令。

fabric.operations.local('ls -l')fabric.operations.local('ls -l', capture = True)

envoy


envoy 以“subprocess for humans”闻名,它是对subprocess模块的封装,简单易用

r = envoy.run("ls -l"r.std_out


参考链接:

https://stackoverflow.com/questions/89228/how-to-call-an-external-command


关于调用外部命令,你们是在用哪种方法呢?欢迎在评论中和我探讨。觉得文章不错,请点赞和在看支持我继续分享好文。谢谢!



- EOF -

推荐阅读  点击标题可跳转

1、如何返回一个 List 中某元素的索引?

2、原来 collections 这么好用!!

3、GitHub 标星 7.4k!Python 魔法库之 FuzzyWuzzy


觉得本文对你有帮助?请分享给更多人

关注「Python开发者」加星标,提升Python技能

点赞和在看就是最大的支持❤️

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/74845