subprocess.run()用法python3.7

def run(*popenargs,
        input=None, capture_output=False, timeout=None, check=False, **kwargs):
    """Run command with arguments and return a CompletedProcess instance.

    The returned instance will have attributes args, returncode, stdout and
    stderr. By default, stdout and stderr are not captured, and those attributes
    will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

    If check is True and the exit code was non-zero, it raises a
    CalledProcessError. The CalledProcessError object will have the return code
    in the returncode attribute, and output & stderr attributes if those streams
    were captured.

    If timeout is given, and the process takes too long, a TimeoutExpired
    exception will be raised.

    There is an optional argument "input", allowing you to
    pass bytes or a string to the subprocess's stdin.  If you use this argument
    you may not also use the Popen constructor's "stdin" argument, as
    it will be used internally.

    By default, all communication is in bytes, and therefore any "input" should
    be bytes, and the stdout and stderr will be bytes. If in text mode, any
    "input" should be a string, and stdout and stderr will be strings decoded
    according to locale encoding, or by "encoding" if set. Text mode is
    triggered by setting any of text, encoding, errors or universal_newlines.

    The other arguments are the same as for the Popen constructor.
    """
    if input is not None:
        if 'stdin' in kwargs:
            raise ValueError('stdin and input arguments may not both be used.')
        kwargs['stdin'] = PIPE

    if capture_output:
        if ('stdout' in kwargs) or ('stderr' in kwargs):
            raise ValueError('stdout and stderr arguments may not be used '
                             'with capture_output.')
        kwargs['stdout'] = PIPE
        kwargs['stderr'] = PIPE

    with Popen(*popenargs, **kwargs) as process:
        try:
            stdout, stderr = process.communicate(input, timeout=timeout)
        except TimeoutExpired:
            process.kill()
            stdout, stderr = process.communicate()
            raise TimeoutExpired(process.args, timeout, output=stdout,
                                 stderr=stderr)
        except:  # Including KeyboardInterrupt, communicate handled that.
            process.kill()
            # We don't call process.wait() as .__exit__ does that for us.
            raise
        retcode = process.poll()
        if check and retcode:
            raise CalledProcessError(retcode, process.args,
                                     output=stdout, stderr=stderr)
    return CompletedProcess(process.args, retcode, stdout, stderr)

  可以看到返回的是一个completeProcess对象

 

class CompletedProcess(object):
    """A process that has finished running.

    This is returned by run().

    Attributes:
      args: The list or str args passed to run().
      returncode: The exit code of the process, negative for signals.
      stdout: The standard output (None if not captured).
      stderr: The standard error (None if not captured).
    """
    def __init__(self, args, returncode, stdout=None, stderr=None):
        self.args = args
        self.returncode = returncode
        self.stdout = stdout
        self.stderr = stderr

    def __repr__(self):
        args = ['args={!r}'.format(self.args),
                'returncode={!r}'.format(self.returncode)]
        if self.stdout is not None:
            args.append('stdout={!r}'.format(self.stdout))
        if self.stderr is not None:
            args.append('stderr={!r}'.format(self.stderr))
        return "{}({})".format(type(self).__name__, ', '.join(args))

    def check_returncode(self):
        """Raise CalledProcessError if the exit code is non-zero."""
        if self.returncode:
            raise CalledProcessError(self.returncode, self.args, self.stdout,
                                     self.stderr)

  

 

所以调用获取最终returncode可以使用

sub=subproccess.run(xxxxx)

returncode,out,err,args=sub.returncode,sub.stdout,sub.stderr,sub.args

 

 

#!/usr/bin/python3
# coding=gbk
import os
import sys
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
import subprocess
import platform
from src import logutils

