我发现这边走检查主机是否可以在给定端口上访问,但我只对命令的状态代码感兴趣,因此我尝试执行以下操作:
[CptBartender@somewhere ~]$ <dev/tcp/host/port ; echo $?
0
如果我尝试在开放端口上工作,这可以正常工作,但是如果我检查关闭的端口,我会得到:
[CptBartender@somewhere ~]$ <dev/tcp/host/blocked_port ; echo $?
-bash: connect: Connection refused
-bash: /dev/tcp/host/blocked_port: Connection refused
1
现在我的下一步是尝试丢弃第一个命令的输出,所以我尝试:
[CptBartender@somewhere ~]$ <dev/tcp/host/blocked_port >/dev/null/ 2>&1; echo $?
-bash: connect: Connection refused
-bash: /dev/tcp/host/blocked_port: Connection refused
1
输出相同。我的问题是,为什么第一个命令会打印任何输出,我该如何阻止它这样做?
答案1
这不是命令这是打印输出。你不需要任何命令 –< /dev/tcp/…
只是常规输入重定向并由 shell 本身进行处理。
(不仅如此,重定向是从左到右处理的,因此<
重定向的处理方式是前一个2>&1
,所以无法重定向反正。
您可以通过在子 shell 中运行“命令”来解决此问题。例如:
( </dev/tcp/$host/$port ) 2>/dev/null
实际上,在这种情况下似乎不需要子 shell;即使在同一个进程中,命令组也会起作用 - 它仍然强制首先处理“外部”重定向:
{ </dev/tcp/$host/$port; } 2>/dev/null
附注:/dev/tcp
是 bash 本身处理的神奇路径 - 它实际上并不存在于 Linux 的 /dev 中,但可以与 bash 重定向一起使用。但是,此技巧不适用于#!/bin/sh
,并且在某些较旧的系统(过去禁用此功能)或某些非 Linux 系统上,它仍有可能无法与 bash 一起使用。