Python - 在Popen中使用列表作为命令

3 投票
2 回答
12579 浏览
提问于 2025-04-17 09:36

我尝试用Popen创建一个子进程。以下是我最开始的代码:

hostname = 'host'
servername = 'server'
commandargs = ['/usr/sbin/mminfo',' -o n',' -s',servername,' -q "client=\'',hostname,'\',savetime>=last day"',' -r "client,name"']
process = subprocess.Popen(commandargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

问题是执行的命令失败了,提示信息是联系的服务器不可用。看起来变量hostname没有被使用到……

我试着用一个字符串代替列表作为Popen中的命令(并设置Shell=True),这样就一切正常了。

有没有人知道我的代码哪里出错了?

问候,
Stefan

2 个回答

7

在这个列表里,每个参数都必须是单独的一项。字符串中不能有空格:

commandargs = ['/usr/sbin/mminfo', '-o', 'n', '-s', servername,
               '-q', "client='" + hostname + "',savetime>=last day",
               '-r', 'client,name']
5

在给定的列表中,每个字符串都被当作一个单独的命令行参数来处理。使用这种语法时,你也不需要加引号。

可以试试这样做:

hostname = 'host'
servername = 'server'
commandargs = [
    '/usr/sbin/mminfo',
    '-o', 'n', # these are separate arguments, but on the same line for clarity's sake
    '-s', servername, # same here
    '-q', "client='%s',savetime>=last day" % hostname, # same here...
    '-r', 'client,name' # and here.
]
process = subprocess.Popen(commandargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

补充说明:或者,根据评论,可以试试这样:

import subprocess

client_name = "lxds05"
server_name = "nsr_srv"

queryspec = "client='%s',savetime>=last day" % client_name
reportspec = "client,name,savetime(17),nsavetime,level,ssflags"

args = [
    '/usr/sbin/mminfo',
    '-o', 'n',
    '-s', server_name,
    '-q', queryspec,
    '-r', reportspec,
    '-x', 'c'
]

subprocess.Popen(args) # ... etc

撰写回答