调用子流程“;ls-l文件夹“wc-l”;在python中,can';不行

调用子流程“;ls-l文件夹“wc-l”;在python中,can';不行,python,subprocess,call,Python,Subprocess,Call,我想使用调用子进程运行此命令 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 如何修复它?请尝试使用字符串作为第

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

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
,因为它可能会通过引入安全问题。

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

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

您可以尝试使用subprocess.PIPE,假设您希望避免使用
subprocess.call(…,shell=True)

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

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


您可以通过连接一个进程的
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()

管子是贝壳的东西。shell将分叉两个子进程,并将第一个子进程的stdout管道化为第二个子进程的stdin。你需要自己实现这个逻辑。谢谢你,它工作得很好:)它没有返回预期的结果,只是这个错误已经让你明白了。第一个参数必须是字符串。现在应该工作了。Hy@ ReMrBurn如果这个或任何答案已经解决了你的问题,请考虑点击复选标记。这向更广泛的社区表明,你已经找到了一个解决方案,并给回答者和你自己带来了一些声誉。没有义务这样做。谢谢您的回答:)谢谢,仍在学习子流程:)谢谢您的回答:)
if err:
    print(err.strip().decode())
if out:
    print(out.strip().decode())
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()