$nc -vlkp 3000 Listening on [0.0.0.0] (family 0,port 3000)
在终端2上,我创建一个fifo并保留一只猫:
$mkfifo fifo $cat > fifo
在终端3上,我将fifo作为客户端netcat的输入:
$cat fifo | nc -v localhost 3000 Connection to localhost 3000 port [tcp/*] succeeded!
在4号航站楼,我发送任何我想要的东西:
$echo command1 > fifo $echo command2 > fifo $echo command3 > fifo
回到终端1,我看到收到的命令:
$nc -vlkp 3000 Listening on [0.0.0.0] (family 0,port 3000) Connection from [127.0.0.1] port 3000 [tcp/*] accepted (family 2,sport 41722) command1 command2 command3
一切顺利.但是当我把它放在脚本中时(我称之为fifo.sh),bash无法写入fifo:
在终端1上,同一个监听服务器:
$nc -vlkp 3000 Listening on [0.0.0.0] (family 0,我运行脚本:#!/bin/bash rm -f fifo mkfifo fifo cat > fifo & pid1=$! cat fifo | nc -v localhost 3000 & pid2=$! echo sending... echo comando1 > fifo echo comando2 > fifo echo comando3 > fifo kill -9 $pid1 $pid2终端2的输出是:
$./fifo.sh Connection to localhost 3000 port [tcp/*] succeeded! sending...在终端1上,我只看到连接.没有命令:
$nc -vlkp 3000 Listening on [0.0.0.0] (family 0,sport 42191) Connection closed,listening again.知道为什么它只能以交互方式工作吗?或者还有其他方法只使用Bash创建持久连接?我不想去Expect,因为我有一个更大的Bash脚本,它在发送command1之后做了一些工作,而command2依赖于command1输出等.
谢谢!
在这种情况下,当cat>对fifo进行求值,shell分析子进程,从/ dev / null重定向标准输入,并尝试打开fifo进行写入.这个孩子此时仍处于阻塞的公开电话中.请注意,在打开调用完成之后才会执行cat.
接下来,cat fifo |生成nc -v localhost 3000. cat打开fifo进行读取,这允许从第一个子节点打开阻塞并执行第一个cat.
第一个cat继承其父级的文件描述符,因此其标准输入附加到/ dev / null,因此它立即读取并发出EOF.第二只猫读取EOF并将其传递给nc的标准输入,这会导致netcat退出.
在评估echo语句时,$pid1和$pid2标识的进程已完成.由于fifo上不再有监听器,因此第一个echo将永远阻塞.
我没有纯shell修复,但您可以使用像perl这样的外部程序将占位符编写器打开到fifo而不是使用shell重定向.除此之外,请注意,在echo语句之后有一个nc的竞赛(在netcat有机会处理输入/发送输出之前发生了kill),所以这里我添加了一个延迟nc表达.几乎可以肯定有一个更好的解决方案,但这就是我想出的:
#!/bin/bash rm -f fifo mkfifo fifo perl -e 'open(my $fh,">","fifo"); sleep 3600 while 1' & pid1=$! cat fifo | nc -v localhost 3000 & pid2=$! sleep 2 echo sending... echo comando1 > fifo echo comando2 > fifo echo comando3 > fifo kill -9 $pid1 $pid2
希望这有帮助,很好的问题!