我想使用调用子进程运行此命令
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())