Subprocess command shows FileNotFoundError: [Errno 2] No such file or directory

Subprocess command shows FileNotFoundError: [Errno 2] No such file or directory

我正在尝试 运行 shell 通过在下面的代码中使用子进程模块使用 python 命令,但我不知道为什么我的脚本会抛出如下错误.有人可以帮我解决我所缺少的吗?

根据上面的 Gordon - 默认情况下 Popen() 对待

sed 's/"/ /g'

作为命令的名称到 运行 而不是命令名称加一个参数。因此您需要执行以下操作之一:

p2 = subprocess.Popen(['sed', 's/"/ /g'], stdin=p1.stdout, stdout=subprocess.PIPE)

p2 = subprocess.Popen('sed \'s/"/ /g\'', stdin=p1.stdout, stdout=subprocess.PIPE, shell=True)

使用 shell=True 获取 Popen 函数将字符串拆分为包含命令和参数的列表。

另请注意,p0 是您的最后一个结果,但您调用了 p01.communicate()

你的命令还是错误的。如果您只想像 shell 那样 运行 这些命令,那么最简单的方法就是...使用 shell.

result = subprocess.run('''
# useless cat, but bear with
cat output3.txt |
sed 's/"/ /g' |
grep "shipOption" |
grep -v "getShipMethod" |
cut -d ',' -f2 |
sed 's/"//g' |
sort |
uniq -c |
sort -nr |
head -10
    ''',
    # Probably add these too
    check=True,
    capture_output=True,
    # We are using the shell for piping etc
    shell=True)

如果您想删除 shell=True 并手动 运行 所有这些过程,您必须了解 shell 的工作原理。特别是,您需要修复引号,以便 运行 的命令在 shell 处理句法引号后保留 的引号。

p1 = subprocess.Popen(['cat', 'output3.txt'], stdout=subprocess.PIPE)  # still useless
p2 = subprocess.Popen(['sed','s/"/ /g'], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(['grep', "shipOption"], stdin=p2.stdout,stdout=subprocess.PIPE)
p4 = subprocess.Popen(['grep', '-v', "getShipMethod"], stdin=p3.stdout, stdout=subprocess.PIPE)
p5 = subprocess.Popen(['cut', '-d', ',', '-f2'], stdin=p4.stdout, stdout=subprocess.PIPE)
p6 = subprocess.Popen(['sed', 's/"//g'],stdin=p5.stdout, stdout=subprocess.PIPE)
p7 = subprocess.Popen(['sort'], stdin=p6.stdout, stdout=subprocess.PIPE)
p8 = subprocess.Popen(['uniq', '-c'], stdin=p7.stdout, stdout=subprocess.PIPE)
p9 = subprocess.Popen(['sort', '-nr'], stdin=p8.stdout, stdout=subprocess.PIPE)
p0 = subprocess.Popen(['head', '-10'], stdin=p9.stdout, stdout=subprocess.PIPE)

请特别注意 sedgrep 的参数如何删除它们的外引号,以及我们如何在所有地方删除 shell=True。根据经验,如果 Popen(或其他 subprocess 方法)的第一个参数是列表,则不应使用 shell=True,反之亦然。 (在某些情况下,您可以将列表传递给 shell=True,但是......让我们甚至不开始去那里。)

不过,所有这些似乎都没有实际意义,因为 Python 可以出色地完成所有这些事情。

from collections import Counter

counts = Counter()
with open('output3.txt', 'r', encoding='utf-8') as lines:
    for line in lines:
        line = line.rstrip('\n').replace('"', ' ')
        if "shipOption" in line and "getShipMethod" not in line:
            field = line.split(',')[1].replace('"', '')
            counts[field] += 1
print(counts.most_common(10))

您可能希望将 rstripreplace 放在 if 中以避免不必要的工作。当然,可以对 shell 管道进行相同的重构。