问题

也许大家在日常工作中遇到过要用 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 -
©著作权归作者所有:来自51CTO博客作者mb5fe18fed96438的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 如何使用Python执行系统命令?Python学习教程!
  2. 使用Eclipse实现自定义Jmeter函数助手
  3. Cocos平台 | 快速集成AGC云函数服务
  4. 正确使用异步函数的姿势[每日前端夜话(0x06)]
  5. Numpy中Meshgrid函数介绍及2种应用场景
  6. Python中匿名函数与内置高阶函数详解
  7. 面试必知必会|理解C++虚函数
  8. 类和函数傻傻分不清楚?三个例子讲明白
  9. 上班摸鱼系列|Python开发命令行斗地主

随机推荐

  1. android(6) 扇形菜单实现
  2. fragment保存页面不销毁
  3. 基于第三方开发Android锁屏
  4. 错误”. lang。当使用带有ViewPager的选
  5. Android输入法框的梳理
  6. 做自己的Android ROM,屏蔽对framework中的
  7. 检查ArrayList是否只包含null值的方法。
  8. cocos2d-x避免手动修改android.mk文件来
  9. android 模拟键盘鼠标事件(adb shell)
  10. [Unity3D]调用Android接口