python 执行外部命令的几种方式

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.systemos.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中被废弃

你可能感兴趣的:(python 执行外部命令的几种方式)