Subprocess.call中使用管道符|失效问题求助
解决subprocess中管道命令执行失败的问题
我来帮你搞定这个问题~你遇到的错误本质是管道符号|是Shell的专属功能,而默认情况下subprocess.call不会启动Shell来解析命令,导致shlex.split拆分后的管道符和后续命令被当成了ip命令的参数,自然会触发报错。
方案1:启用Shell解析(简单直接)
如果你的命令是固定内容、没有用户输入的部分,可以直接给call加上shell=True参数,让Shell帮你处理管道逻辑,这时候不需要用shlex.split:
#!/usr/bin/python from subprocess import call interface = call("ip -o link show | awk '{print $2}' | grep wl", shell=True)
⚠️ 注意:如果命令中包含用户可控的输入内容,shell=True会带来Shell注入风险,这种场景下不建议使用这个方案。
方案2:手动创建进程管道(更安全)
如果要规避Shell注入风险,可以用subprocess.Popen手动连接多个进程的输入输出,模拟Shell管道的效果:
#!/usr/bin/python from subprocess import Popen, PIPE # 启动第一个进程:执行ip命令,输出到管道 ip_process = Popen(["ip", "-o", "link", "show"], stdout=PIPE) # 启动第二个进程:awk处理ip的输出,结果再输出到管道 awk_process = Popen(["awk", "{print $2}"], stdin=ip_process.stdout, stdout=PIPE) ip_process.stdout.close() # 关闭ip进程的stdout,让它在awk结束时收到SIGPIPE # 启动第三个进程:grep筛选结果 grep_process = Popen(["grep", "wl"], stdin=awk_process.stdout, stdout=PIPE) awk_process.stdout.close() # 获取最终输出和返回码 result_output, _ = grep_process.communicate() return_code = grep_process.returncode
为什么你的原代码会报错?
shlex.split("ip -o link show | awk '{print $2}' | grep wl")会把整个命令拆成如下参数列表:
['ip', '-o', 'link', 'show', '|', 'awk', '{print $2}', '|', 'grep', 'wl']
subprocess.call会把这些参数全部传给ip命令,而ip根本不认识|和awk这些“非法参数”,所以才会抛出Error: either "dev" is duplicate, or "awk" is a garbage的错误。
内容的提问来源于stack exchange,提问作者Hayden Seward
相关产品推荐
相关产品推荐

