subprocess.Popen 不是 运行 shell 命令
subprocess.Popen is not running shell command
我正在尝试使用 subprocess.Popen
到 运行 'cat test.txt | grep txt',但它不起作用。在我的代码中,我执行了 subprocess.Popen
命令两次。
1: First time I used it to run a tshark command which redirectes the command output to a text (test.txt) file (which works fine). (defined in function get_all_tshark_out in below code)
2: Second time used subprocess.Popen to run 'cat test.txt | grep txt' command to extract txt from this file to perform some validation. This didn't work for me. (defined in function get_uniq_sessions in below code)
为了确保不是因为缓冲区溢出,我也在刷新 stdout
,但没有得到任何帮助。下面是我的代码:
import subprocess
import logging
def get_all_tshark_out(logger, tcpdump, port):
command = """tshark -r "%s" -odiameter.tcp.ports:"%s" -R 'diameter.cmd.code == 272 and diameter.flags.request==0 and !tcp.analysis.retransmission and diameter.flags.T == 0' -Tpdml -Tfields -ediameter.Session-Id | sort > test.txt""" %(tcpdump, port)
p_out = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
sys.stdout.flush()
sys.stderr.flush()
return 1
def get_uniq_sessions(logger, id='1234', uniqlog_file='test.txt'):
command = "cat "+ uniqlog_file +" | grep "+ id
print command
p_out = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
print "PPPPP", p_out
output = p_out.stdout.read()
p_out.wait()
command_out_list = (output.strip().split("\n"))
sys.stdout.flush()
print "%%%", output, p_out.stderr.read()
print len(command_out_list)
if p_out.stderr.read():
logger.error("\"%s\" Error happened while trying to execute \"%s\"" (p_out.stderr.read().strip(), command))
sys.exit(1)
elif command_out_list[0] == '' and len(command_out_list) == 1:
logger.error("No Sessions belongs to %s campaign ID please provide proper input as Campaign ID" %id)
sys.exit(1)
else:
return command_out_list
我该如何解决这个问题?
TL;DR 您 subprocess.Popen()
的两个 电话都坏了;使用 subprocess
中的一种包装方法,and/or 使用 Python 的内置工具而不是外部工具。
您使用 useless use of cat
有什么特别的原因吗?只是 subprocess.Popen(['grep', id, uniqlog_file])
会简单得多,而不需要 shell=True
—— 当然, Python 本身在读取文件和检查每行是否包含字符串方面非常出色。
def get_uniq_sessions(logger, id='1234', uniqlog_file='test.txt'):
matches = []
with open(uniqlog_file, 'r') as handle:
for line in handle:
if id in line:
matches.append(line)
return matches
您的函数可能不应该调用 sys.exit()
;相反,引发异常,或者只是 return None
—— 这样,调用代码可以决定如何处理错误和异常。
你剩下的 subprocess.Popen()
只是巧合,只要输出量有限。您可能应该改用 subprocess.call
,它的存在正是为了 运行 在受控条件下检查错误的子进程。
这里的关键观察是 Popen()
本身只是生成子进程。您需要与它交互并为它 wait()
以确保它成功并 return 其所有输出。 call
和 subprocess
module 中的各种 check_*
方法为您做这件事; Popen()
主要在您不再需要那些罐装包装纸的设施时很有用,但也有些难以正确处理,尤其是第一次。
tshark
命令不需要shell=True
,如果你自己把它拆成一个列表,然后排序并写入Python中的文件。如果输出文件的唯一目的是从 Python 再次打开它,我建议将原始输出读入 Python 字符串并在 Python.[= 中完成所有剩余处理33=]
def get_all_tshark_out(logger, tcpdump, port):
output = subprocess.check_output(['tshark', '-r', str(tcpdump),
'-odiameter.tcp.ports:{0}'.format(port), '-R',
'diameter.cmd.code == 272 and diameter.flags.request==0 '
'and !tcp.analysis.retransmission and diameter.flags.T == 0',
'-Tpdml', '-Tfields', '-ediameter.Session-Id'])
return sorted(output)
... 现在你的 get_uniq_sessions
函数基本上是一个单行函数:
session = [x for x in get_all_tshark_out() if '1234' in x]
我正在尝试使用 subprocess.Popen
到 运行 'cat test.txt | grep txt',但它不起作用。在我的代码中,我执行了 subprocess.Popen
命令两次。
1: First time I used it to run a tshark command which redirectes the command output to a text (test.txt) file (which works fine). (defined in function get_all_tshark_out in below code)
2: Second time used subprocess.Popen to run 'cat test.txt | grep txt' command to extract txt from this file to perform some validation. This didn't work for me. (defined in function get_uniq_sessions in below code)
为了确保不是因为缓冲区溢出,我也在刷新 stdout
,但没有得到任何帮助。下面是我的代码:
import subprocess
import logging
def get_all_tshark_out(logger, tcpdump, port):
command = """tshark -r "%s" -odiameter.tcp.ports:"%s" -R 'diameter.cmd.code == 272 and diameter.flags.request==0 and !tcp.analysis.retransmission and diameter.flags.T == 0' -Tpdml -Tfields -ediameter.Session-Id | sort > test.txt""" %(tcpdump, port)
p_out = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
sys.stdout.flush()
sys.stderr.flush()
return 1
def get_uniq_sessions(logger, id='1234', uniqlog_file='test.txt'):
command = "cat "+ uniqlog_file +" | grep "+ id
print command
p_out = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
print "PPPPP", p_out
output = p_out.stdout.read()
p_out.wait()
command_out_list = (output.strip().split("\n"))
sys.stdout.flush()
print "%%%", output, p_out.stderr.read()
print len(command_out_list)
if p_out.stderr.read():
logger.error("\"%s\" Error happened while trying to execute \"%s\"" (p_out.stderr.read().strip(), command))
sys.exit(1)
elif command_out_list[0] == '' and len(command_out_list) == 1:
logger.error("No Sessions belongs to %s campaign ID please provide proper input as Campaign ID" %id)
sys.exit(1)
else:
return command_out_list
我该如何解决这个问题?
TL;DR 您 subprocess.Popen()
的两个 电话都坏了;使用 subprocess
中的一种包装方法,and/or 使用 Python 的内置工具而不是外部工具。
您使用 useless use of cat
有什么特别的原因吗?只是 subprocess.Popen(['grep', id, uniqlog_file])
会简单得多,而不需要 shell=True
—— 当然, Python 本身在读取文件和检查每行是否包含字符串方面非常出色。
def get_uniq_sessions(logger, id='1234', uniqlog_file='test.txt'):
matches = []
with open(uniqlog_file, 'r') as handle:
for line in handle:
if id in line:
matches.append(line)
return matches
您的函数可能不应该调用 sys.exit()
;相反,引发异常,或者只是 return None
—— 这样,调用代码可以决定如何处理错误和异常。
你剩下的 subprocess.Popen()
只是巧合,只要输出量有限。您可能应该改用 subprocess.call
,它的存在正是为了 运行 在受控条件下检查错误的子进程。
这里的关键观察是 Popen()
本身只是生成子进程。您需要与它交互并为它 wait()
以确保它成功并 return 其所有输出。 call
和 subprocess
module 中的各种 check_*
方法为您做这件事; Popen()
主要在您不再需要那些罐装包装纸的设施时很有用,但也有些难以正确处理,尤其是第一次。
tshark
命令不需要shell=True
,如果你自己把它拆成一个列表,然后排序并写入Python中的文件。如果输出文件的唯一目的是从 Python 再次打开它,我建议将原始输出读入 Python 字符串并在 Python.[= 中完成所有剩余处理33=]
def get_all_tshark_out(logger, tcpdump, port):
output = subprocess.check_output(['tshark', '-r', str(tcpdump),
'-odiameter.tcp.ports:{0}'.format(port), '-R',
'diameter.cmd.code == 272 and diameter.flags.request==0 '
'and !tcp.analysis.retransmission and diameter.flags.T == 0',
'-Tpdml', '-Tfields', '-ediameter.Session-Id'])
return sorted(output)
... 现在你的 get_uniq_sessions
函数基本上是一个单行函数:
session = [x for x in get_all_tshark_out() if '1234' in x]