如何在Plumbum中实现进程替换(如echo hi | tee >(gzip > /tmp/1) > /tmp/2)
在Plumbum里实现进程替换(并行分流处理输出)
没问题!完全get你不想重复跑那种巨耗时的find /、还想同时用两套过滤规则的需求——Plumbum确实能实现类似bash里>(...)进程替换的效果,而且根本不用碰mkfifo那套麻烦的临时管道,咱们直接用它的后台进程和管道重定向就能搞定。
核心逻辑拆解
bash里的tee >(command)本质是偷偷建了个匿名管道,让tee把输出同时写到stdout和这个管道里,管道另一端的命令就能并行处理内容。在Plumbum里,我们可以用这两步模拟:
- 先启动一个后台进程来处理其中一路输出(比如
grep hi > /tmp/grepped),拿到它的输入管道; - 再把主进程的输出通过
tee同时导向这个后台进程的输入和另一路目标(文件或其他命令)。
实战代码示例
模拟find / | tee >(grep hi > /tmp/grepped) > /tmp/nongrepped
直接上可运行的代码,注释讲得很清楚:
from plumbum import local, BG # 先定义好要用的命令和文件路径 find = local["find"]("/") tee = local["tee"] grep_hi = local["grep"]("hi") grepped_output = local.path("/tmp/grepped") nongrepped_output = local.path("/tmp/nongrepped") # 第一步:启动后台进程——让grep把匹配到的内容写到grepped_output,同时拿到它的输入管道 # BG标记表示让进程在后台跑,返回的Process对象里的stdin就是我们要的管道入口 grep_process = (grep_hi > grepped_output) & BG # 第二步:构建主命令链——find的输出传给tee,tee一边把内容写到nongrepped_output, # 另一边把内容喂给后台grep进程的输入管道 main_pipeline = find | tee(grep_process.stdin) > nongrepped_output # 执行主命令 main_pipeline() # 别忘了等后台的grep进程跑完,不然可能会有输出不完整的情况 grep_process.wait()
再试另一个例子:echo hi | tee >(gzip > /tmp/1) > /tmp/2
逻辑完全一致,只是把grep换成gzip而已:
from plumbum import local, BG echo = local["echo"]("hi") tee = local["tee"] gzip = local["gzip"] compressed_file = local.path("/tmp/1") plain_file = local.path("/tmp/2") # 后台启动gzip进程,输出到compressed_file gzip_process = (gzip > compressed_file) & BG # 主管道:echo的输出经tee分流到gzip的输入和plain_file main_pipeline = echo | tee(gzip_process.stdin) > plain_file main_pipeline() gzip_process.wait()
关键细节提醒
BG操作符:这是实现后台并行的核心,它让进程在后台运行,同时暴露stdin属性给我们,相当于bash进程替换里的匿名管道写入端。- 避免重复执行主进程:整个流程里
find /只跑一次,输出被实时分流到两个处理分支,完全满足你不想重复执行高开销命令的需求。 - 一定要等后台进程:主命令跑完后,必须调用
wait(),不然后台进程可能还没处理完就被终止,导致输出文件不完整。
这种方式完全不需要手动创建临时管道,Plumbum已经帮我们封装好了底层的管道操作,既简洁又安全,完美匹配你的需求~
内容的提问来源于stack exchange,提问作者d33tah
相关产品推荐
相关产品推荐

