无法在 python 中调用子进程"ls -l folder | wC语言 l"



我想使用调用子进程运行此命令

ls -l folder | wc -l

我在 Python 文件中的代码在这里:

subprocess.call(["ls","-l","folder","|","wc","-l"])

我收到如下错误消息:

ls: cannot access |: No such file or directory
ls: cannot access wc: No such file or directory

这就像命令|wc不能被调用子进程读取。

我该如何解决它?

使用字符串作为第一个参数尝试 shell 选项:

subprocess.call("ls -l folder | wc -l",shell=True)

尽管这有效,但请注意,不建议使用 shell=True,因为它可能会通过 shell 注入引入安全问题。

您可以通过将

一个进程的stdout与另一个进程的stdin连接来设置命令管道。在您的示例中,错误和最终输出将写入屏幕,因此我没有尝试重定向它们。这通常比communicate之类的东西更可取,因为它们不是等待一个程序完成再启动另一个程序(并承担将数据移动到父级的费用),而是并行运行。

import subprocess
p1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["wc","-l"], stdin=p1.stdout)
# close pipe in parent, its still open in children
p1.stdout.close()
p2.wait()
p1.wait()

您需要自己实现管道逻辑才能使其正常工作。

def piped_call(prog1, prog2):
  out, err = subprocess.call(prog1).communicate()
  if err:
    print(err)
    return None
  else:
    return subprocess.call(prog2).communicate(out)

您可以尝试使用子流程。PIPE,假设您想避免使用 subprocess.call(..., shell=True) .

import subprocess
# Run 'ls', sending output to a PIPE (shell equiv.: ls -l | ... )
ls = subprocess.Popen('ls -l folder'.split(),
                      stdout=subprocess.PIPE)
# Read output from 'ls' as input to 'wc' (shell equiv.: ... | wc -l)
wc = subprocess.Popen('wc -l'.split(), 
                      stdin=ls.stdout, 
                      stdout=subprocess.PIPE)
# Trap stdout and stderr from 'wc'
out, err = wc.communicate()
if err:
    print(err.strip())
if out:
    print(out.strip())

对于 Python 3,请记住,此处使用的 communicate() 方法将返回一个 byte 对象而不是一个字符串。

在这种情况下,您需要使用 decode() 将输出转换为字符串:

if err:
    print(err.strip().decode())
if out:
    print(out.strip().decode())

最新更新