我正在尝试使用bash创建持久连接.在终端1上,我保持netcat作为服务器运行:
$ nc -vlkp 3000
Listening on [0.0.0.0] (family 0, port 3000)
Run Code Online (Sandbox Code Playgroud)
在终端2上,我创建了一个fifo并保留了一只猫:
$ mkfifo fifo
$ cat > fifo
Run Code Online (Sandbox Code Playgroud)
在终端3上,我将fifo作为客户端netcat的输入:
$ cat fifo | nc -v localhost 3000
Connection to localhost 3000 port [tcp/*] succeeded!
Run Code Online (Sandbox Code Playgroud)
在4号航站楼,我发送任何我想要的东西:
$ echo command1 > fifo
$ echo command2 > fifo
$ echo command3 > fifo
Run Code Online (Sandbox Code Playgroud)
回到终端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
Run Code Online (Sandbox Code Playgroud)
一切顺利.但是当我把它放在脚本中时(我称之为fifo.sh),bash无法写入fifo:
在终端1上,同一个监听服务器:
$ nc -vlkp 3000
Listening on [0.0.0.0] (family 0, port 3000)
Run Code Online (Sandbox Code Playgroud)
在终端2上,我运行脚本:
#!/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
Run Code Online (Sandbox Code Playgroud)
终端2的输出是:
$ ./fifo.sh
Connection to localhost 3000 port [tcp/*] succeeded!
sending...
Run Code Online (Sandbox Code Playgroud)
在终端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 42191)
Connection closed, listening again.
Run Code Online (Sandbox Code Playgroud)
知道为什么它只能以交互方式工作吗?或者有没有其他方法只使用Bash创建持久连接?我不想去Expect,因为我有一个更大的Bash脚本,它在发送command1之后做了一些工作,而command2依赖于command1输出等.
谢谢!
当进程在脚本中的后台启动时,标准输入将从/dev/null. 这意味着第一个cat命令将在执行后立即读取并发出EOF,这将导致 netcat 在启动后立即退出,因此脚本中稍后的输出将永远不会到达 fifo,因为那里没有活动的侦听器时间。
在这种情况下,当cat > fifo进行求值时,shell 会分叉一个子进程,重定向来自 的标准输入/dev/null,并尝试打开fifo以进行写入。open此时孩子仍处于阻塞呼叫中。请注意,cat直到调用完成后才会执行open。
接下来,cat fifo | nc -v localhost 3000就是催生了。cat打开fifo以供读取,这允许第一个子级的阻塞open完成并cat执行第一个子级。
第一个cat继承了其父级的文件描述符,因此它的标准输入被附加到/dev/null,因此它立即读取并发出一个EOF。第二个cat读取EOF并将其传递到 的标准输入nc,这会导致 netcat 退出。
当语句被评估时,由和echo标识的过程就完成了。由于 上不再有侦听器,因此第一个侦听器将永远阻塞。$pid1$pid2fifoecho
我没有纯 shell 修复,但您可以使用 perl 等外部程序来打开占位符编写器,fifo而不是使用 shell 重定向。另外,请注意,在语句之后有一个nc开始的竞争echo(在killnetcat 有机会处理输入/发送输出之前发生),所以这里我在表达式之后添加了一个延迟cat | 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
Run Code Online (Sandbox Code Playgroud)
希望这有帮助,很好的问题!
| 归档时间: |
|
| 查看次数: |
1595 次 |
| 最近记录: |