如何在Bash中让进程将自身输出重定向为输入?FIFO脚本问题求助
解决程序输出重定向为自身输入的FIFO脚本问题
我来帮你拆解下你这个FIFO脚本的问题,然后给出可行的改进方案~
首先还原你的需求:你想让一个从stdin读、向stdout写的程序,在执行期间把自身输出当成输入,而且不想用expect工具。你尝试用FIFO实现,但脚本有阻塞或异常问题,你的原脚本是:
mkfifo fifo echo "Initial input" > fifo cat fifo | ./my_program > fifo rm -rf fifo
原脚本的核心问题
你的脚本里有两个致命的逻辑问题:
echo命令会无限阻塞:FIFO的特性是「写入操作必须等到有进程打开读端才会完成」,你先执行echo "Initial input" > fifo,此时还没有任何进程打开fifo的读端,所以这个echo会一直卡住,后面的cat和程序根本没机会启动。- 数据流逻辑混乱+清理时机错误:就算解决了阻塞,
cat fifo | ./my_program > fifo的结构里,cat读取fifo内容传给程序,程序又把输出写回fifo,这种串行链路很容易出现数据丢失或死锁;而且rm命令在程序未执行完就删除FIFO,会导致后续IO操作直接失败。
正确的实现方案
要实现「程序输出闭环为自身输入」,关键是先让程序同时打开FIFO的读端和写端,再写入初始输入,这样就能避免阻塞,同时形成完整的数据流闭环。
基础版本脚本
# 创建FIFO管道 mkfifo myfifo # 后台启动程序,将stdin和stdout都绑定到FIFO ./my_program < myfifo > myfifo & # 写入初始输入(此时程序已经打开了FIFO的读端,echo不会阻塞) echo "Initial input" > myfifo # 等待程序执行完毕,再清理FIFO wait rm myfifo
优化版本(解决缓冲问题)
如果你的程序是带缓冲输出的(比如C/C++程序默认会缓冲stdout),可能会出现输出无法实时回传到输入的情况,这时候需要禁用IO缓冲:
mkfifo myfifo # 用stdbuf关闭stdin和stdout的缓冲,确保数据实时传输 stdbuf -i0 -o0 ./my_program < myfifo > myfifo & echo "Initial input" > myfifo wait rm myfifo
方案原理说明
- 先后台启动程序,让程序同时打开
myfifo作为stdin(读端)和stdout(写端),此时FIFO的读写端都处于活跃状态,后续写入操作不会阻塞。 - 写入初始输入到FIFO,程序会立即读取到这个输入并处理,处理后的输出又写回FIFO,形成「输入→处理→输出→输入」的闭环。
wait命令确保程序完全执行完毕后再删除FIFO,避免提前删除导致的IO错误。
内容的提问来源于stack exchange,提问作者samvel1024
相关产品推荐
相关产品推荐

