将 socat 分支的 stderr 重定向到单独的进程

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

我有一个通过 socat 访问的 python 程序,以便在客户端上提供并显示 stdin 和 stdout。我用:

socat TCP4-LISTEN:12345,reuseaddr,fork EXEC:"python prompt.py"

这按预期工作。 Prompt.py 显示 stderr 上的一些信息,这些信息显示在服务器端。相反,我希望将 stderr 发送到第三台服务器上的日志记录进程(因此不是连接到上述 socat 的客户端)。我可以使用以下命令按预期执行 stderr 部分(无需 socat):

python prompt.py 2> >(nc -q 0 logger 2323)

在这种情况下,我可以在运行此命令的终端上读取/回答提示,并且 stderr 转到正在运行的记录器:

socat TCP4-LISTEN:2323,reuseaddr,fork EXEC:"tee -a errors.txt"

并且errors.txt 按预期填满。但是当我尝试将这些与:

socat TCP4-LISTEN:12345,reuseaddr,fork EXEC:"python prompt.py 2> >(nc -q 0 logger 2323)",pty

python Prompt.py 的 stderr 未按预期发送;相反,它仍然显示在服务器上。我也尝试过:

socat TCP4-LISTEN:12345,reuseaddr,fork EXEC:"bash -c 'python prompt.py 2> >(nc -q 0 logger 2323)'"

这样,连接到 socat 时似乎什么也没有发生。为什么我的 bash 命令或 python 命令的 EXEC 不运行 stderr 重定向?有办法做到这一点吗?

我尝试重定向 socat 命令的 stderr;然而,这会打开并保持打开我不想要的数控连接。我希望每次运行 python 程序时打开然后关闭 nc 连接。

linux netcat socat
1个回答
0
投票

Socats EXEC 地址使用直接执行命令的 execvp() 系统调用。但是,您的各种重定向需要由 shell 来解释。

您可以尝试使用 system() 调用的 SYSTEM 地址,但它使用 /bin/sh 而不是 bash(或任何其他现代 shell),并且只能理解简单的重定向,例如 ">" 或 ">2"

有两种解决方法:

  1. 让 EXEC 显式调用 bash;然而,这需要转义引号和空格才能使 execvp() 参数正确:

socat TCP4-LISTEN:12345,reuseaddr,fork EXEC:"bash -c \\"python\ Prompt.py\ 2>\ >(nc\ -q\ 0\ logger\ 2323)\\"",pty

  1. 使用 SHELL 地址(Socat 1.8 中的新功能!),它隐式地执行 EXEC:“bash -c ...”技巧:

socat TCP4-LISTEN:12345,reuseaddr,fork SHELL:“python提示.py 2> >(nc -q 0 logger 2323)”,pty

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