Ich suche nach einer schnellen und einfachen Methode, um ordnungsgemäß zu testen, ob ein bestimmter TCP-Port auf einem Remote-Server in einem Shell-Skript geöffnet ist.
Ich habe es geschafft, es mit dem Telnet-Befehl zu tun, und es funktioniert gut, wenn der Port geöffnet wird, aber es scheint keine Zeitüberschreitung zu geben, wenn es nicht ist und hängt einfach dort ...
Hier ist ein Beispiel:
l_TELNET=`echo "quit" | telnet $SERVER $PORT | grep "Escape character is"`
if [ "$?" -ne 0 ]; then
echo "Connection to $SERVER on port $PORT failed"
exit 1
else
echo "Connection to $SERVER on port $PORT succeeded"
exit 0
fi
Ich brauche entweder einen besseren Weg oder einen Weg, um Telnet zum Timeout zu zwingen, wenn es keine Verbindung in weniger als 8 Sekunden herstellt, und etwas zurückzugeben, das ich in Shell abfangen kann (Rückkehrcode oder String in stdout).
Ich kenne die Perl-Methode, die das IO :: Socket :: INET-Modul verwendet und ein erfolgreiches Skript geschrieben hat, das einen Port testet, möchte aber die Verwendung von Perl möglichst vermeiden.
Hinweis: Dies ist, was mein Server ausführt (wo ich dies ausführen muss)
SunOS 5.10 Generic_139556-08 i86pc i386 i86pc
Antworten:
Wie von B. Rhodes gezeigt,
nc
wird die Arbeit erledigen. Eine kompaktere Art, es zu verwenden:Auf diese Weise
nc
wird nur überprüft, ob der Port geöffnet ist, und bei Erfolg mit 0 und bei Fehler mit 1 beendet.Für eine schnelle interaktive Überprüfung (mit einer Zeitüberschreitung von 5 Sekunden):
quelle
-G#
, um ein Verbindungszeitlimit unabhängig von / zusätzlich zum-w#
Zeitlimit festzulegen, das im Grunde genommen als Lesezeitlimit fungiert.-z
Option zu erhalten. Vielleicht möchten Sie FolgendesEs ist einfach genug, mit den
-z
und-w TIMEOUT
Optionen zu arbeitennc
, aber nicht alle Systeme habennc
installiert. Wenn Sie eine ausreichend aktuelle Version von Bash haben, funktioniert dies:Was hier passiert, ist, dass
timeout
der Unterbefehl ausgeführt und beendet wird, wenn er nicht innerhalb des angegebenen Zeitlimits beendet wird (1 Sekunde im obigen Beispiel). In diesem Fallbash
handelt es sich um den Unterbefehl, der mithilfe seiner speziellen Behandlung / dev / tcp versucht, eine Verbindung zu dem angegebenen Server und Port herzustellen. Wennbash
die Verbindung innerhalb des Timeouts geöffnet werden kann,cat
wird sie sofort geschlossen (da sie von liest/dev/null
) und mit einem Statuscode beendet, der0
sich durchbash
und dann ausbreitettimeout
. Wennbash
vor dem angegebenen Zeitlimit ein Verbindungsfehler auftritt,bash
wird der Exit mit dem Exit-Code 1 beendet, dertimeout
ebenfalls zurückgegeben wird. Und wenn bash keine Verbindung herstellen kann und das angegebene Zeitlimit abläuft, danntimeout
wird tötenbash
und mit einem Status von 124 beenden.quelle
/dev/tcp
auf anderen Systemen als Linux verfügbar? Was ist insbesondere mit Macs?timeout
auch in FreeBSD nicht existiert, und auf meiner alten Ubuntu-Box ist es ein installierbares Paket, aber standardmäßig nicht vorhanden. Wäre großartig, wenn es eine Möglichkeit gäbe, dies allein in Bash zu tun, ohne Tools von Drittanbietern wie Timeout oder Netcat.timeout
dies Teil von GNU Coreutils zu sein scheint und auf Macs mit Homebrew installiert werden kann :brew install coreutils
. Es wird dann als verfügbar seingtimeout
.bash-2.04-devel
, obwohl möglicherweise Unterstützung für Hostnamen hinzugefügt wurdebash-2.05-alpha1
.Inhaltsverzeichnis:
timeout
nc
Mit Bash und
timeout
:Beachten Sie, dass
timeout
RHEL 6+ vorhanden sein sollte oder alternativ in GNU Coreutils 8.22 enthalten ist. Installieren Sie es unter MacOS mitbrew install coreutils
und verwenden Sie es alsgtimeout
.Befehl:
Wenn der Host und Port Parametrisierung, sollten Sie sie angeben , wie
${HOST}
und${PORT}
wie oben ist. Geben Sie sie nicht nur als$HOST
und an$PORT
, dh ohne die geschweiften Klammern. In diesem Fall funktioniert es nicht.Beispiel:
Erfolg:
Fehler:
Wenn Sie den Exit-Status von beibehalten müssen
bash
,Verwenden von
nc
:Beachten Sie, dass eine abwärts inkompatible Version von
nc
auf RHEL 7 installiert wird.Befehl:
Beachten Sie, dass der folgende Befehl insofern einzigartig ist, als er für RHEL 6 und 7 identisch ist. Nur die Installation und die Ausgabe unterscheiden sich.
RHEL 6 (nc-1,84):
Installation:
Beispiele:
Erfolg: Fehler:Wenn der Hostname mehreren IPs zugeordnet ist, durchläuft der obige fehlgeschlagene Befehl viele oder alle. Zum Beispiel:
RHEL 7 (nmap-ncat-6.40):
Installation:
Beispiele:
Erfolg: Fehler:Wenn der Hostname mehreren IPs zugeordnet ist, durchläuft der obige fehlgeschlagene Befehl viele oder alle. Zum Beispiel:
Bemerkungen:
Das Argument
-v
(--verbose
) und derecho $?
Befehl dienen natürlich nur zur Veranschaulichung.quelle
timeout 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
ist ein toller Punkt!2>&1
zu nicht Echo Statusresult_test=$(nc -w 2 $ip_addreess 80 </dev/null 2>&1 ; echo $?)
Mit können
netcat
Sie überprüfen, ob ein Port wie folgt geöffnet ist:Der Rückgabewert von
nc
ist erfolgreich, wenn der TCP-Port geöffnet wurde, und ein Fehler (normalerweise der Rückkehrcode 1), wenn die TCP-Verbindung nicht hergestellt werden konnte.Einige Versionen von
nc
hängen, wenn Sie dies versuchen, da sie die sendende Hälfte ihres Sockets auch nach dem Empfang des Dateiende von nicht schließen/dev/null
. Auf meinem eigenen Ubuntu-Laptop (18.04) bietet dienetcat-openbsd
von mir installierte Version von netcat eine Problemumgehung: Die-N
Option ist erforderlich, um ein sofortiges Ergebnis zu erzielen:quelle
nc
, die die-w
Flagge nicht unterstützen .-z
Unterstützung - funktioniert zum Beispiel unter RHEL / CentOS 7-w
ist er erforderlich. Andernfalls kann der Befehl bei Verwendung in einem Skript länger als zehn Sekunden hängen bleiben. Ich habe eine Antwort geschrieben , die enthält-w
.nc host port -w 2 && echo it works
nc -vz localhost 3306
. Es gibt eine ausführlichere Ausgabe. Versuchte es nur auf dem Mac.In Bash ist die Verwendung von Pseudogerätedateien für TCP / UDP-Verbindungen unkompliziert. Hier ist das Skript:
Testen:
Hier ist ein Einzeiler (Bash-Syntax):
Beachten Sie, dass einige Server durch eine Firewall vor SYN-Flood-Angriffen geschützt werden können, sodass möglicherweise ein TCP-Verbindungszeitlimit (~ 75 Sekunden) auftritt. Versuchen Sie Folgendes, um das Timeout-Problem zu umgehen:
Siehe: Wie kann das Zeitlimit für TCP connect () -Systemaufrufe verringert werden?
quelle
telnet canyouseeme.org 81
hängt auch. Dies wird durch Ihre Timeout-Limits gesteuert, die wahrscheinlich in Bash fest codiert sind. Siehe: Zeitlimit für TCP connect () -Systemaufrufe verringern .$SERVER
und$PORT
mit Klammern, zumindest${SERVER}
und${PORT}
.Ich brauchte eine flexiblere Lösung für die Arbeit an mehreren Git-Repositorys, also schrieb ich den folgenden Sh-Code basierend auf 1 und 2 . Sie können Ihre Serveradresse anstelle von gitlab.com und Ihren Port anstelle von 22 verwenden.
quelle
Wenn Sie ksh oder bash verwenden , unterstützen beide die E / A-Umleitung zu / von einem Socket mithilfe des Konstrukts / dev / tcp / IP / PORT . In dieser Korn - Shell Beispiel ich Umleiten no-op ( : ) STD-in aus der Steckdose:
Die Shell gibt einen Fehler aus, wenn der Socket nicht geöffnet ist:
Sie können dies daher als Test in einer if- Bedingung verwenden:
Das No-Op befindet sich in einer Subshell, sodass ich std-err wegwerfen kann, wenn die std-in-Umleitung fehlschlägt.
Ich benutze oft / dev / tcp, um die Verfügbarkeit einer Ressource über HTTP zu überprüfen:
Dieser Einzeiler öffnet den Dateideskriptor 9 zum Lesen und Schreiben in den Socket, druckt das HTTP-GET in den Socket und verwendet
cat
zum Lesen aus dem Socket.quelle
</dev/tcp/canyouseeme.org/80
und dann</dev/tcp/canyouseeme.org/81
.Während eine alte Frage, habe ich mich gerade mit einer Variante davon befasst, aber keine der Lösungen hier war anwendbar, also habe ich eine andere gefunden und füge sie für die Nachwelt hinzu. Ja, ich weiß, dass das OP sagte, dass sie sich dieser Option bewusst waren und sie nicht zu ihnen passte, aber für jeden, der danach folgt, könnte sie sich als nützlich erweisen.
In meinem Fall möchte ich die Verfügbarkeit eines lokalen
apt-cacher-ng
Dienstes aus einemdocker
Build testen . Das heißt, vor dem Test kann absolut nichts installiert werden. Neinnc
,nmap
,expect
,telnet
oderpython
.perl
ist jedoch zusammen mit den Kernbibliotheken vorhanden, daher habe ich Folgendes verwendet:quelle
In einigen Fällen, in denen Tools wie Curl, Telnet, NCONMAP nicht verfügbar sind, haben Sie mit wget immer noch eine Chance
quelle
Überprüfen Sie die Ports mit Bash
Beispiel
Der Port 22 ist offen
Code
quelle
Wenn Sie
nc
eine Version verwenden möchten, die diese unterstützt-z
, versuchen Sie Folgendes--send-only
:und mit Timeout:
und ohne DNS-Suche, wenn es sich um eine IP handelt:
Es gibt die Codes als
-z
basierend darauf zurück, ob eine Verbindung hergestellt werden kann oder nicht.quelle
Ich vermute, dass es für eine Antwort zu spät ist, und dies ist vielleicht keine gute, aber los geht's ...
Wie wäre es, wenn Sie es in eine while-Schleife mit einem Timer stecken? Ich bin eher ein Perl-Typ als Solaris, aber abhängig von der verwendeten Shell sollten Sie in der Lage sein, Folgendes zu tun:
Fügen Sie dann einfach ein Flag in die while-Schleife ein, damit Sie das Zeitlimit als Grund für den Fehler angeben können, wenn das Zeitlimit vor dem Abschluss abgelaufen ist.
Ich vermute, dass das Telnet auch einen Timeout-Schalter hat, aber ich denke, dass das oben genannte funktionieren wird.
quelle
Ich brauchte ein kurzes Skript, das in cron ausgeführt wurde und nicht ausgegeben wurde. Ich löse meine Probleme mit nmap
So führen Sie es aus Sie sollten nmap installieren, da es sich nicht um ein standardmäßig installiertes Paket handelt.
quelle
nmap
Die grepable Ausgabe kann auch nützlich sein-oG -
, um sie an stdout zu senden. (Der Grep müsste ein wenig modifiziert werden)Dies verwendet Telnet hinter den Kulissen und scheint unter Mac / Linux gut zu funktionieren. Netcat wird aufgrund der Unterschiede zwischen den Versionen unter Linux / Mac nicht verwendet, und dies funktioniert mit einer Standard-Mac-Installation.
Beispiel:
is_port_open.sh
quelle
Aufbauend auf der am höchsten bewerteten Antwort können Sie hier warten, bis zwei Ports geöffnet sind, mit einer Zeitüberschreitung. Beachten Sie die beiden Ports, die geöffnet sein müssen, 8890 und 1111, sowie die max_attempts (1 pro Sekunde).
quelle
nmap-ncat zum Testen auf einen lokalen Port, der noch nicht verwendet wird
quelle