Bash中多个不退出命令管道连接时Python readline挂起如何解决
问题原因
程序挂起是管道场景下的默认输出缓冲规则导致的,和Python脚本逻辑无关。
当grep的输出直接打印到终端时,默认走行缓冲模式:每匹配到一行内容就立即写入输出流,所以单独执行tail -f /tmp/myfile | grep abcde时,能实时看到匹配结果,命令也会持续等待新输入。
但当grep的输出通过管道传给下游程序时,会自动切换为块缓冲模式:不会逐行输出内容,而是要等内存里的输出缓冲区攒到固定大小(通常是4KB或8KB),才会把攒的内容一次性写到输出流。每次往文件里追加的单行匹配内容长度太短,根本填不满缓冲区,grep就一直不会把匹配到的行传给下游Python进程,sys.stdin.readline()拿不到输入自然会一直阻塞挂起。
可用解决方案
任选一种即可修复问题:
- 给grep添加
--line-buffered参数,强制它在管道场景下也使用行缓冲,修改后的完整命令:tail -f /tmp/myfile | grep --line-buffered abcde | python extract.py - 借助
stdbuf命令手动指定grep的标准输出使用行缓冲,不需要改grep的启动参数:
其中参数tail -f /tmp/myfile | stdbuf -oL grep abcde | python extract.py-oL的作用就是把对应命令的标准输出缓冲模式设置为行缓冲。
补充:你写的
extract.py逻辑没有问题,只要上游grep把匹配到的行内容刷入管道流,sys.stdin.readline()就能立刻读到内容并正常打印,不需要额外修改Python侧的代码或缓冲配置。
内容的提问来源于stack exchange,提问作者Not Dylan Burns
相关产品推荐
相关产品推荐

