python中output用法_【python2】commands模块getstatusoutput函数的小问题

2023-05-16

[TOC]

问题

import commands as subprocess

status, _ = 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

什么是subprocess32

谷歌将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).stdout

def 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, data

def 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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python中output用法_【python2】commands模块getstatusoutput函数的小问题 的相关文章

随机推荐