将进程的标准输入和输出重定向到netcat

9
我有一个带有简单交互式命令行界面的嵌入式Linux应用程序。
我想从telnet(或网络)访问命令行。
但是,该进程应在开机时启动,并且只能有一个实例。因此,以下netcat命令不可选:
nc -l -p 4000 -e myapp

我能做到

nc -l -p 4000 | myapp

我想发送远程命令到myapp,但这样我看不到myapp的输出。

有没有办法将标准输入和标准输出都重定向到netcat?

谢谢。

4个回答

11

有没有办法将stdin和stdout都重定向到netcat?

socat是一种更高级的netcat工具,可以使用它重定向stdinstdout。例如:

socat TCP4-LISTEN:5556,reuseaddr,fork EXEC:"cat - /etc/redhat-release"

在上述代码中,cat 读取 stdin/etc/redhat-release 并将它们输出到 stdout 中。

然后尝试使用它:

$ echo "hello" | nc 127.0.0.1 5556
hello
Fedora release 22 (Twenty Two)

$ echo "hello 2" | nc 127.0.0.1 5556
hello 2
Fedora release 22 (Twenty Two)

使用您建议的命令,我的应用程序仅在客户端连接时启动(就像nc -e一样)。我希望能够在没有任何连接的情况下启动我的进程。 - Daniele Pallastrelli
@DanielePallastrelli,那么你的应用程序必须是一个TCP服务器。你不能(至少不容易)重定向正在运行进程的打开文件描述符。 - Maxim Egorushkin
嗯...当我启动我的应用程序时,我可以直接将stdin/out重定向到socat,socat则充当服务器。连接稍后可以到达。 - Daniele Pallastrelli
不需要重定向正在运行的进程的打开文件描述符:文件描述符可以从一开始就被重定向(例如到socat)。然后连接可以稍后到达。 - Daniele Pallastrelli
1
比其他方案要好得多。对我有用。10倍 :] - IdanB
酷,我可以用服务器命令获取客户端UDP端口:socat UDP4-LISTEN:5353,reuseaddr,fork EXEC:"bash -c (ss -tuwanp|grep 5353|grep ESTAB|awk '{print $6}')",以及客户端命令:nc -p 15443 -u server_ip 5353。 - diyism

9
我发现在使用Bash版本大于或等于4.0时,我可以使用coproc
#!/bin/bash

coproc myapp
nc -kl -p 4000 <&"${COPROC[0]}" >&"${COPROC[1]}"

编辑

我最终在我的CLI库中加入了一个Telnet服务器。你可以在GitHub上找到结果:https://github.com/daniele77/cli


好主意。<&"${COPROC[0]}" >&"${COPROC[1]}" 部分看起来是不必要的,因为 bash 已经为您完成了这个操作。应该只需要使用 2>&1stderr 重定向到 stdout 即可。 - Maxim Egorushkin

3
你可以使用ncat(来自nmap软件包:apt install nmap)来完成此操作,步骤如下:

ncat -lnvp 443 -e myapp

在应用程序中的每个printf(%s,str);之后不要忘记fflush(stdout);

冗长选项 --verbose 或 -v 是上述命令 (-lnvp) 中捕获 stderr 的选项。https://nmap.org/ncat/guide/ncat-output.html - Florian Bidabé

1

在阅读man nc时,我发现了这个技巧。

使用命名管道,可以将标准输入和标准输出都重定向到同一个应用程序。

示例:

# create named pipe
rm -f /tmp/f; mkfifo /tmp/f

# launch interactive 'sh' session redirected to/from listening nc
cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

从另一个终端执行:

nc localhost 1234 # connect to the listening nc
$
$
$ ls -lah
total 16K
drwxrwxr-x  43 ky   ky    12K Jun 17 01:31 .
drwxr-xr-x 123 ky   ky    12K Jun 17 01:35 ..

哦,它真的有效。如果您不介意将所有发送的数据保存在文件中,则可以使用文件而不是命名管道来实现此方法。像这样:

# create an empty file
echo -n '' > /tmp/session

# launch interactive 'sh' session redirected to/from listening nc
tail -f /tmp/session | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/session

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接