以下python脚本:
#!/usr/bin/env python
import os
cmd = "echo Hello world | cut -d' ' -f1"
test=os.system(cmd)
print(test)
Run Code Online (Sandbox Code Playgroud)
它运行正常(输出是Hello).但是当我使用subprocess模块时:
#!/usr/bin/env python
import subprocess
cmd = "echo Hello world | cut -d' ' -f1"
process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
test = process.communicate()[0]
print (test)
Run Code Online (Sandbox Code Playgroud)
不行.输出是Hello world | cut -d' ' -f1,我希望是唯一的Hello.我该如何纠正?
我看到一般来说,当我使用bash命令时,子进程模块会失败:
<cmd1> | <cmd2>
Run Code Online (Sandbox Code Playgroud)
这个:
echo Hello world | cut -d' ' -f1
Run Code Online (Sandbox Code Playgroud)
...实际上不是命令,它是shell脚本的一个片段.所以你需要让shell执行它.
您只需添加shell=True到Popen构造函数即可完成此操作.
文档解释了这是如何工作的.它还解释了在没有shell的情况下做同样事情的更好方法.例如:
p1 = Popen(['echo', 'Hello', 'world'], stdout=PIPE)
p2 = Popen(['cut', "-d' '", '-f1'], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()
test = p2.communicate()[0]
Run Code Online (Sandbox Code Playgroud)
同时,您几乎不想split在命令行上使用 - 事实上,您的示例显示了您不希望的确切原因:
>>> cmd = "echo Hello world | cut -d' ' -f1"
>>> cmd.split()
['echo', 'Hello', 'world', '|', 'cut', "-d'", "'", '-f1']
Run Code Online (Sandbox Code Playgroud)
请注意,它分为-d' '两个参数,-d'和'.
如果您正在使用shell=True,请不要尝试拆分参数; 只需传递一个字符串作为你的cmd:
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
Run Code Online (Sandbox Code Playgroud)
如果你没有使用shell,正确的方法是使用shlex模块:
>>> shlex.split(cmd)
['echo', 'Hello', 'world', '|', 'cut', '-d ', '-f1']
Run Code Online (Sandbox Code Playgroud)
请注意,"-d' '"转入"-d "这个时间.乍一看这看起来很奇怪,但事实上它确实是外壳会做什么,以及你想要什么; 该cut程序将获得一个空间作为d选项.(换句话说,引号是针对shell的,而不是针对shell运行的程序.)
(该shlex模块还有一个句柄quote功能,您可以将其用于完全相反的目的:从参数列表构建命令行shell=True.)
但是,通常最好只创建一个参数列表,而不是试图弄清楚如何创建一个字符串,在运行时shlex.split(),它将为您提供所需的列表.
| 归档时间: |
|
| 查看次数: |
2642 次 |
| 最近记录: |