Python Popen shell脚本但失败了

时间:2015-12-08 17:32:10

标签: python bash shell subprocess popen

我想执行bash命令

 '/bin/echo </verbosegc> >> /tmp/jruby.log'

在python中使用Popen。代码不会引发任何异常,但执行后jruby.log上没有任何更改。 python代码如下所示。

>>> command='/bin/echo </verbosegc> >> '+fullpath
>>> command
'/bin/echo </verbosegc> >> /tmp/jruby.log'
>>process = subprocess.Popen(command.split(),  stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
>>> output= process.communicate()[0]
>>> output
'</verbosegc> >> /tmp/jruby.log\n

我还打印出process.pid,然后使用ps -ef |检查pid grep pid。结果显示进程pid已完成。

4 个答案:

答案 0 :(得分:2)

如果要将输出附加到文件,只需使用传递文件对象,除非设置shell=True,否则无法重定向到文件:

command = ['/bin/echo', '</verbosegc>']

with open('/tmp/jruby.log',"a") as f:
     subprocess.check_call(command, stdout=f,stderr=subprocess.STDOUT)

答案 1 :(得分:1)

subprocess.Popen的第一个参数是数组['/bin/echo', '</verbosegc>', '>>', '/tmp/jruby.log']。当subprocess.Popen的第一个参数是一个数组时,它不会启动一个shell来运行命令,而shell负责将>> /tmp/jruby.log解释为“将输出写入jruby.log”。 / p>

为了使>>重定向工作在此命令中,您需要将command直接传递给subprocess.Popen(),而不将其拆分为列表。您还需要引用第一个参数(否则shell将以您不想要的方式解释“&lt;”和“&gt;”字符):

command = '/bin/echo "</verbosegc>" >> /tmp/jruby.log'
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)

答案 2 :(得分:1)

请考虑以下事项:

command = [ 'printf "%s\n" "$1" >>"$2"',  # shell script to execute
            '',                           # $0 in shell
            '</verbosegc>',               # $1
            '/tmp/jruby.log' ]            # $2
subprocess.Popen(command, shell=True)

第一个参数是引用$1$2的shell脚本,它们又作为单独的参数传递。将数据与代码分开,而不是试图将前者替换为后者,是对shell注入的预防措施(将其视为SQL注入的类比)。

当然,不要实际上在Python中做这样的事情 - 文件IO的原生原语更合适。

答案 3 :(得分:-1)

您是否尝试过不拆分命令and using shell=True?我通常的格式是:

 process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
 output = process.stdout.read()       # or .readlines()