本文共 4686 字,大约阅读时间需要 15 分钟。
[TOC]
import commands as subprocessstatus, _ = subprocess.getstatusoutput("ps -elf|grep fuckU")# status:# 255
这里的status按照grep的定义其实应该返回1,也就是没有grep到匹配项,在shell中echo $? 结果为1
但是python2
的getstatusoutput
获取的并不是os.exitcode()
而是os.wait()
的返回值。 python3
由于使用的是subprocess = modified(commands + subprocess)
,同样执行 status, _ = subprocess.getstatusoutput("ps -elf|grep fuckU")
得到的status为正确的1
兼顾Python2和Python3的使用习惯,使用google开源的subprocess32代替commands
谷歌将Python32的subprocess移植到了python2版本中。据说这是线程安全的版本。
最新的Python32版本为3.5.3也就是将python3.5.3中的subprocess基本功能移植到了Python2中。但是subprocess32不包含原本commands中的函数。Timeout support backported from Python 3.3 is included.The run() API from Python 3.5 was backported in subprocess32 3.5.0.Otherwise features are frozen at the 3.2 level.
这里我们使用subprocess32.run()方法去模拟getstatusoutput等便捷的函数(python3官方实现)
# 原本的timeout=None,因为Python2不支持*args,**kwargs外再有kwargs,暂时移出参数项,放至函数体内# def check_output(*popenargs, timeout=None, **kwargs):def check_output(*popenargs, **kwargs): r"""Run command with arguments and return its output. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"]) b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally. To capture standard error in the result, use stderr=STDOUT. >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], ... stderr=STDOUT) b'ls: non_existent_file: No such file or directory\n' There is an additional optional argument, "input", allowing you to pass 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 too will be used internally. Example: >>> check_output(["sed", "-e", "s/foo/bar/"], ... input=b"when in the course of fooman events\n") b'when in the course of barman events\n' If universal_newlines=True is passed, the "input" argument must be a string and the return value will be a string rather than bytes. """ timeout = None if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') if 'input' in kwargs and kwargs['input'] is None: # Explicitly passing input=None was previously equivalent to passing an # empty string. That is maintained here for backwards compatibility. kwargs['input'] = '' if kwargs.get('universal_newlines', False) else b'' return subprocess.run(*popenargs, stdout=subprocess.PIPE, timeout=timeout, check=True, **kwargs).stdoutdef getstatusoutput(cmd): """Return (exitcode, output) of executing cmd in a shell. Execute the string 'cmd' in a shell with 'check_output' and return a 2-tuple (status, output). The locale encoding is used to decode the output and process newlines. A trailing newline is stripped from the output. The exit status for the command can be interpreted according to the rules for the function 'wait'. Example: >>> import subprocess >>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') >>> subprocess.getstatusoutput('cat /bin/junk') (1, 'cat: /bin/junk: No such file or directory') >>> subprocess.getstatusoutput('/bin/junk') (127, 'sh: /bin/junk: not found') >>> subprocess.getstatusoutput('/bin/kill $$') (-15, '') """ try: data = check_output(cmd, shell=True, universal_newlines=True, stderr=subprocess.STDOUT) exitcode = 0 except subprocess.CalledProcessError as ex: data = ex.output exitcode = ex.returncode if data[-1:] == '\n': data = data[:-1] return exitcode, datadef getoutput(cmd): """Return output (stdout or stderr) of executing cmd in a shell. Like getstatusoutput(), except the exit status is ignored and the return value is a string containing the command's output. Example: >>> import subprocess >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' """ return getstatusoutput(cmd)[1]
其实python官方推荐使用这个函数执行系统命令
subprocess.run()
但是这个函数将输出直接print到终端中
如果需要屏蔽恣意的屏幕输出,可以使用subprocess.DEVNULL
(subprocess 3.5.3中有)
# 即x = subprocess.run('echo 250', shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)# x:# CompletedProcess(args='echo 250', returncode=0)# reference: https://stackoverflow.com/questions/8529390/is-there-a-quiet-version-of-subprocess-call
转载于:https://blog.51cto.com/l0vesql/2357311