【问题标题】:Help with wrapping a command line tool in Python帮助在 Python 中包装命令行工具
【发布时间】:2011-08-26 17:49:53
【问题描述】:

我真的遇到了一个问题,希望有人能帮助我。我正在尝试在 Python3.1 中为名为@9​​87654322@ 的命令行程序创建一个包装器。我可以像这样在命令行上成功运行这个程序:

$ spooky -a 4 -b .97

我对 spooky 的第一次 Python 包装器尝试如下所示:

import subprocess

start = "4"
end = ".97"

spooky_path = '/Users/path/to/spooky'
cmd = [spooky_path, '-a', start, '-b', end]
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
process.wait()
print('Done')

以上代码打印Done,但不执行程序spooky

接下来我尝试像这样在命令行上执行程序:

$ /Users/path/to/spooky -a 4 -b .97

上面的代码也失败了,并且没有提供任何有用的错误。

我的问题是:如何通过将spooky -a 4 -b .97 发送到命令行来让 Python 运行该程序?我非常感谢您能提供的任何帮助。提前致谢。

【问题讨论】:

  • 首先你必须调查为什么后面的命令行调用不起作用。除非你没有解决这个问题,否则你不必考虑你的 python 方法。您的命令行调用会产生哪些“有用的错误”?
  • ...所以当您输入spooky 时它会运行,但是当您给它完整路径时它不会运行...明显的原因是完整路径是错误的。
  • 通过将其与which spooky 进行比较来检查这是否真的是正确的路径。
  • 在不相关的说明中,我认为subprocess.call 会比subprocess.Popen 更明显。
  • @Gerret 是的,它在输入spookyspooky -a 4 -b .97 时在命令行上运行。如果我输入完整路径,它也可以工作,但是如果我输入带参数的完整路径,它就不起作用('/Users/path/to/spooky -a 4 -b .97')

标签: python subprocess wrapper


【解决方案1】:

您需要删除 stdout=subprocess.PIPE。这样做会断开进程的标准输出与 Python 的标准输出,并使其可以使用 Popen.communicate() 函数检索,如下所示:

import subprocess

spooky_path = 'ls'
cmd = [spooky_path, '-l']
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = process.communicate()[0]
print "Output:", output
process.wait()
print('Done')

要使其直接打印,您可以在不使用 stdout 参数的情况下使用它:

process = subprocess.Popen(cmd)

或者你可以使用调用函数:

process = subprocess.call(cmd)

【讨论】:

  • 哇,这真的有效!!!考虑到我单独使用命令工具时遇到问题,我不太确定我是否理解为什么您的代码可以工作?无论如何,非常感谢您的帮助。
  • 它可能是事先工作的,您只是没有看到输出,因为它是通过管道传输的,您没有显示它,甚至没有尝试检索它。
【解决方案2】:

试着把你的命令变成一个字符串:

cmd = 'spooky_path -a start -b end'
process = subprocess.Popen(cmd, shell=True)

【讨论】:

  • 这只会告诉你没有可执行文件"spooky_path -a start -b end"
  • 不幸的是,一旦程序运行,我将需要使用 Python 以不同的 -b 值重复运行此命令。
  • 即使它必须是单个字符串也不是问题,只需将所需的值插入到字符串中,例如,cmd = "spooky -a %s -b %s" % (a, b) BTW,是的,单个字符串应该可以工作:从docs:“args 应该是一个字符串,或者是程序参数的序列。要执行的程序通常是 args 序列中的第一项,如果给定了字符串,则为字符串。”
  • 好吧,它不适合我 - Popen("touch this") 引发 OSError: [Errno 2] No such file or directory: 'touch this',而 Popen(["touch", "this"]) 按预期工作。 Python 版本 3.2 和 2.7。
  • @delnan:如果我设置shell=True,则使用单个字符串对我有用。答案已更新。
猜你喜欢
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
相关资源
最近更新 更多