子流程不将输出存储在变量中
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))
我正在尝试捕获此命令的输出:
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))