log=logutils.logger("app",rootstdout=True,handlerList=['I','E'])
""" 
  if check=True then returncode ==0 return stdout normal,
  returncode!=0 rasise callProcessError ,check=False nothing to do
""" def subprocess_run(): str_shell='df -m &&netstat -ntslp|grep 11111' CompletedProcessObject=subprocess.run(args=str_shell,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True,timeout=10,check=False) if CompletedProcessObject: code,out,err=CompletedProcessObject.returncode,CompletedProcessObject.stdout,CompletedProcessObject.stderr if code ==0: if out: #log.info("执行isok!!!!") log.info(out) return out if err: log.error(err) return err else: if code ==1: log.error("语法输出对象为空") else: #log.info(code) raise subprocess.CalledProcessError(code,str_shell) def run(): str_shell='df -m && netstat -ntlp' sub=subprocess.Popen(args=str_shell,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True) out,err=sub.communicate() #res=sub.stdout.readlines() if sub.returncode == 0: #log.info("returncode is 0,执行输出正常") if out: log.info("执行输出正常") log.info(out) if err: log.error("出现异常") log.error(err,exc_info=True) else: if sub.returncode == 1: log.error("执行shell对象结果有空") else: raise subprocess.CalledProcessError(sub.returncode, str_shell) def operate_sys(): plat_tuple=platform.architecture() system=platform.system() plat_version=platform.platform() if system == 'Windows': return system,plat_version # log.info('this is windows system') # log.info('version is: '+plat_version) elif system == 'Linux': return system,plat_version # log.info('this is linux system ') # log.info('version is: '+plat_version) if __name__ == '__main__': subprocess_run()

 正常check=True时 returncode=0代表结果都输出正常

[root@hostuser src]# python3 subprocess_popen.py
[INFO]2019-05-19 21:01:59 Sun --app-- subprocess_popen.py:
执行isok!!!!
[INFO]2019-05-19 21:01:59 Sun --app-- subprocess_popen.py:
Filesystem 1M-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 27627 8652 18975 32% /
devtmpfs 894 0 894 0% /dev
tmpfs 910 1 910 1% /dev/shm
tmpfs 910 11 900 2% /run
tmpfs 910 0 910 0% /sys/fs/cgroup
/dev/sda1 1014 232 783 23% /boot
tmpfs 182 1 182 1% /run/user/42
tmpfs 182 0 182 0% /run/user/0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.81.129 netmask 255.255.255.0 broadcast 192.168.81.255
inet6 fe80::f08c:a9:42b2:6ec4 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:11:d6:35 txqueuelen 1000 (Ethernet)
RX packets 16609 bytes 1344727 (1.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 9525 bytes 1168830 (1.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 194415 bytes 161261315 (153.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 194415 bytes 161261315 (153.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:4a:9f:2c txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

正常check=True时抛出异常1代表执行结果有空:
[root@hostuser src]# python3 subprocess_popen.py
Traceback (most recent call last):
File "subprocess_popen.py", line 73, in <module>
subprocess_run()
File "subprocess_popen.py", line 17, in subprocess_run
stderr=subprocess.PIPE,universal_newlines=True,timeout=10,check=True)
File "/usr/local/lib/python3.7/subprocess.py", line 487, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'df -m &&netstat -ntslp|grep 11111' returned non-zero exit status 1.

check=False:异常时则如果你不做处理返回空

正常还是返回stdout结果

 

转载于:https://www.cnblogs.com/SunshineKimi/p/10889145.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`subprocess.Popen()`和`subprocess.run()`都是Python中用于执行外部命令的模块,但它们有一些区别。 1. 返回值类型: - `subprocess.Popen()`返回一个Popen对象,它代表了正在执行的子进程。 - `subprocess.run()`返回一个CompletedProcess对象,它包含了已完成的子进程的执行结果。 2. 方便性: - `subprocess.Popen()`提供了更多底层的控制选项和灵活性。它可以用于更复杂的使用场景,如处理多个子进程、管道连接等。 - `subprocess.run()`是Python 3.5及以上版本引入的更高级的接口,它封装了常见的命令行操作,提供了更简单易用的方式来执行外部命令。 3. 输捕获: - 在Python 3.7及以下版本中,`subprocess.Popen()`需要手动处理标准输和错误输,通常需要使用`stdout=subprocess.PIPE`和`stderr=subprocess.PIPE`参数,并结合`communicate()`方法来获取输结果。 - 在Python 3.7及以上版本中,`subprocess.run()`提供了`capture_output=True`参数,可以直接捕获命令的标准输和错误输到`stdout`和`stderr`属性中。 4. 等待命令完成: - `subprocess.Popen()`需要显式地调用`wait()`或`communicate()`方法来等待子进程完成。 - `subprocess.run()`会等待命令执行完毕,不需要显式调用其他方法。 总的来说,如果你需要更底层的控制或处理复杂的使用场景,可以使用`subprocess.Popen()`。而对于简单的命令行操作,`subprocess.run()`提供了更简洁易用的接口。如果你使用的是Python 3.7及以上版本,`subprocess.run()`可以方便地捕获输结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值