开放端口
user@linux:~$ >/dev/tcp/127.0.0.1/8080 && echo open || echo closed
open
user@linux:~$
关闭端口
user@linux:~$ >/dev/tcp/127.0.0.1/8088 && echo open || echo closed
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/8088: Connection refused
closed
user@linux:~$
将 stderr 重定向到 /dev/null 不起作用
user@linux:~$ >/dev/tcp/127.0.0.1/8088 2>/dev/nul
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/8088: Connection refused
user@linux:~$
所需输出
user@linux:~$ >/dev/tcp/127.0.0.1/8088 && echo open || echo closed
closed
user@linux:~$
答案1
反转重定向的顺序并让我们bash
知道 stderr 应该在 stdin 之前
$ >/dev/tcp/127.0.0.1/8088 2>/dev/nul
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/8088: Connection refused
$ 2>/dev/null >/dev/tcp/127.0.0.1/8088 && echo open || echo closed
closed
$
第一个版本失败的原因是重定向是按照其出现的顺序进行处理的,因此>/dev/tcp/127.0.0.1/8088 2>/dev/null
当发生重定向到端口时,stderr 流还没有被重定向。您可以使用实用程序在诊断输出中清楚地看到相应的系统调用dup2()
以重定向 stderr(或在命令失败的情况下缺少重定向)strace
$ strace -e dup2,connect -f bash -c '>/dev/tcp/127.0.0.1/8088 2>/dev/null'
connect(3, {sa_family=AF_INET, sin_port=htons(8088), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/8088: Connection refused
+++ exited with 1 +++
$ strace -e dup2,connect -f bash -c '2>/dev/null >/dev/tcp/127.0.0.1/8088 '
dup2(3, 2) = 2
connect(3, {sa_family=AF_INET, sin_port=htons(8088), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)
dup2(10, 2) = 2
+++ exited with 1 +++
$