Python 弹出 shell 脚本但失败

Python Popen shell script but fail

我要执行bash命令

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

在 python 中使用 Popen。该代码不会引发任何异常,但是 none 在执行后对 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已经执行完毕。

你试过不拆分命令and using shell=True吗?我常用的格式是:

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

subprocess.Popen 的第一个参数是数组 ['/bin/echo', '</verbosegc>', '>>', '/tmp/jruby.log']。当 subprocess.Popen 的第一个参数是数组时,它不会启动 shell 到 运行 命令,shell 负责解释 >> /tmp/jruby.log意思是 "write output to jruby.log".

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

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

考虑以下几点:

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

第一个参数是引用 </code> 和 <code> 的 shell 脚本,它们依次作为单独的参数传递。将数据与代码分开,而不是试图将前者替换为后者,是防止 shell 注入的一种预防措施(将其视为 SQL 注入的类比)。


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

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

,否则无法重定向到文件
command = ['/bin/echo', '</verbosegc>']

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