为什么这不起作用:subprocess.Popen(["ls -l | grep myfile"], shell=False)
但这条线有效:subprocess.Popen(["ls -l | grep myfile"], shell=True)
我理解这个shell = True在内部创建一个子shell并执行命令。但是不明白这会如何影响Popen的行为
答案 0 :(得分:2)
Popen()使用子进程模块内的代码进行子进程管理。它不知道与|
的管道,并且它不知道你传递的字符串是一个程序还是一个参数,就像在ls
的示例中它会假设除ls
本身之外的所有其他内容都是该程序的参数。它将尝试执行列表中的第一项并将所有其他项作为参数传递。
当您使用shell=True
时,您可能会认为它(例如在UNIX上)与使用您作为字符串提供的arglist运行/bin/sh -c
。所以
Popen('ls -l | grep myfile', shell=True)
接近
Popen(['/bin/sh', '-c', 'ls -l | grep myfile'])
在这两种情况下,参数处理实际上都是由shell完成的。
对于管道和shell=False
,您应该使用子进程模块中提供的工具使用subprocess.PIPE
和stdout / stdin / stderr重定向。
答案 1 :(得分:0)
shell=True
用于将单个字符串作为命令行传递给shell。虽然技术上可以传递一个列表,但它可能永远不会是你想要的。
subprocess.Popen("ls -l | grep myfile", shell=True)
答案 2 :(得分:-1)
如果您使用shell=False
,则必须使用它:
subprocess.Popen(["ls","-l"],shell=False)