python使用subprocess执行命令

介绍

subprocess模块用来创建新的进程,连接到其stdin、stdout、stderr管道并获取它们的返回码。

subprocess模块的出现是为了替代如下旧模块及函数:os.system、os.spawn*、os.popen*、popen2.*、commands.*。

强烈建议POSIX用户(Linux、BSD等)安装并使用较新的subprocess32模块,而不是Python 2.7自带的subprocess。

快捷函数

推荐用户使用run(新),call、check_call和check_output这三个快捷函数,在无法满足需求的时候才使用更高级的Popen函数。

call、check_call和check_output其实都是调用的Popen函数

run

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, encoding=None, errors=None)

功能:执行args参数所表示的命令,等待命令结束,并返回一个CompletedProcess类型对象。

下面是run参数的作用:

  • args:表示要执行的命令。必须是一个字符串,字符串参数列表。

  • stdin、stdout和stderr:子进程的标准输入、输出和错误。其值可以是subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者None。subprocess.PIPE表示为子进程创建新的管道。subprocess.DEVNULL表示使用os.devnull。默认使用的是None,表示什么都不做。另外,stderr可以合并到stdout里一起输出。

  • timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出TimeoutExpired异常。

  • check:如果该参数设置为True,并且进程退出状态码不是0,则弹出CalledProcessError异常。

  • encoding:如果指定了该参数,则stdin、stdout和stderr可以接收字符串数据,并以该编码方式编码。否则只接收bytes类型的数据。

  • shell:如果该参数为True,将通过操作系统的shell执行指定的命令,如果执行命令时遇见权限不足的境况,可以将此参数设置为True

更多参见:
https://www.cnblogs.com/liangxiyang/p/12124738.html

Popen

获取实时打印

popen = subprocess.Popen("./annie "+url, stdout = subprocess.PIPE,shell=True)# ,bufsize=1
while True:
    line = popen.stdout.readline().decode("utf-8")
    if not line:
        break

call

subprocess.call(args, *, stdin= None, stdout = None, stderr = None, shell = False)

运行由args参数提供的命令,

  • args参数是shell命令时,需要提供shell=True参数(否则命令错误时会抛出异常,不会正常返回命令提示)
  1. 父进程等待子进程完成
  2. 执行结束并返回返回码,正确执行返回0,否则返回1
  3. 执行错误不会抛出异常
#coding=utf-8
import subprocess

res = subprocess.call('java -version',shell=True)
print('=====结果:\n', res)

或者

#coding=utf-8
import subprocess

res = subprocess.call(['java','-version'],shell=True)
print('=====结果:\n', res)

注意不要为stdout和stderr参数赋值subprocess.PIPE,如果子进程输出量较多会造成死锁,这两个参数可以赋值为subprocess.STDOUT打印到屏幕或者赋值为一个文件对象将输出写入文件:

网上粘贴的,没试过

#coding=utf-8
import subprocess as sp
sp.call('python run.py', shell = True, stdin=open('fake_input', 'r'), stdout=open('result', 'w'))

check_call

subprocess.check_call(args, *, stdin = None, stdout = None, stderr = None, shell = False)
  1. 父进程等待子进程完成
  2. 与call方法类似,不同在于如果命令行执行成功,check_call返回返回码0,否则抛出subprocess.CalledProcessError异常。
  3. subprocess.CalledProcessError异常包括returncode、cmd、output等属性,其中returncode是子进程的退出码,cmd是子进程的执行命令,output为None。
    可用try…except…检查
#coding=utf-8
import subprocess

#必须加上shell=True,否则命令错误时会抛出异常,会不正常返回命令提示
try:
    res = subprocess.check_call(['java2','-version'],shell=True)
    print('=====结果:\n', res)
except subprocess.CalledProcessError, exc:
    print('\n异常信息:')
    print('returncode:', exc.returncode)
    print('cmd:', exc.cmd)
    print('output:', exc.output)

注意:不要为stdout和stderr参数赋值为subprocess.PIPE。

check_output

subprocess.check_output(args, *, stdin = None, stderr = None, shell = False, universal_newlines = False)
  1. 父进程等待子进程完成
  2. 以字符串形式返回执行结果的输出(即返回子进程向标准输出的输出结果),必须指定stderr = subprocess.STDOUT,否则返回为空
  3. 检查退出信息,如果returncode不为0,则抛出subprocess.CalledProcessError异常,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try…except…来检查。
#coding=utf-8
import subprocess
try:
    res = subprocess.check_output('java2 -version',
                    stderr = subprocess.STDOUT,
                    shell = True)
    print  ('结果:\n', res)
except subprocess.CalledProcessError, exc:
    print ('returncode:', exc.returncode)
    print ('cmd:', exc.cmd)
    print ('output:', exc.output)

执行ping baidu.com -t就废废了,有-t,会一直执行,执行不结束,就不会输出内容

注意:不要为stderr参数赋值为subprocess.PIPE。

更简单的文章参看:
http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html

感谢以下文章
http://blog.csdn.net/a464057216/article/details/47355219
http://www.jb51.net/article/48086.htm


原文出处:/show_1C7l3X6kPi.html