如何将 socat 的 stdin 和 stdout 重定向到其父进程(即 bash 脚本)?

问题描述 投票:0回答:1

我想做的事情应该相当简单,但我已经浪费了 5 个多小时尝试所有明显的事情......而且我一直在努力做我的作业......

这个问题似乎提出了正确的问题,但没有得到对我有帮助的答案。

我的目标是启动

socat
(首选)或
ncat
(也应该工作良好)的实例作为“服务器”,并具有双向流量方向 - stdin 和 stdout - 由 bash 脚本处理。

到目前为止我找到的最接近的是这个答案,但它没有做我想做的事。它将所有/所有 IO 都交给连接客户端,从而使其成为服务器...我喜欢它的是,它实际上以一种有用的方式重定向 stdin 和 stdout。因此,其中包含的想法很有趣,值得尝试,我也这么做了。

我也尝试过这个答案,这似乎也很有希望,但也不起作用。

作为我的测试用例的当前示例 - 我已经尝试了数百种变体但无济于事 - 是这样的:

#!/bin/bash
#

port=7654
inFile=/tmp/in
outFile=/tmp/out
logFile=/tmp/log

nohup tail -f $infile | /bin/socat TCP-LISTEN:$port,fork - > $outFile 2>$logFile &

while read line
do
   echo "user: $line"
   echo "$line" > "$inFile"
   tail -1 "$outFile"

done < /dev/stdin

当然,我不打算在真正的交互式会话中从键盘读取标准输入;这只是为了轻松地提供一些用于测试目的的实时操作。完成后,它将处理来自客户端的数据,如您所料!

在此示例中,通过上述传递的内容似乎不会被

socat
注意到,更不用说真正的客户了。客户端尝试发送的内容也无济于事,并且在两次尝试发送后,客户端(使用
ncat
)错误地显示“管道损坏。”

当然,当“手动运行”时,一切都很好。

我还尝试使用 < but it then won't start saying it doesn't have two connections specified.

重定向到 socat 的标准输入

关于上面的内容,我尝试过在管道中对命令进行分组,就像原始示例一样,但是

nohup
不会接受它,所以我猜测如果可以说服
nohup
运行一组命令,它可以工作,尽管我尝试了 () 和 {} 语法但一无所获。

我什至尝试过这个版本:

while read line
do
   echo "$line"
   echo "Back at you: $line" >&3

done < $( exec 3> >(ncat -l -k $port) )

考虑到下面菲利普的问题,这可能会有所帮助:

如果这种类型的事情有效,下面是最终代码的示例:

while read line
do
   # socat_stdin and socat_stdout are from the
   # point of view of an interactive session
   #
   # ...Process line based on it's contents.
   #
   # When a response is needed, stored in a variable
   # called reply, then this might happen:

   if [ -n "$reply" ] ;
   then
      echo "$reply" > socat_stdin
   fi
done < socat_stdout

...好吧,我到底该怎么做?

bash socat
1个回答
0
投票

我的目标是启动

socat
(首选)或
ncat
(也应该工作良好)的实例作为“服务器”,并具有双向流量方向 - stdin 和 stdout - 由 bash 脚本处理。

我认为您是在说您想要使用

socat
作为 shell 脚本的面向网络的前端。从网络连接到
socat
的客户端会将
socat
转发的数据发送到脚本的标准输入,脚本的标准输出将返回到
socat
转发到客户端。

我可以想到多种方法来实现这一目标,但最容易实现的可能是使用协进程。

#!/bin/bash

port=7654
logFile=/tmp/log

coproc echo_server { cat; }

/bin/socat TCP-LISTEN:$port,fork STDIO <${echo_server[0]} >${echo_server[1]} 2>$logFile

或者,您可以使用

socat
SYSTEM
EXEC
地址类型将其连接到脚本。 使用单独的脚本最容易做到这一点,但也可以仅使用一个脚本来完成:

#!/bin/bash

if ! [ $1 = --server ]; then
  port=7654
  logFile=/tmp/log

  exec /bin/socat TCP-LISTEN:$port,fork EXEC:"${BASH_SOURCE[0]} --server"
else
  # echo server
  cat
fi

此变体不依赖于特定于 Bash 的 shell 功能。

© www.soinside.com 2019 - 2024. All rights reserved.