如何从“">/dev/tcp/ip/port”中删除“连接被拒绝”行

如何从“">/dev/tcp/ip/port”中删除“连接被拒绝”行

开放端口

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 +++
$ 

相关内容