子流程不将输出存储在变量中

Subprocess does not store output in variable

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

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)。

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

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

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

当然,这仍然行不通,因为 glob 扩展是 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)

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))