【问题标题】:Passing shell commands in python subprocess.Popen() with two quoted words在 python subprocess.Popen() 中使用两个引用的单词传递 shell 命令
【发布时间】:2020-05-29 01:05:30
【问题描述】:

我试图在我的 python 代码中运行下一个命令:

iostat -d 7 7 -p sda | awk '!/^Device/' | awk '!/^Linux/'

到目前为止我尝试的方式是这样的:

command = ["iostat", "-d", "7", "7", "-p", "sda", "|", "awk", "'!/^Device/'", "|", "awk", "'!/^Linux/'"]
device = subprocess.Popen(command, stdout=subprocess.PIPE)
devicetr = device.stdout.read()

似乎代码无法按预期处理"'!/^Device/'""'!/^Linux/'" 中的引号,例如'!/^Device/''!/^Linux/'

当没有连接 USB 时,我得到的不是空白:

Linux 4.14.98-v7+   01/28/2020  _armv7l_    (4 CPU)

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn

已经尝试添加 '\' 并且这个: Passing double quote shell commands in python to subprocess.Popen()?

【问题讨论】:

  • 这不起作用,因为 | 和其他字符由 shell 解释,Popen 默认与 shell=False 一起运行。从 Python 中执行 Shell 管道并不容易,尤其是在复杂的引用中。

标签: python subprocess


【解决方案1】:
  1. 您不需要添加额外的引号,因为subprocess 会在需要时自动添加它们。
command = ["iostat", "-d", "7", "7", "-p", "sda", "|", "awk", "!/^Device/", "|", "awk", "!/^Linux/"]
device = subprocess.Popen(command, stdout=subprocess.PIPE)
devicetr = device.stdout.read()  # also here was a typo red -> read
  1. 由于@noufal-ibrahim 指向| 的指针不能以这种方式工作。您需要通过管道传输您的命令:
ps1 = subprocess.Popen(["iostat"], stdout=subprocess.PIPE)
ps2 = subprocess.Popen(["awk",  "!/^ *KB/"], stdin=ps1.stdout, stdout=subprocess.PIPE)  # filter out line with KB and extra space
print(ps2.stdout.read().decode())

^ 此代码适用于我的机器,您可以根据自己的用例进行调整。

附录。您可以使用shlex lib(来自标准python lib),而不是手动创建命令列表:

>>> import shlex
>>> shlex.split("python foo.py 'multi word arg'")
['python', 'foo.py', 'multi word arg']

【讨论】:

  • 尝试删除,但遇到同样的问题。
猜你喜欢
  • 2013-02-02
  • 2021-12-31
  • 2017-05-02
  • 2017-10-12
  • 2023-04-04
  • 2015-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多