哪些 Linux shell 允许通过重定向器进行网络流量管理(向/从 `/dev/tcp/host/port` 发送/接收数据)?

Sop*_*rez 3 shell networking io-redirection

按照此Bash 教程,我已成功使用此方法获取发出简单命令网页代码:

$ exec 3<>/dev/tcp/www.google.com/80
$ echo -e "GET / HTTP/1.1\n\n" >&3
$ cat <&3
Run Code Online (Sandbox Code Playgroud)

确实,我得到了基本的 Google html 站点代码:

HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: http://www.google.es/?gfe_rd=cr&ei=HsiuVafkLpGt8weX7o-YAg
Content-Length: 258
Date: Tue, 21 Jul 2015 22:30:54 GMT
Server: GFE/2.0
Alternate-Protocol: 80:quic,p=0

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.es/?gfe_rd=cr&amp;ei=HsiuVafkLpGt8weX7o-YAg">here</A>.
</BODY></HTML>
Run Code Online (Sandbox Code Playgroud)

这个技巧对我很有用。比如我已经成功用它来发送Magic Packets(Wake on LAN)(类似的例子)。

哪些 shell 允许通过使用简单的命令和重定向程序将数据直接发送到网络?
当然,除了 Bash。

此信息用于了解这些系统是否具有此功能:

  • 带有嵌入式 Linux 的路由器
  • 常见的安卓外壳。
  • iOS (iPhone/iPad) 外壳。
  • 其他运行某种 Linux 的嵌入式设备(NAS、Compulab 的 Utilite、Odroid 等)。

Gil*_*il' 8

这是在 bash 2.04中添加的 ATT ksh93 的一个特性。其他常见 shell 都没有它,特别是在任何 dash 变体、pdksh 或 mksh(截至 2015 年 7 月)、任何 BusyBox 或 Android 变体或 zsh¹ 或fish 中都找不到它。可以在没有此功能的情况下编译 Bash(请参阅 参考资料--enable-net-redirections),因此即使嵌入式设备具有 bash,它也可能不存在。

要测试该功能是否存在,您可以在尝试打开丢弃服务的 TCP 端口时检查错误消息:bash 和 ksh 都说“连接被拒绝”(或者如果您本地有丢弃服务,则命令立即返回机器),如果这不尝试建立一些网络连接,你就不会看到。

: </dev/tcp/127.0.0.1/9
Run Code Online (Sandbox Code Playgroud)

这不是一个常见功能的一个原因是,许多网络协议需要双向通信,并仔细处理谁在何时谈话,哪些 shell 不太方便。另一个原因是对于简单的情况,涉及netcatsocatsocket 的管道也可以工作。这些程序处理二进制数据,可以是服务器也可以是客户端。大多数可以以简单方式处理的协议都有专门的工具,局域网唤醒除外。

echo -e "GET / HTTP/1.1\n\n" | nc www.google.com 80

echo -e "GET / HTTP/1.1\n\n" | socat - TCP:www.google.com:80
Run Code Online (Sandbox Code Playgroud)

socket实际上并不能用作 HTTP 客户端,因为它不会在输入结束时关闭连接的写入。)

对于脚本:

case $(export LANGUAGE=C LC_ALL=C; { : </dev/tcp/127.0.0.1/9; } 2>&1) in
  ""|*"Connection refused"*) echo "/dev/tcp is present";;
  *)
    if type nc >/dev/null 2>/dev/null; then
      echo "netcat is present"
    elif type socat >/dev/null 2>/dev/null; then
      echo "socat is present"
    else
      echo "I can't do TCP"
    fi
esac
Run Code Online (Sandbox Code Playgroud)

¹ Zsh 使用 UDP 和 TCP 套接字的方式不同。

  • @SopalajodeArrierez 没有内核标志,因为这与内核无关。我不认为有什么方便的方法。例如,Bash 没有设置变量来指示这一点。你可以运行类似`: &lt;/dev/tcp/localhost/99999` 的命令,看看你得到了什么错误消息(如果支持该功能,则“连接被拒绝”,如果不支持,则“没有这样的文件或目录”)。 (3认同)
  • Debian 不久前使用 `--disable-net-redirections` 配置了 Bash。我喜欢讨论:[bash:PATCH 支持 TCP/UDP 服务名称](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=65172),[bash:网络重定向不起作用] (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=66352), [bash: /dev/tcp 应该默认启用](https://bugs.debian.org/cgi- bin/bugreport.cgi?bug=146464)。“这种功能不应该是 shell 的一部分,而是一个特殊的工具。这个工具已经存在多年了,它叫做 netcat。”:) (2认同)