Skip to content

subprocess: python 2.7脚本中如何运行shell命令

每次用的时候都要去读一下文档,这次总结一下,记录于此,已备后用。

其实这个主要是用subprocess这个模块。

最普通的,执行命令,但不管命令的输出:

import subprocess
return_code = subprocess.call("ls","-ltra"], shell=True)

设置”shell=True” 是告诉python在后台生成一个shell进程,然后在此shell进程中执行相应命令。 这样可以利用到shell中的一些特性,但这样做有安全风险,只有传入的命令完全可控时才这样做。

 

命令的返回值保存在return_code中。输出则直接输出到屏幕(stdout)。

如果需要获取命令的输出,则用subprocess中的check_output, 而非call:

output = subprocess.check_output(['ls', '-l'])
print 'Have %d bytes in output' % len(output)
print output

## if the command fails, python throws an CalledProcessError

上面的方式中,如果命令的出错输出(如果有的话)仍然会出现在屏幕上。

如果想要将出错输出一并捕捉,则在设置stderr参数为STDOUT:

import subprocess

output = subprocess.check_output(
'echo to stdout; echo to stderr 1>&2; exit 1',
shell=True,
stderr=subprocess.STDOUT,
)
print 'Have %d bytes in output' % len(output)
print output

如果需要传入一些数据给要执行的命令,则使用Popen函数,且设置stdin参数为subprocess.PIPE, 然后再调用 communicate()函数,将要传入的数据作为参数传入:

import subprocess

print '\nwrite:'
proc = subprocess.Popen(['cat', '-'],
stdin=subprocess.PIPE,
)
proc.communicate('\tstdin: to stdin\n')

如果既需要传入数据,又需要获取输出,则同时设置stdin和stdout:

import subprocess

print '\npopen2:'

proc = subprocess.Popen(['cat', '-'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
stdout_value = proc.communicate('through stdin to stdout')[0]
print '\tpass through:', repr(stdout_value)

如果还要错误输出:

import subprocess

print '\npopen4:'
proc = subprocess.Popen('cat -; echo "to stderr" 1>&2',
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
stdout_value, stderr_value = proc.communicate('through stdin to stdout\n')
print '\tcombined output:', repr(stdout_value)
print '\tstderr value :', repr(stderr_value)

模仿shell命令的管道用法: cat index.rst | grep ‘.. include::’ | cut -f 3 -d:

(每次看到为了运行一个命令都要这么麻烦我就头痛 :-()

import subprocess

cat = subprocess.Popen(['cat', 'index.rst'], 
stdout=subprocess.PIPE,
)

grep = subprocess.Popen(['grep', '.. include::'],
stdin=cat.stdout,
stdout=subprocess.PIPE,
)

cut = subprocess.Popen(['cut', '-f', '3', '-d:'],
stdin=grep.stdout,
stdout=subprocess.PIPE,
)

end_of_pipe = cut.stdout

print 'Included files:'
for line in end_of_pipe:
print '\t', line.strip()

参考文档:

https://docs.python.org/2/library/subprocess.html

https://pymotw.com/2/subprocess/

Avatar

专业Linux/Unix/Windows系统管理员,开源技术爱好者。对操作系统底层技术,TCP/IP协议栈以及信息系统安全有强烈兴趣。电脑技术之外,则喜欢书法,古典诗词,数码摄影和背包行。

Sidebar