bash脚本使用netcat与服务器连续通信运行卡顿问题求解
问题原因
你之前的写法存在两个核心问题:
- 每次通过管道给
nc传数据,nc在管道输入结束后会自动关闭连接,无法实现循环收发的长连接需求 - 第一种写法里的
read读的是终端输入而非nc的输出,会直接卡住;第二种写法要等nc完全退出才会把输出存入变量,也无法实现实时交互
解决方案
方案1:Bash 4.0+ 协程实现(推荐)
用bash自带的协程功能常驻nc进程,绑定其输入输出流实现持续读写:
#!/bin/bash BAGLANTI="替换为你的服务器地址" PORT="替换为服务端口" JOB_STRING="替换为首次要发送的内容" # 启动nc协程,保持连接常驻 coproc NC_PROC { nc "$BAGLANTI" "$PORT"; } # 首次发送初始数据 echo "$JOB_STRING" >&${NC_PROC[1]} # 循环执行读写逻辑 while true; do # 读取服务器返回内容,-r参数防止转义特殊字符 if read -r line <&${NC_PROC[0]}; then if [[ "$line" == "2.7" ]]; then echo "Sunucu Verisyonu $line" # 此处写对应场景要发给服务器的内容 echo "VERSION_RECV_OK" >&${NC_PROC[1]} else echo "İş geldi" # 此处写对应场景要发给服务器的内容 echo "JOB_RECV_OK" >&${NC_PROC[1]} fi else # 读取失败代表连接已断开,退出循环 echo "服务器连接已断开" break fi done # 清理进程 kill $NC_PROC_PID 2>/dev/null
方案2:低版本Bash 命名管道实现
如果bash版本不支持协程,可以用命名管道实现同样效果:
#!/bin/bash BAGLANTI="替换为你的服务器地址" PORT="替换为服务端口" JOB_STRING="替换为首次要发送的内容" # 创建两个命名管道分别处理输入输出 mkfifo nc_in nc_out # 后台启动nc,绑定输入输出到管道 nc "$BAGLANTI" "$PORT" < nc_in > nc_out & NC_PID=$! # 首次发送初始数据 echo "$JOB_STRING" > nc_in # 循环执行读写逻辑 while true; do if read -r line < nc_out; then if [[ "$line" == "2.7" ]]; then echo "Sunucu Verisyonu $line" # 此处写对应场景要发给服务器的内容 echo "VERSION_RECV_OK" > nc_in else echo "İş geldi" # 此处写对应场景要发给服务器的内容 echo "JOB_RECV_OK" > nc_in fi else echo "服务器连接已断开" break fi done # 清理资源 kill $NC_PID 2>/dev/null rm -f nc_in nc_out
注意事项
- 如果你用的是OpenBSD版本的netcat,启动nc时需要加
-q 0参数,避免发送完数据就自动断开连接 - 如果服务器返回的内容不带换行符,
read会一直阻塞,可以给read加超时参数,比如read -r -t 10 line表示10秒无响应就超时 - 你原来第二段代码的判断逻辑漏了比较符,正确写法是
[[ $RESPONSE == "2.7" ]]
内容的提问来源于stack exchange,提问作者mkursadulusoy
相关产品推荐
相关产品推荐

