我正在使用Windows 7,我在Python 2.6.6和Python 3.2下尝试过这个。
所以我试图从Python调用这个命令行:
netstat -ano | find ":80"
在Windows cmd下,此行完全正常。
所以,
第一次尝试:
output = subprocess.Popen(
[r'netstat -ano | find ":80"'],
stdout=subprocess.PIPE,
shell=True
).communicate()
引发错误,“发现”实际上没有收到正确的参数(例如'find':80“\”):
Access denied - \
第二次尝试:
#calling netstat
cmd_netstat = subprocess.Popen(
['netstat','-ano'],
stdout = subprocess.PIPE
)
#pipelining netstat result into find
cmd_find = subprocess.Popen(
['find','":80"'],
stdin = cmd_netstat.stdout,
stdout = subprocess.PIPE
)
同样,引发了同样的错误。
Access denied - \
我做错了什么? :(
编辑:
第3次尝试(如@Pavel Repin建议的那样):
cmd_netstat = subprocess.Popen(
['cmd.exe', '-c', 'netstat -ano | find ":80"'],
stdout=subprocess.PIPE
).communicate()
不幸的是,使用['cmd.exe',' - c']的子进程导致类似死锁或空白cmd窗口的内容。我假设cmd忽略'-c',导致communic()无限期地等待cmd终止。由于这是Windows,我的赌注是cmd只接受以斜杠(/)开头的参数。所以我用'/ c'代替'-c':
cmd_netstat = subprocess.Popen(
['cmd.exe', '/c', 'netstat -ano | find ":80"'],
stdout=subprocess.PIPE
).communicate()
然后......回到同样的错误:
Access denied - \
编辑: 我放弃了,我将只处理Python中'netstat -ano'返回的字符串。这可能是个错误吗?
答案 0 :(得分:3)
所以我重新回答了这个问题,发现了两个解决方案(我之前转向Python 2.7,所以我不确定Python 2.6,但它应该是相同的。):
将 find 替换为 findstr ,并删除双引号
output = subprocess.Popen(['netstat','-ano','|','findstr',':80'],
stdout=subprocess.PIPE,
shell=True)
.communicate()
但这并不能解释为什么“查找”无法使用,所以:
使用字符串参数代替列表
output = subprocess.Popen('netstat -ano | find ":80"',
stdout=subprocess.PIPE,
shell=True)
.communicate()
或
pipeout = subprocess.Popen(['netstat', '-ano'],
stdout = subprocess.PIPE)
output = subprocess.Popen('find ":80"',
stdin = pipeout.stdout,
stdout = subprocess.PIPE)
.communicate()
问题来自于:['find','“:80”']实际上被翻译成['find,'\“:80 \”']。 因此,在Windows命令shell中执行以下命令:
>find \":80\"
Access denied - \
证明:
运行:
output = subprocess.Popen(['echo','find','":80"'],
stdout=subprocess.PIPE,
shell=True)
.communicate()
print output[0]
返回:
find \":80\"
运行:
output = subprocess.Popen('echo find ":80"',
stdout=subprocess.PIPE,
shell=True)
.communicate()
print output[0]
返回:
find ":80"
答案 1 :(得分:2)
我建议您在Python代码中执行最大限度的操作。因此,您可以执行以下命令:
# executing the command
import subprocess
output = subprocess.Popen(['netstat', '-ano'], stdout=subprocess.PIPE).communicate()
然后解析输出:
# filtering the output
valid_lines = [ line for line in output[0].split('\r\n') if ':80' in line ]
您将获得一系列行。在我的计算机上,输出看起来像端口号1900(没有激活html连接):
[' UDP 127.0.0.1:1900 *:* 1388', ' UDP 192.xxx.xxx.233:1900 *:* 1388']
在我看来,这更容易使用。
请注意:
希望这有帮助。
编辑:哎呀,我错过了编辑的最后一行。看起来你已经有了自己的想法。答案 2 :(得分:0)
再次阅读这个旧问题后的新答案:这可能是由于以下两个事实:
管道操作符在子shell中执行以下命令;参见例如this interesting consequence)。
Python 本身 uses the pipe as a way to get the results back:
<块引用>请注意 (...) 要在结果元组中获得 None 以外的任何内容,您还需要提供 stdout=PIPE 和/或 stderr=PIPE。
不确定这种“冲突”是错误还是设计选择。