【问题标题】:Subprocess does not store output in variable子进程不将输出存储在变量中
【发布时间】:2021-11-06 20:35:27
【问题描述】:

我正在尝试捕获此命令的输出:

ls -l /sys/class/net/e*/device/virtfn*

在我的 python 脚本中使用子进程库。

这个命令的输出是:

lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f0/device/virtfn0 -> ../0000:01:10.0
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f0/device/virtfn1 -> ../0000:01:10.2
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f0/device/virtfn2 -> ../0000:01:10.4
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f0/device/virtfn3 -> ../0000:01:10.6
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f0/device/virtfn4 -> ../0000:01:11.0
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f0/device/virtfn5 -> ../0000:01:11.2
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f0/device/virtfn6 -> ../0000:01:11.4
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f0/device/virtfn7 -> ../0000:01:11.6
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f1/device/virtfn0 -> ../0000:01:10.1
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f1/device/virtfn1 -> ../0000:01:10.3
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f1/device/virtfn2 -> ../0000:01:10.5
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f1/device/virtfn3 -> ../0000:01:10.7
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f1/device/virtfn4 -> ../0000:01:11.1
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f1/device/virtfn5 -> ../0000:01:11.3
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f1/device/virtfn6 -> ../0000:01:11.5
lrwxrwxrwx. 1 root root 0 Sep  7 14:52 /sys/class/net/enp1s0f1/device/virtfn7 -> ../0000:01:11.7

我的脚本中的代码:

def getMacOfBusSlotFunction(self, slotbus, slotslot, slotfunction):
   myParentDevicesProcess = subprocess.Popen(['ls','-l','/sys/class/net/e*/device/virtfn*'])

    stdout , stderr = myParentDevicesProcess.communicate()
    print(stdout.decode("utf-8"))

我以Retrieving the output of subprocess.call() 为基础。

我添加了.decode("utf-8") 部分,因为我认为输出可能会以bytes 返回。包括它和排除它仍然会得到相同的结果...

运行此命令得到的实际输出是一个空行 (\n)。

我希望输出是命令的实际输出。

【问题讨论】:

    标签: python python-2.7 subprocess


    【解决方案1】:

    您忘记告诉Popen 捕获输出/stderr;默认情况下,它只是让它进入终端。要修复,您只需要告诉它通过管道将它们捕获到父进程:

    myParentDevicesProcess = subprocess.Popen(['ls','-l','/sys/class/net/e*/device/virtfn*'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    

    当然,这仍然行不通,因为全局扩展是 shell 的属性,而不是 ls 命令,而且您不是通过 shell 运行命令(也不应该)。您可以让 Python 为您进行 glob 扩展以大致匹配 shell(将 import glob 放在文件顶部):

    myParentDevicesProcess = subprocess.Popen(['ls','-l'] + glob.glob('/sys/class/net/e*/device/virtfn*'), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    

    【讨论】:

      【解决方案2】:

      Popen(或任何subprocess 调用),没有shell=True,不能使用通配符扩展等shell 功能。如果您也检查过标准错误,您会发现ls 找不到字面名称为/sys/class/net/e*/device/virtfn 的文件的错误消息。

      简单的解决方法是使用 shell(并且可能切换回以避免裸露的Popen)。

      listing = subprocess.check_output('ls -l /sys/class/net/e*/device/virtfn', shell=True)
      

      在某些方面,更好的解决方案是使用 Python 的本机函数来提取您需要的信息,而不是 attempt to parse ls output,但由于我们不知道您想要什么信息,这有点难以确定。如果您的最终目标是解析符号链接,请尝试

      import glob
      import os
      
      for symlink in glob.glob('/sys/class/net/e*/device/virtfn'):
          print(os.readlink(symlink))
      

      【讨论】:

        猜你喜欢
        • 2017-04-21
        • 2017-01-05
        • 1970-01-01
        • 1970-01-01
        • 2014-07-02
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        • 2018-07-12
        相关资源
        最近更新 更多