【问题标题】:Python - using a list in Popen as commandPython - 在 Popen 中使用列表作为命令
【发布时间】:2012-01-05 14:06:40
【问题描述】:

我尝试使用 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)

问题是执行的命令失败并显示一条消息,即所联系的服务器不可用。似乎没有使用变量主机名... 尝试使用字符串而不是列表,作为 Popen 中的命令(使用 Shell=True),一切正常。

有人知道代码有什么问题吗?

问候。 斯蒂芬

【问题讨论】:

  • 不要引用主机名,不需要。有效的主机名没有任何可以扩展为奇怪的字符,也没有空格。您应该做的另一件事是将命令中的每个实体分开,不要使用“-o n”,而是使用“-o”、“n”等。
  • hostname = 'host' 你的意思是 ^?这是我用测试主机名填充变量的测试。

标签: python string list subprocess popen


【解决方案1】:

在列表中,每个参数都必须是它自己的项目。字符串中不应有空格:

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

【讨论】:

  • 谢谢,一切正常。只有“最后一天”有一个空白。有什么特殊字符吗?
  • @StefanS 不,列表的重点正是让子进程完成所有转义。
  • 好的,像'这样的字符是什么,我必须转义它吗?
  • 没有。正如我所写,子进程所有为命令行调用进行转义。如果您的程序将其参数解释为复合结构的表示(例如您的示例中的 -q,我之前没有注意到 - 已更新),您必须自己组装该表示。
【解决方案2】:

给定列表中的每个字符串都作为单个命令行参数处理。使用此语法时也不需要使用引号。

试试这样的:

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)

编辑:或者,基于 cmets,类似

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

【讨论】:

  • commandargs = [ '/usr/sbin/mminfo', '-o','n', '-s',服务器名, '-q','"client='',主机名, '\',savetime>=last',' ','day"', '-r','"client,name,savetime(17),nsavetime,level,ssflags"', '-x','"c ;"', '|sed','"1d"']
  • 如果没有 shell 参数,使用管道将无法工作,但如果您只使用 sed 删除一行,您也可以在 Python 中这样做。跨度>
  • 对不起我的粘贴,:-(,我试图把编辑后的列表放在这里。
  • 好的,非常感谢。但是如何在列表元素中使用空白?
  • something = ["", "", ""] 将创建一个包含三个空字符串的列表。
猜你喜欢
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 2017-12-18
  • 1970-01-01
相关资源
最近更新 更多