- 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结果