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/