Linux FIFO读阻塞问题求助:Protostar net0练习命令行执行异常
解决Protostar net0练习中FIFO管道阻塞及数据格式问题
我来帮你排查并解决这个问题,你的命令主要存在两个核心问题:FIFO时序阻塞,以及二进制数据输出格式错误。
问题1:FIFO管道的阻塞原因
命名管道(FIFO)的核心特性是:当没有进程打开管道的写入端时,尝试读取管道的进程会一直阻塞。你的命令链中,cat /tmp/pipe会先启动并尝试读取管道,但此时负责写入管道的python ... > /tmp/pipe进程还没启动(它要等netcat输出数据才会被触发),这就导致cat卡在read操作上,整个命令链无法推进。
问题2:二进制数据输出错误
你用print struct.pack('I', int({}))输出二进制数据,但Python的print函数会自动在输出末尾添加换行符,这会导致你发送给服务器的数据多了一个额外的字节,破坏了要求的32位小端整数格式——即使管道不阻塞,服务器也不会正确识别你的回复。
修复后的解决方案
这里提供两种可靠的实现方式,你可以任选一种:
方案1:用Bash进程替换替代显式FIFO(推荐)
这种方式不需要手动创建FIFO,Bash会自动处理管道的读写时序,同时修正Python的输出问题:
netcat 127.0.0.1 2999 | tee -a /tmp/log | cut -d ' ' -f 3 | xargs -I{} python -c "import struct, sys; sys.stdout.write(struct.pack('<I', int({})))" | netcat 127.0.0.1 2999
注意:我把
'I'改成了'<I',显式指定小端序(虽然I在x86系统默认是小端,但显式声明更稳妥,避免跨平台问题)。
方案2:修正FIFO时序并修复数据输出
如果你坚持用FIFO,可以先打开写入端避免阻塞,同时修正Python的输出:
# 创建FIFO mkfifo /tmp/pipe # 先打开FIFO的写入端,避免读取端阻塞 exec 3> /tmp/pipe # 启动完整命令链,注意用sys.stdout.write输出原始二进制 cat /tmp/pipe | netcat 127.0.0.1 2999 | tee -a /tmp/log | cut -d ' ' -f 3 | xargs -I{} python -c "import struct, sys; sys.stdout.write(struct.pack('<I', int({})))" > /tmp/pipe # 执行完毕后关闭文件描述符 exec 3>&-
额外说明
如果你需要在同一个Netcat连接中完成收发(而不是两个独立连接),可以用Bash的协程(coproc)来实现双向通信:
coproc NC { netcat 127.0.0.1 2999; } while read -r line <&"${NC[0]}"; do num=$(echo "$line" | cut -d ' ' -f 3) python -c "import struct, sys; sys.stdout.write(struct.pack('<I', int($num)))" >&"${NC[1]}" done
这种方式更高效,也彻底避免了FIFO的时序问题。
内容的提问来源于stack exchange,提问作者dcnh35
相关产品推荐
相关产品推荐

