【问题标题】:Execute a bash command with parameter in Python在 Python 中执行带参数的 bash 命令
【发布时间】:2016-05-30 09:09:47
【问题描述】:

这是我在 python 中运行并得到预期结果的 bash 命令:

count = subprocess.Popen("ps -ef | grep app | wc -l", stdout=subprocess.PIPE, shell=True)

但是当我想传递一个参数(在这种情况下是计数)时,我不知道该怎么做。 我试过了:

pid = subprocess.call("ps -ef | grep app | awk -v n=' + str(count), 'NR==n | awk \'{print $2}\'", shell=True)

args = shlex.split('ps -ef | grep app | awk -v n=' + str(count), 'NR==n | awk \'{print $2}\'')
pid = subprocess.Popen(args, stdout=subprocess.PIPE, shell=True)

在其他尝试中,来自这里的各种帖子,但仍然无法成功。

【问题讨论】:

  • 因为您使用' + str(..) 而不是" + str(...) 来终止您的字符串。在第二次尝试时,无论出于何种原因,您都会传递一个冒号 , 'NR==。你的语法到处都是。

标签: python bash subprocess


【解决方案1】:

您混合了开头和结尾的引号,并且在其他尝试中错误地传递了冒号。

试试这个解决办法:

pid = subprocess.call("ps -ef | grep app | awk -v n=" + str(count) + " NR==n | awk '{print $2}'", shell=True)

您使用" 打开了命令参数,因此您需要在使用" 而不是' 执行+ str() 之前关闭它。此外,我将, 'NR= 替换为+ "NR=,因为您想在命令中附加更多内容,而不是将参数传递给subprocess.call()

正如 cmets 中所指出的,将命令与 shlex 分开是没有意义的,因为管道命令未在 subprocess 中实现,但我想指出通常不建议使用 shell=True,因为例如examples given here 之一。

【讨论】:

  • 你错过了n=str(count)NR==n之间的空白
  • @J.F.Sebastian 不知道,感谢您指出这一点。通常不要在子进程中使用管道。更正我的答案。
  • @J.F.Sebastian 哈哈,我今天简直是满脸毛病,呵呵。我对那个枪很着急,一分钟前解决了元字符问题的问题,只是直言不讳地认为这又是这样的情况:)已修复!还要感谢您提到否决票的原因,正是出于这个原因,我希望人们更频繁地这样做,这样我们正确回答问题的人就可以在我们犯错误时完善我们的知识。
【解决方案2】:

另一个vay正在使用格式:

pid = subprocess.call("ps -ef | grep app | awk -v n={} NR==n | awk '{{print $2}}'".format(str(count)), shell=True)

【讨论】:

  • 不要使用'..n={}..'.format(str(count)),而是使用'..n={n}..'.format(n=count)
【解决方案3】:

您的 Awk 管道可以大大简化 - 如果目标是打印最后一场比赛,ps -ef | awk '/app/ { p=$2 } END { print p }' 会这样做。但很多时候,从 Python 中运行 Awk 是很愚蠢的,而在 Python 中执行过滤既方便又容易,而且显然效率更高(您不仅省去了 Awk 进程,还省去了烦人的shell=True)。

for p in subprocess.check_output(['ps', '-ef']).split('\n'):
    if 'app' in p:
        pid = p.split()[1]

【讨论】:

  • downvote—call() 返回退出状态(整数),而不是字符串。要了解如何逐行读取子进程的输出,请参阅this answer。虽然如果我们在 Python 中重新实现 shell 命令,那么我们可以使用 psutil 模块。
  • @J.F.Sebastian 哎呀,我的错,不小心从 OP 的代码中复制。改为使用check_output()(但它不适用于 2.7 之前的 Python)。
  • @J.F.Sebastian 这里的其他答案似乎也使用subprocess.call()...?
  • check_output(['ps', '-ef']).split('\n') 在 Python 3 中不起作用。是的,pid 名称作为 call() 的结果具有误导性。
猜你喜欢
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
相关资源
最近更新 更多