我希望使用/dev/tcp/host/port psuedo-设备语法在bash中打开TCP套接字,但如果host/port端点没有侦听,则需要优雅地恢复。如果我所做的只是将数据发送到套接字,或者从套接字中提取数据,那么这很容易,因为我可以使用一次性重定向,即:
echo 'ping' 2> >(logger) >/dev/tcp/127.0.0.1/8080或者,从插座读取:
cat 2> >(logger) </dev/tcp/127.0.0.1/8080其中,logger是从stdin到syslog写入行的标准记录器。
问题是,在某些情况下,我需要向套接字写入请求并获得响应。因此,我需要使用exec为套接字打开一个文件描述符,但在本例中,捕获"-bash: connect: Connection redirect“错误更困难,因为我不希望重定向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等。我正在开发的项目 (这个bash问题出现的地方)源于对一个特定工具的速度有多慢的失望,这是因为它如何将所有的shell助手代理到外部(python)解释器。此外,如果可能的话,我想避免使用mkfifo。
发布于 2015-01-04 00:24:28
eval 'exec 3<>/dev/tcp/127.0.0.1/8080' 2> >(logger)或者,更好的原因是它没有破坏旧的文件描述符3:
eval 'exec {fd}<>/dev/tcp/127.0.0.1/8080' 2> >(logger)它使用最小的空闲文件描述符并将其分配给fd。
unset fd
eval 'exec {fd}<>/dev/tcp/127.0.0.1/8080' 2> >(logger)
if test $? != 0 # status of the last command - 0 if the connection succeeded
then
echo cannot open connection >&2
fi
# $? shows the last status only. Later you can check success this way:
if test -z "$fd"
then
echo could not open connection >&2 # past tense because it's later now
else
echo some data to transmit >&$fd
IFS= read -r just_on_line_of_response <&$fd
fi完成后,使用
exec {fd}>&-这也将起作用:
eval "exec $fd>&-"但这很不幸地失败了,再加上关闭了你的标准:
exec $fd>&-https://stackoverflow.com/questions/27760732
复制相似问题