【发布时间】:2015-01-03 23:35:23
【问题描述】:
我想在 bash 中打开一个 TCP 套接字,使用 /dev/tcp/host/port psuedo-device syntax,但如果 host/port 端点没有监听,我需要正常恢复。如果我所做的只是向套接字发送数据或从中提取数据,这很容易,因为我可以使用一次性重定向,即:
echo 'ping' 2> >(logger) >/dev/tcp/127.0.0.1/8080
或者,从套接字读取:
cat 2> >(logger) </dev/tcp/127.0.0.1/8080
其中logger 是标准logger,它将行从标准输入写入系统日志。
问题是在某些情况下我需要向套接字写入请求并得到响应。所以我需要用exec为套接字打开一个文件描述符,但在这种情况下,捕获“-bash:连接:连接被拒绝”错误更难,因为我不想重定向shell中的所有输出,这就是 2> >(logger) 在 exec 上下文中使用时所做的事情。如果端点关闭(因为 bash 在打开套接字时遇到错误并重置所有重定向),以下内容非常有用,但如果能够建立连接,我的 shell 将变得非常无用。
exec 2> >(logger) 3<>/dev/tcp/127.0.0.1/8080
到目前为止,我想出的最佳解决方案如下,我打开一个指向原始 STDERR 的文件描述符 (fd 9),将 STDERR (fd 2) 重定向到我的记录器,打开 fd 上的套接字3,然后将fd 2设置回原来的STDERR,并关闭我的临时STDERR别名(fd 9)。
exec 9>&2 2> >(logger) 3<>/dev/tcp/127.0.0.1/8080 2>&9 9>&-
对于如此简单的事情,这似乎需要做很多工作。有没有办法告诉 bash 我想在 bash 运行 exec 命令时重定向 STDERR,而不是将重定向视为 exec 的文字参数?
请保留您的答案/建议仅限于 bash(最高 bash 4.3.30)。我知道telnet、netcat、socat 等。我正在研究的project 的想法(这个bash 问题出现的地方)源于对特定tool 有多慢的挫败感,这是由于它如何将所有 shell 助手代理到外部(python)解释器。另外,如果可能的话,我想避免使用mkfifo。
【问题讨论】:
标签: bash shell tcp io-redirection