为什么这个管道脚本不起作用?

为什么这个管道脚本不起作用?
#!/bin/bash
rm out
mkfifo out
nc -l 8080 < out | while read line
do
    echo hello > out   
    echo $line
done

如果我浏览到运行此脚本的计算机的 IP(使用端口 8080),我希望看到单词“hello”,然后在运行脚本的计算机上,我希望它输出请求中的行。

然而,什么也没有发生。浏览器没有得到任何响应,服务器的终端也没有任何输出。

为什么它不起作用,我可以修改什么才能使它起作用?我想将其保留为简单的管道,我不想使用进程替换或类似的东西。

答案1

重定向< out导致命名管道打开以供读取。只要没有进程打开管道进行写入,就会阻塞。同时,管道的右侧在命令中阻塞read,等待nc(尚未启动)通过管道输出某些内容。它是僵局

要允许脚本继续运行,请确保命名管道打开以独立写入和读取。例如:

nc -l 8080 < out | while read line
do
    echo hello >&3
    echo "$line"
done 3>out

或者

nc -l 8080 < out | {
  exec 3>out
  while read line
  do
    echo hello >&3
    echo "$line"
  done
}

请注意,这样的东西是行不通的,因为nc会看到它的输入在读取 0 个字节后关闭,并且后续写入将阻塞等待命名管道再次打开以进行读取:

nc -l 8080 < out | {
  : >out
  while read line
  do
    echo hello >out
    echo "$line"
  done
}

相关内容