无法使用 nohup 和 socat 捕获远程客户端数据

无法使用 nohup 和 socat 捕获远程客户端数据

我需要捕获socat在远程服务器上运行的详细和调试输出。

socat我可以在前台运行时实现上述操作:

$ socat -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log

然而,stdout.log如果上述操作nohup在后台运行,则不会收到任何输出

$ nohup socat -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log &

这是stderr.log我启动nohup socat上述版本之后的情况:

nohup: ignoring input
2024/03/24 20:06:22 socat[28360] I socat by Gerhard Rieger and contributors - see www.dest-unreach.org
2024/03/24 20:06:22 socat[28360] I This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)
2024/03/24 20:06:22 socat[28360] I This product includes software written by Tim Hudson ([email protected])
2024/03/24 20:06:22 socat[28360] I setting option "bind" to "0.0.0.0"
2024/03/24 20:06:22 socat[28360] I setting option "fork" to 1
2024/03/24 20:06:22 socat[28360] I setting option "so-reuseaddr" to 1
2024/03/24 20:06:22 socat[28360] I socket(2, 1, 6) -> 5
2024/03/24 20:06:22 socat[28360] W ioctl(5, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ...): Inappropriate ioctl for device
2024/03/24 20:06:22 socat[28360] I starting accept loop
2024/03/24 20:06:22 socat[28360] N listening on AF=2 0.0.0.0:8080

接下来我8080从 netcat 连接到端口,

$ nc localhost 8080

接下来就是stderr.log捕获的内容:

2024/03/24 20:06:59 socat[28360] I accept(5, {2, AF=2 127.0.0.1:37910}, 16) -> 6
2024/03/24 20:06:59 socat[28360] N accepting connection from AF=2 127.0.0.1:37910 on AF=2 127.0.0.1:8080
2024/03/24 20:06:59 socat[28360] I permitting connection from AF=2 127.0.0.1:37910
2024/03/24 20:06:59 socat[28360] N forked off child process 28563
2024/03/24 20:06:59 socat[28360] I close(6)
2024/03/24 20:06:59 socat[28360] I still listening
2024/03/24 20:06:59 socat[28360] N listening on AF=2 0.0.0.0:8080
2024/03/24 20:06:59 socat[28563] I just born: child process 28563
2024/03/24 20:06:59 socat[28563] I close(4)
2024/03/24 20:06:59 socat[28563] I close(3)
2024/03/24 20:06:59 socat[28563] I just born: child process 28563
2024/03/24 20:06:59 socat[28563] I close(5)
2024/03/24 20:06:59 socat[28563] N reading from and writing to stdio
2024/03/24 20:06:59 socat[28563] I resolved and opened all sock addresses
2024/03/24 20:06:59 socat[28563] N starting data transfer loop with FDs [6,6] and [0,1]
2024/03/24 20:06:59 socat[28563] E read(0, 0x60485184f000, 8192): Bad file descriptor
2024/03/24 20:06:59 socat[28563] N exit(1)
2024/03/24 20:06:59 socat[28563] I shutdown(6, 2)
2024/03/24 20:06:59 socat[28360] N childdied(): handling signal 17
2024/03/24 20:06:59 socat[28360] I childdied(signum=17)
2024/03/24 20:06:59 socat[28360] I childdied(17): cannot identify child 28563
2024/03/24 20:06:59 socat[28360] I waitpid(): child 28563 exited with status 1
2024/03/24 20:06:59 socat[28360] I waitpid(-1, {}, WNOHANG): No child processes
2024/03/24 20:06:59 socat[28360] I childdied() finished

接下来我在 netcat 终端中输入一些文本并按 ENTER。

然而问题是:不仅 netcat 退出,我stdout.log也看不到我输入的文本

除了阐明这里发生的事情之外,有人还能建议如何捕获nohup'ed的 stderr 和 stdoutsocat吗?本质上,我需要捕获-v-d -d -d输出stderr.log以及远程套接字客户端发送到 的任何和所有数据stdout.log

答案1

解释

这是关于 的标准输入socat

对于使用 在后台运行的命令&,基本上有两种可能性:

  • 如果在 shell 中禁用作业控制(这是脚本的默认设置),则命令的标准输入应被重定向(在执行任何明确的重定向之前)到/dev/null或等效文件。

  • 如果在 shell 中启用了作业控制(这是交互式使用中的默认设置),则命令的标准输入就是您期望的,因此它可能是终端。如果它是终端,后台的命令无法从中窃取输入;如果它尝试,它将获得 SIGTTIN。您仍然可以使用 和 将命令带到fg前台然后它可以从终端读取。

nohup它本身会将标准流重定向出终端,因此即使在后一种情况下,当socat后台或其任何子线程/线程/任何内容尝试从其标准输入读取时,都会立即收到 EOF 条件(或某些错误)。

您应该能够通过类似方式快速传递数据echo message | nc localhost 8080socat处理这个特定的连接应该在因其标准输入上的 EOF 而终止之前获取消息。


解决方案

如果您不想因为 的标准输入上的 EOF 而终止连接socat,请告诉工具不要从该地址读取。来自man 1 socat

-u使用单向模式。第一个地址仅用于读取,第二个地址仅用于写入[…]。

-U反向使用单向模式。第一个地址仅用于写入,第二个地址仅用于读取。

在您的情况下-(意思是STDIO)是第二个地址,因此您需要-u

nohup socat -u -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log &

相关内容