Ich habe gefundenHier entlangzu prüfen, ob ein Host auf einem bestimmten Port erreichbar ist. Mich interessiert jedoch nur der Statuscode des Befehls, deshalb versuche ich es mit etwas wie dem Folgenden:
[CptBartender@somewhere ~]$ <dev/tcp/host/port ; echo $?
0
Dies funktioniert einwandfrei, wenn ich es an einem offenen Port versuche. Wenn ich jedoch einen geschlossenen Port überprüfe, erhalte ich Folgendes:
[CptBartender@somewhere ~]$ <dev/tcp/host/blocked_port ; echo $?
-bash: connect: Connection refused
-bash: /dev/tcp/host/blocked_port: Connection refused
1
Mein nächster Schritt bestand nun darin, die Ausgaben des ersten Befehls zu verwerfen. Also habe ich Folgendes versucht:
[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
Dieselbe Ausgabe. Meine Fragen sind: Warum gibt der erste Befehl überhaupt eine Ausgabe aus und wie verhindere ich dies?
Antwort1
Es ist nicht dasBefehldas ist Druckausgabe. Sie haben nichtbeliebigBefehl – das < /dev/tcp/…
ist einfach normalEingabeumleitungund wird von der Shell selbst verarbeitet.
(Und nicht nur das, sondern Umleitungen werden von links nach rechts verarbeitet, so dass die <
Umleitung verarbeitet wirdVorder 2>&1
eine, also konnte es nicht umgeleitet werdenTrotzdem.)
Sie können dies umgehen, indem Sie den „Befehl“ in einer Subshell ausführen. Beispiel:
( </dev/tcp/$host/$port ) 2>/dev/null
Tatsächlich scheint in diesem Fall eine Subshell nicht erforderlich zu sein; eine Befehlsgruppe funktioniert auch, wenn sie sich innerhalb desselben Prozesses befindet – sie erzwingt dennoch, dass die „äußeren“ Umleitungen zuerst verarbeitet werden:
{ </dev/tcp/$host/$port; } 2>/dev/null
Randbemerkung: /dev/tcp
ist ein magischer Pfad, der von Bash selbst verwaltet wird – er existiert eigentlich nicht in /dev von Linux, kann aber mit Bash-Umleitungen verwendet werden. Dieser Trick funktioniert jedoch nicht mit #!/bin/sh
, und es besteht immer noch die Möglichkeit, dass er mit Bash auf einigen älteren Systemen (auf denen diese Funktion deaktiviert war) oder einigen Nicht-Linux-Systemen nicht funktioniert.