Python Subprocess 给我的 shell 参数添加了额外的引号

3 投票
1 回答
1256 浏览
提问于 2025-04-16 19:44

预期行为

在正常情况下,我可以在Linux系统下使用 tshark -E separator='@' 这个命令,强制它用 @ 来分隔输出的字段,像下面这样...

[mpenning@hotcoffee ~]$ tshark -r scp_test.pcap -e frame.number -e ip.src_host -e tcp.srcport -E separator='@' -T fields tcp | less
1@192.168.12.236@33088
2@192.168.12.238@22
3@192.168.12.236@33088
...

意外行为

同样,我以为可以通过 subprocess.Popen() 来运行相同的命令,然后把结果整理成列,并根据一些分析来上色... 我所有的分析都依赖于输出结果用 @ 来分隔,当我运行脚本时... 然而,我的脚本却 没有 使用 @... 相反,它用的是单引号;我不太明白这是为什么。

脚本

import subprocess
import sys

filename = sys.argv[1].strip()
fields = ['frame_num', 'IP Src', 'TCP Src']
sep = '@'
cmd = r"""tshark -r %s -e frame.number -e ip.src_host -e tcp.srcport -E separator='%s' -T fields tcp""" % (filename, sep)

subcmd = cmd.split(' ')
lines = subprocess.Popen(subcmd, stdout = subprocess.PIPE)
for line in lines.communicate()[0].split('\n'):
    print line

结果

[mpenning@hotcoffee ~]$ python analyze.py scp_test.pcap | less
1'192.168.12.236'33088
2'192.168.12.238'22
3'192.168.12.236'33088
4'192.168.12.238'22
5'192.168.12.236'33088
6'192.168.12.236'33088
7'192.168.12.238'22
8'192.168.12.236'33088

似乎无论我用以下任何一种方式来设置 sep 都没有关系...

  • sep = '@'
  • sep = '\@'
  • sep = re.escape('@') # 绝望的尝试 ;-)

问题

有人能解释一下吗:

  1. 为什么我上面的脚本输出没有用 @ 来分隔。
  2. 我该如何修复使用 subprocess 的脚本见注释B


附注

注释A. 系统信息:

[mpenning@hotcoffee ~]$ python -V
Python 2.6.6
[mpenning@hotcoffee ~]$ uname -a
Linux hotcoffee 2.6.32-5-amd64 #1 SMP Mon Mar 7 21:35:22 UTC 2011 x86_64 GNU/Linux
[mpenning@hotcoffee ~]$

注释B. 我不想要使用 os.system()os.popen() 的答案。

1 个回答

6

tshark正在处理来自'%s''。不要使用单引号:

cmd = r"tshark -r %s -e frame.number -e ip.src_host -e tcp.srcport -E separator=%s -T fields tcp" % (filename, sep)

当你从命令行运行它时,Bash把单引号去掉了,所以tshark没有看到它们。

撰写回答