我正在尝试将一些命令合并到一个python脚本中,我通常会在命令行(Ubuntu 14.04)中使用它来处理文件。
我尝试按照subprocess help page上的示例操作,但它遇到以下错误消息:
find: paths must precede expression: |
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
原因,我有点难以理解,如果我直接在控制台中输入它,它会正常运行。我怀疑解析参数的方法有问题,但是argv1
和argv2
的打印输出结果看起来像预期的(基于示例)。
import subprocess, shlex
cmd1 = "find . -name *.tgz | xargs -i pigz -dv {}"
cmd2 = "find . -name *.tar | xargs -i tar -xfv {} -C decompressed --wildcards '*B5.TIF' '*B6.TIF' '*B8.TIF' "
args1 = shlex.split(cmd1)
args2 = shlex.split(cmd2)
print args1
print args2
subprocess.call(args1)
subprocess.call(args2)
我尝试subprocess.call()
和subprocess.Popen()
的结果相同。任何建议都非常感谢。
答案 0 :(得分:1)
subprocess.Popen(args1,shell=True)
或subprocess.call(args1,shell=True)
shell=True
可以在Ubuntu 14.04上正常使用。
警告执行包含来自不受信任来源的未经过处理的输入的shell命令会使程序容易受到shell注入攻击,这是一个严重的安全漏洞,可能导致任意命令执行。出于这个原因,强烈建议不要使用shell = True ,其中命令字符串是从外部输入构建的:
答案 1 :(得分:1)
我相信您因为命令中的管道而遇到此错误。
你想要做这样的事情(这只适用于cmd1):
cmd1=`find . -name *.tgz | xargs -i pigz -dv {}`
# should instead be
p1 = subprocess.Popen(["find", ".", "-name", "*.tgz"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["xargs", "-i", "pigz", "-dv", "{}"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
有关详细信息,请阅读subprocess documentation。