← 返回首页

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/