我有一个很长的单行shell命令,将由Python调用。代码如下:
# "first way" def run_cmd ( command ): print "Run: %s" % command subprocess.call (command, shell=True) run_cmd('''sort -n -r -k5 {3} |head -n 500|awk 'OFS="\t"{{if($2-{1}>0){{print $1,$2-{1},$3+{1},$4,$5}}}}' > {2}'''.format(top_count,extend/2,mid,summit))
这些代码有效,但始终会这样抱怨:
sort: write failed: standard output: Broken pipe sort: write error awk: (FILENAME=- FNR=132) fatal: print to "standard output" failed (Broken pipe)
根据先前的答案,我需要使用更长的脚本来完成此操作,例如:
# "second way" p1 = Popen("sort -n -r -k5 %s"%summit, stdout=PIPE) p2 = Popen("head -n 500", stdin=p1.stdout, stdout=PIPE) # and so on ..........
我的问题是:
(1)“第二种方式”是否会比“第一种方式”慢
(2)如果无论如何我都必须以“第一种方式”写(因为这样写起来更快),如何避免这样的抱怨 broken pipe
broken pipe
(3)我不应该以“第一方式”写作的最令人信服的原因是什么
shell = True如果您的输入数据来自不受信任的来源,则使用可能会带来安全风险。例如,如果您的mid变量的内容是"/dev/null; rm -rf /"。在您的情况下似乎并非如此,因此我不必对此太担心。
shell = True
mid
"/dev/null; rm -rf /"
在代码中,您将结果awk直接写入中的文件名mid。要调试该问题,您可能需要使用subprocess.check_output并读取awkpython程序中调用的结果。
awk
subprocess.check_output
cmd = """sort -n -r -k5 %s | head -n 500| awk 'OFS="\t"{{if($2-{1}>0){{print $1,$2-{1},$3+{1},$4,$5}}}}'""".format(summit, top_count) subprocess.check_call(cmd, shell=True, stdout=file)