python 中的调用子进程 "ls -l folder | wc -l" 无法完成
Call subprocess "ls -l folder | wc -l" in python can't be done
我想运行这个命令使用调用子进程
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
不能被call subprocess读取。
我该如何解决?
尝试使用字符串作为第一个参数的 shell 选项:
subprocess.call("ls -l folder | wc -l",shell=True)
虽然这项工作有效,但请注意,不建议使用 shell=True
,因为它可能会通过 shell injection 引入安全问题。
您需要自己实现管道逻辑才能使其正常工作。
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.call(..., shell=True)
,您可以尝试使用 subprocess.PIPE。
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())
For Python 3 请记住这里使用的 communicate()
方法将 return 一个 byte
对象而不是一个字符串。 :
在这种情况下,您需要使用 decode()
:
将输出转换为字符串
if err:
print(err.strip().decode())
if out:
print(out.strip().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()
我想运行这个命令使用调用子进程
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
不能被call subprocess读取。
我该如何解决?
尝试使用字符串作为第一个参数的 shell 选项:
subprocess.call("ls -l folder | wc -l",shell=True)
虽然这项工作有效,但请注意,不建议使用 shell=True
,因为它可能会通过 shell injection 引入安全问题。
您需要自己实现管道逻辑才能使其正常工作。
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.call(..., shell=True)
,您可以尝试使用 subprocess.PIPE。
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())
For Python 3 请记住这里使用的 communicate()
方法将 return 一个 byte
对象而不是一个字符串。 :
在这种情况下,您需要使用 decode()
:
if err:
print(err.strip().decode())
if out:
print(out.strip().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()