使用Python subprocess获取过滤后dmesg输出遇问题求助
Python subprocess 处理管道命令获取USB断开日志问题
问题场景
命令行执行dmesg | tail -100 | grep "USB disconnect"能正常获取USB设备断开的日志,但用Python的subprocess模块实现时遇到管道重定向问题:
- 仅传入
"dmesg"能获取完整日志,但带管道的命令无法正确返回结果。
尝试的代码
import subprocess args = ["dmesg | tail -100 | grep \042USB disconnect\042"] grep_rpt = str(subprocess.call(args[0x00], shell = True)) print(grep_rpt + ", " + str(len(grep_rpt))) args = ["dmesg", "|", "tail", "-100", "|", "grep", "\042USB disconnect\042"] shellCmd = subprocess.run(args, capture_output = True, text = True) grep_rpt = str(shellCmd.stdout) print(grep_rpt + ", " + str(len(grep_rpt)))
执行输出
[ 4197.327275] usb 1-1.3: USB disconnect, device number 19 [ 4329.665928] usb 1-1.3: USB disconnect, device number 20 [ 4645.282024] usb 1-1.3: USB disconnect, device number 21 [ 4729.497491] usb 1-1.3: USB disconnect, device number 22 [ 4961.154086] usb 1-1.3: USB disconnect, device number 23 [ 5090.165051] usb 1-1.3: USB disconnect, device number 24 [ 5181.803769] usb 1-1.3: USB disconnect, device number 25 [ 5620.543437] usb 1-1.3: USB disconnect, device number 26 [ 5831.722098] usb 1-1.3: USB disconnect, device number 27 [ 7350.416575] usb 1-1.3: USB disconnect, device number 28 [ 7507.328715] usb 1-1.3: USB disconnect, device number 29 0, 1 , 0
问题根因
- 第一种写法(
subprocess.call+shell=True):call方法仅返回命令的退出码(0表示执行成功),命令的实际输出会直接打印到终端,无法被捕获到变量中。 - 第二种写法(
subprocess.run拆分参数):管道符|是Shell的特殊语法,直接作为参数传给dmesg时,dmesg会把它当成普通的命令行参数处理,并不会触发管道功能,因此没有输出。
解决方案
方案1:用shell=True配合subprocess.run捕获输出
将完整的管道命令作为单个字符串传入,同时开启shell=True和输出捕获参数,直接获取命令结果:
import subprocess cmd = 'dmesg | tail -100 | grep "USB disconnect"' result = subprocess.run(cmd, shell=True, capture_output=True, text=True) if result.returncode == 0: print("捕获到的USB断开日志:") print(result.stdout) else: print("命令执行出错:", result.stderr)
方案2:不依赖Shell,手动实现管道(更安全)
避免shell=True的安全风险,通过多个subprocess实例依次传递输入输出,手动实现管道逻辑:
import subprocess # 执行dmesg获取原始日志 dmesg_proc = subprocess.run(["dmesg"], capture_output=True, text=True) # 将dmesg输出传给tail -100 tail_proc = subprocess.run(["tail", "-100"], input=dmesg_proc.stdout, capture_output=True, text=True) # 将tail输出传给grep过滤目标内容 grep_proc = subprocess.run(["grep", "USB disconnect"], input=tail_proc.stdout, capture_output=True, text=True) if grep_proc.returncode == 0: print("捕获到的USB断开日志:") print(grep_proc.stdout) else: print("未找到匹配日志或执行出错:", grep_proc.stderr)
内容的提问来源于stack exchange,提问作者Christopher Theriault
相关产品推荐
相关产品推荐

