在python程序中调用shell命令
1. os.system(command)
此函数会启动子进程,在子进程中执行command,并返回command命令执行完毕后的退出状态,如果command有执行内容,会在标准输出显示。这实际上是使用C标准库函数system()实现的。
缺点:这个函数在执行command命令时需要重新打开一个终端,并且无法保存command命令的执行结果。
system方法会创建子进程运行外部程序,方法只返回外部程序的运行结果。这个方法比较适用于外部程序没有输出结果的情况。
import os
os.system("echo \"Hello World\"") # 直接使用os.system调用一个echo命令
Hello World ——————> 打印命令结果
0 ——————> What's this ? 返回值?
>>> val = os.system("ls -al | grep \"log\" ") # 使用val接收返回值
-rw-r--r-- 1 root root 6030829 Dec 31 15:14 log ——————> 此时只打印了命令结果
>>> print val
0 ——————> 注意,此时命令正常运行时,返回值是0
>>> val = os.system("ls -al | grep \"log1\" ")
>>> print val
256 ——————> 使用os.system调用一个没有返回结果的命令,返回值为256~
实例:os.system(‘ls -l *’)
2. os.popen(command,mode)
打开一个与command进程之间的管道。这个函数的返回值是一个文件对象,可以读或者写(由mode决定,mode默认是’r’)。如果mode为’r’,可以使用此函数的返回值调用read()来获取command命令的执行结果。
os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。实际使用时视需求情况而选择。
- 当需要得到外部程序的输出结果时,本方法非常有用,返回一个类文件对象,调用该对象的read()或readlines()方法可以读取输出内容。比如使用urllib调用Web API时,需要对得到的数据进行处理。os.popen(cmd) 要得到命令的输出内容,只需再调用下read()或readlines()等 如a=os.popen(cmd).read()
>>> os.popen('ls -lt') # 调用os.popen(cmd)并不能得到我们想要的结果
<open file 'ls -lt ', mode 'r' at 0xb7585ee8>
>>> print os.popen('ls -lt').read() # 调用read()方法可以得到命令的结果
total 6064
-rwxr-xr-x 1 long long 23 Jan 5 21:00 hello.sh
-rw-r--r-- 1 long long 147 Jan 5 20:26 Makefile
drwxr-xr-x 3 long long 4096 Jan 2 19:37 test
-rw-r--r-- 1 root root 6030829 Dec 31 15:14 log
drwxr-xr-x 2 long long 4096 Dec 28 09:36 pip_build_long
drwx------ 2 Debian-gdm Debian-gdm 4096 Dec 23 19:08 pulse-gylJ5EL24GU9
drwx------ 2 long long 4096 Jan 1 1970 orbit-long
>>> val = os.popen('ls -lt').read() # 使用变量可以接收命令返回值
>>> if "log" in val: # 我们可以使用in来判断返回值中有木有一个字符串
... print "Haha,there is the log"
... else:
... print "No,not happy"
...
Haha,there is the log
实例:tmp = os.popen(‘ls -l *’).readlines()
3. commands.getstatusoutput(command)
使用os.popen()函数执行command命令并返回一个元组(status,output),分别表示command命令执行的返回状态和执行结果。对command的执行实际上是按照{command;} 2>&1的方式,所以output中包含控制台输出信息或者错误信息。output中不包含尾部的换行符。
使用commands模块的getoutput方法,这种方法同popend的区别在于popen返回的是一个类文件对象,而本方法将外部程序的输出结果当作字符串返回,很多情况下用起来要更方便些。
4. subprocess模块
根据Python官方文档说明,subprocess模块用于取代上面这些模块。有一个用Python实现的并行ssh工具—mssh,代码很简短,不过很有意思,它在线程中调用subprocess启动子进程来干活。
args="ls -l"
p=subprocess.Popen(args,shell=True)
subprocess与system相比的优势是它更灵活(你可以得到标准输出,标准错误,“真正”的状态代码,更好的错误处理,等…)。其中的call()完全替代了system(),而popen()被更为丰富的Popen类替代;
总结:推荐使用subprocess.run() 来解决一般问题。
subprocess.run()、subprocess.call()、subprocess.check_call()、subprocess.check_output()都是通过对subprocess.Popen的封装来实现的高级函数,因此如果我们需要更复杂功能时,可以通过subprocess.Popen来完成。run默认不会返回输出,只返回命令和执行状态。
Python之系统交互(subprocess)
举例讲解Linux系统下Python调用系统Shell的方法