【Python】Python中调用Linux命令并获取其返回值
其返回值是shell指令运行后返回的状态码,int类型,0表示shell指令成功执行,256/512表示未找到,该方法适用于shell命令不需要输出内容的场景。会启动子进程,在子进程中执行cmd,如果cmd有执行内容,会在标准输出显示。举例说明:列举当前目录下的所有文件。
1. 方法一:使用os模块的system方法
os.system(cmd)
,其返回值是shell指令运行后返回的状态码,int类型,0表示shell指令成功执行,256/512表示未找到,该方法适用于shell命令不需要输出内容的场景。
os.system(cmd)
会启动子进程,在子进程中执行cmd,如果cmd有执行内容,会在标准输出显示。
举例说明:
列举当前目录下的所有文件。
import os
val = os.system('ls -al')
print val #输出为0
val = os.system('ls -al non_exist_folder')
print val #输出为512
val = os.system('ls -al|grep non_exist_val')
print val #输出为256
2. 方法二:使用os.popen()
该方法以文件的形式返回shell指令运行后的结果,需要获取内容时可使用read()
或readlines()
方法。
os.system(cmd)
或os.popen(cmd)
,前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。实际使用时视需求情况而选择。
举例:
import os
os.popen('ls -l')
# 输出:<open file 'ls -l', mode 'r' at 0x7f46af044930>
os.popen('ls -l').read() #返回字符串类型的结果
#输出:'total 0\n-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 a.txt\n-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 b.txt\n'
os.popen('ls -l').readlines() #返回一个list类型的结果
# 输出:['total 0\n', '-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 a.txt\n', '-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 b.txt\n']
val=os.popen('ls -al')
for i in val.readlines():
print i
3. 方法三:使用commands模块,有三个方法可以使用
(1)commands.getstatusoutput(cmd)
其以元组(status,output)的形式返回命令执行后的返回状态和执行结果。其中,对cmd的执行实际上是按照{cmd;} 2>&1的方式,所以output中包含控制台输出信息或者错误信息,output中不包含尾部的换行符。
(2)commands.getoutput(cmd)
返回cmd的输出结果。
(3)commands.getstatus(file)
返回ls -l file的执行结果字符串,调用了getoutput,不建议使用此方法
import commands
aa=commands.getstatusoutput('ls -l')
# 输出:(0, 'total 0\n-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 a.txt\n-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 b.txt')
# 返回一个元组,对比os.popen(cmd)的返回结果,发现output中不包含尾部的换行符
bb=commands.getoutput('ls -l') #只返回执行结果
# 输出:'total 0\n-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 a.txt\n-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 b.txt'
cc=commands.getstatus('a.txt') #查询某个文件的状态
# 输出:'-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 a.txt'
dd=commands.getstatusoutput('ls -l non_exist_folder') #执行结果中包含控制台输出信息或者错误信息
# 输出:(512, "ls: cannot access 'non_exist_folder': No such file or directory")
4. 方法三:subprocess模块,
允许创建很多子进程,创建的时候能指定子进程和子进程的输入、输出、错误输出管道,执行后能获取输出结果和执行状态。
(1)subprocess.run():
python3.5中新增的函数, 执行指定的命令, 等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。
(2)subprocess.call():
执行指定的命令, 返回命令执行状态, 功能类似os.system(cmd)。
(3)subprocess.check_call():
python2.5中新增的函数, 执行指定的命令, 如果执行成功则返回状态码, 否则抛出异常。
说明:
subprocess.run(args, *, stdin=None, input=None, stdout=None,stderr=None, shell=False, timeout=None, check=False,universal_newlines=False)
subprocess.call(args, *, stdin=None, stdout=None, stderr=None,shell=False, timeout=None)
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None,shell=False, timeout=None)
args:表示shell指令,若以字符串形式给出shell指令,如"ls -l “则需要使shell = Ture。否则默认以数组形式表示shell变量,如"ls”,“-l”。
当使用比较复杂的shell语句时,可以先使用shlex模块的shlex.split()方法来帮助格式化命令,然后在传递给run()方法或Popen。
subprocess.run()、subprocess.call()、subprocess.check_call()、subprocess.check_output()
都是通过对subprocess.Popen的封装来实现的高级函数,因此如果我们需要更复杂功能时,可以通过subprocess.Popen来完成
使用举栗:
import shlex
import subprocess
command='ls -l'
args=shlex.split('ls -l')
bb=subprocess.Popen(args) #bb是一个Popen的对象,该对象不能通过read()或readlines()来读取
输出:total 0
-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 a.txt
-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 b.txt #在该处需要点击换行符才会结束
aa=subprocess.call('ls -l',shell=True) #其返回值为shell命令的执行返回码
输出:total 0
-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 a.txt
-rw-rw-r-- 1 roaddb roaddb 0 Dec 11 10:09 b.txt #直接返回
5. 示例
在Python3中的情况
期望:想要在Python3中执行curl命令并返回执行结果,返回结果时json体
分析:
cmd='curl -s "http://127.0.0.1:8080/xxxxx"'
1)使用os.system(cmd)
无法获取输出内容
2)使用os.popen(cmd).read()
可以获取到返回的json体${aa}
,通过json.loads(${aa})
可以将json体转为字典样式
3)commands模块在Python3.0中被废弃了
4)subprocess.getstatusoutput(cmd)
输出结果类似于python2中的commands.getstatusoutput(cmd)
,返回一个元组,元组的第2个值是执行结果${aa}
,通过json.loads(${aa})
可以将json体转为字典样式。
更多推荐
所有评论(0)