python 执行外部命令的几种方式
2020-08-21 本文已影响0人
望月成三人
os.system
- 执行的时候程序会打出cmd在linux上执行的信息
- 执行命令成功返回为0,否则为1
- 如果想获取在cmd输出的内容,是没办法获到的
t2 = os.system("1adb devices")
t3 = os.system("adb devices")
print(t2) # 打印为1
print(t3) # 打印为0
subprocess.call
- 取代
os.system
,但是也是无法获取cmd输出的内容
import subprocess
t = subprocess.call('adb devices')
print(t) # 打印为0
os.popen
- popen返回的是一个file对象,跟open打开文件一样操作了,r是以读的方式打开
output = os.popen('adb devices')
print(output.read()) # 得到List of devices attached
subprocess.Popen
-
subprocess
模块代替os.system
、os.popen
,能够得到命令输出的值
shell
参数
- 在
linux
下,当shell=False
(默认)时,Popen
使用os.execvp()
来执行子程序。args
一般要是一个【列表】。如果args
是个字符串的
话,会被当做是可执行文件的路径,这样就不能传入任何参数了。
subprocess.Popen("cat test.txt", shell=True)
这是因为它相当于
subprocess.Popen(["/bin/sh", "-c", "cat test.txt"])
stdin
stdout
stderr
参数
- 分别表示程序的标准输入、输出、错误句柄。他们可以是
PIPE
,文件描述符或文件对象,也可以设置为None
表示从父进程继承 - 执行结果使用管道输出的实例:
pipe=subprocess.Popen("adb devices",shell=True,stdout=subprocess.PIPE).stdout
print(pipe.read()) # 得到值b'List of devices attached\r\n\r\n'
- 执行结果保存在文件实例
cmd = "adb shell ls /sdcard/ | findstr aa.png"
fhandle = open(r"e:\aa.txt", "w")
pipe = subprocess.Popen(cmd, shell=True, stdout=fhandle).stdout
fhandle.close()
- 子进程的文本流控制
#!/usr/bin/env python
import subprocess
child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE)
out = child2.communicate()
print out
- child1.stdout-->subprocess.PIPE
- child2.stdin<--subprocess.PIPE
- child2.stdout-->subprocess.PIPE
- 相当于将child1.stdout-->child2.stdin->child2.stdout->subprocess.PIPE
- subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到
communicate()
方法从PIPE中读取出PIPE中的文本。 - 要注意的是,
communicate()
是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。 - 我们还可以利用communicate()方法来使用PIPE给子进程输入:
import subprocess
child = subprocess.Popen(["cat"], stdin=subprocess.PIPE)
child.communicate("vamei") //()不为空,则写入subprocess.PIPE,为空,则从subprocess.PIPE读取
- subprocess.PIPE-->child.stdin
- commiuncate相当于写入subprocess.PIPE,然后child从subprocess.PIPE读取
- 利用python的subprocess模块执行外部命令, 并捕获stdout, stderr的输出
import subprocess
# print ’popen3:’
def external_cmd(cmd, msg_in=''):
try:
proc = subprocess.Popen(cmd,
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
stdout_value, stderr_value = proc.communicate(msg_in)
return stdout_value, stderr_value
except ValueError as err:
# log("ValueError: %s" % err)
return None, None
except IOError as err:
# log("IOError: %s" % err)
return None, None
if __name__ == '__main__':
stdout_val, stderr_val = external_cmd('dir')
print ('Standard Output: %s' % stdout_val)
print ('Standard Error: %s' % stderr_val)
- 得到命令的返回值,wait
p=subprocess.Popen("dir", shell=True)
p.wait()
- 但是Popen函数有一个缺陷,就是它是一个阻塞的方法。如果运行cmd时产生的内容非常多,函数非常容易阻塞住。解决办法是不使用wait()方法,但是也不能获得执行的返回值了。
commands.getstatusoutput
- 不介意使用,因为在python3中被废弃