我想执行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已完成。
答案 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()