subprocess.Popen出错,命令行正常运行(错误:find: 路径必须在表达式之前)

0 投票
2 回答
537 浏览
提问于 2025-04-18 14:32

我正在尝试把一些命令放进一个Python脚本里,这些命令我通常会在命令行(Ubuntu 14.04)中使用来处理文件。

我试着按照subprocess帮助页面上的例子来做,但遇到了以下错误信息:

find: paths must precede expression: |
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

让我感到困惑的是,如果我直接在控制台输入这些命令,它们是可以正常执行的。我怀疑在解析参数时可能出现了问题,但我认为打印出来的argv1argv2的结果看起来是符合预期的(根据例子来看)。

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(),结果都是一样的。任何建议都非常感谢。

2 个回答

1

我在Ubuntu 14.04上使用 subprocess.Popen(args1,shell=True)subprocess.call(args1,shell=True) 都能正常工作。

警告:如果你执行的命令包含来自不可信来源的未经处理的输入,这样会让程序容易受到“命令注入”的攻击,这是一种严重的安全漏洞,可能导致任意命令被执行。因此,在 命令字符串是由外部输入构建的情况下,强烈不建议使用 shell=True

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文档

撰写回答