我發現了這邊走檢查主機是否可以在給定連接埠上訪問,但是我只對命令的狀態代碼感興趣,因此我嘗試這樣的操作:
[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/…
只是常規的輸入重定向並由外殼本身處理。
(不僅如此,重定向是從左到右處理的,因此<
重定向被處理前一個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。