通过 TCP 公开 awk(inetd、socat 等)

通过 TCP 公开 awk(inetd、socat 等)

我正在使用 awk,我想通过 TCP 套接字公开它。

起初我尝试过,但使用 micro inetd 失败了。考虑到问题可能出在处理回车符/换行符的方式上,我决定尝试切换到 socat。

通过 socat 使用远程命令非常简单:

socat TCP4-LISTEN:9000 EXEC:/bin/cat
socat TCP4-LISTEN:9000 SYSTEM:"/bin/python -i"

这两个工作

但是,当使用简单的 awk 命令尝试相同的操作时(例如 `awk '{print NR}' 来逐步计算收到的行数),当从同一台机器上的另一个 shell 与 socat 连接时,我没有得到任何信息。

我尝试了很多东西(其中一些因语法错误而失败,这对我来说有点晦涩。我什至无法尝试 strace socat 来查看到底正在执行什么,因为实际的命令执行被委托给 shell) :

socat TCP4-LISTEN:9000 SYSTEM:"/usr/bin/awk '{print NR}'"
socat TCP4-LISTEN:9000 SYSTEM:'/usr/bin/awk "{print NR}"'
socat TCP4-LISTEN:9000 SYSTEM:'/usr/bin/awk "{print\ NR}"'

我还创建了一个小脚本/tmp/testawk

#! /bin/sh
/usr/bin/awk '{print NR}'

(也有一个 exec 变体)

#! /bin/sh
exec /usr/bin/awk '{print NR}'

这两个都在本地工作,但是在调用时

socat TCP4-LISTEN:9000 EXEC:/tmp/testawk

它不会发回输出

认为问题可能是 stdin/stdout 句柄的继承和/或再次处理 crlf ...我也尝试过:

socat TCP4-LISTEN:9000 EXEC:/tmp/testawk,nofork
socat TCP4-LISTEN:9000,crnl EXEC:/tmp/testawk
socat TCP4-LISTEN:9000 EXEC:/tmp/testawk,crnl
socat TCP4-LISTEN:9000,crnl EXEC:/tmp/testawk,crnl

我发现还有人抱怨类似的问题,但显然它未能引起任何关注

知道出了什么问题吗?

答案1

awk 正在打印到标准输出,当它指向终端时,它是行缓冲的,如果不是,则完全缓冲;这意味着您应该在填充缓冲区后获得输出,即它已打印(例如)4KB。

您可以通过发送大量输出来测试这一点(例如使用 yes 程序);要修复你应该: - 取消缓冲 awk 的标准输出(参见例如https://unix.stackexchange.com/a/25375/63847) - 使用来自发送者的 shutdown(2) 系统调用(丑陋)

欢迎任何更好的解决方案

答案2

您可以告诉socat将 pty 与awk程序关联起来;这会强制awk以行缓冲模式运行,并且您会立即获得所需的响应。

下面是监听 9000 端口的命令行:

socat TCP4-LISTEN:9000 SYSTEM:'/tmp/awk.sh',pty,echo=0

这是脚本的内容/tmp/awk.sh

#!/usr/bin/awk -f
#
BEGIN   { print "This is the awk socket" }
        { print NR, $0 }
END     { print "All done" }

示例运行:

$ nc -vvv otherhost 9000
otherhost [192.168.1.15] 9000 (?) open
This is the awk socket
hello world
1       hello world
how are you
2       how are you
boo
3       boo
^C sent 28, rcvd 61

相关内容