python - subprocess.Popen 的输出

标签 python subprocess

我一直在写一些 python 代码,在我的代码中我使用的是“命令”

代码按我的预期工作,但后来我在 Python 文档中注意到该命令已被弃用,并将在 Python 3 中删除,我应该改用“subprocess”。

“好吧”我想,“我不希望我的代码直接进入遗留状态,所以我应该立即改变它。

问题是 subprocess.Popen 似乎在任何输出的开头添加了一个讨厌的字符串,例如

<subprocess.Popen object at 0xb7394c8c>

我看到的所有例子都有它,它似乎被认为是一直存在的。

这段代码;

#!/usr/bin/python
import subprocess
output = subprocess.Popen("ls -al", shell=True)
print output

产生这个;

<subprocess.Popen object at 0xb734b26c>
brettg@underworld:~/dev$ total 52
drwxr-xr-x  3 brettg brettg 4096 2011-05-27 12:38 .
drwxr-xr-x 21 brettg brettg 4096 2011-05-24 17:40 ..
<trunc>

这正常吗?如果我将它用作向控制台输出各种格式化详细信息的更大程序的一部分,它会把一切都搞砸。

我正在使用命令获取接口(interface)的 IP 地址,方法是使用 ifconfig 以及各种 greps 和 awk 来抓取地址。

考虑这段代码;

#!/usr/bin/python
import commands,subprocess

def new_get_ip (netif):
address = subprocess.Popen("/sbin/ifconfig " + netif + " | grep inet | grep -v inet6 | awk '{print $2}' | sed 's/addr://'i", shell=True)
return address

def old_get_ip (netif):
address = commands.getoutput("/sbin/ifconfig " + netif + " | grep inet | grep -v inet6 | awk '{print $2}' | sed 's/addr://'i")
return address

print "OLD IP is :",old_get_ip("eth0")
print ""
print "NEW IP is :",new_get_ip("eth0")

返回;

brettg@underworld:~/dev$ ./IPAddress.py
OLD IP is : 10.48.16.60

NEW IP is : <subprocess.Popen object at 0xb744270c>
brettg@underworld:~/dev$ 10.48.16.60

至少可以说这很糟糕。

显然我在这里遗漏了一些东西。我当然是 Python 的新手,所以我确定是我做错了事,但到目前为止,各种谷歌搜索都没有结果。

如果我想要更干净的输出怎么办?我是否必须手动修剪有问题的输出,或者我是否错误地调用了 subprocess.Popen

最佳答案

“丑陋的字符串”它应该打印的内容。 Python 正确打印出 repr(subprocess.Popen(...)) , 就像你说 print(open('myfile.txt')) 时它会打印的一样.

此外,python 不知道输出到标准输出的是什么。您看到的输出不是 来自 python,而是来自进程的 stdout 和 stderr 作为垃圾邮件被重定向到您的终端,甚至没有经过 python 进程。这就像你运行了一个程序 someprogram &没有将其标准输出和标准错误重定向到 /dev/null ,然后尝试运行另一个命令,但您偶尔会看到来自该程序的垃圾邮件。重复并澄清:

<subprocess.Popen object at 0xb734b26c>  <-- output of python program
brettg@underworld:~/dev$ total 52                     <-- spam from your shell, not from python
drwxr-xr-x  3 brettg brettg 4096 2011-05-27 12:38 .   <-- spam from your shell, not from python
drwxr-xr-x 21 brettg brettg 4096 2011-05-24 17:40 ..  <-- spam from your shell, not from python
...

为了捕获标准输出,您必须使用 .communicate()函数,像这样:

#!/usr/bin/python
import subprocess
output = subprocess.Popen(["ls", "-a", "-l"], stdout=subprocess.PIPE).communicate()[0]
print output

此外,您永远不想使用 shell=True ,因为它是一个安全漏洞(一个具有未过滤输入的主要安全漏洞,一个没有输入的小安全漏洞,因为它允许通过修改 shell 环境进行本地攻击)。出于安全原因以及为了避免错误,您通常希望传入列表而不是字符串。如果你懒惰,你可以执行“ls -al”.split(),这是不受欢迎的,但执行类似 (“ls -l %s”%unsanitizedInput).split() 之类的操作将是一个安全漏洞。

关于python - subprocess.Popen 的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6147193/

相关文章:

python - cherrypy Python3 兼容了吗?

python - 将重复列名列表和值列表转换为数据框

python - 将多个 Popen 命令与管道链接起来

python - 什么是SQLAlchemy 1.4 ORM中的Query.count?

python - Pandas 将时间序列从微秒降采样到分钟,并按分钟进行处理

python - 队列和线程: subprocess goes missing

python - 为什么此代码在 Python3.1 中的行为与在 Python2.6 中的行为不同?

subprocess - 在 IPython 中运行外部命令

python - 在 Windows 中复制 fork() 的最佳方法是什么?

Python - 格式化字符串中的变量