• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst]bashscript ssh in For-schleife trotz server down

Hallo

hab ein Bash-script geschrieben dass sich per ssh auf verschiedene Server anmeldet und dort ein updatefile startet.
Leider habe ich nun das Problem das wenn ein Server down ist das script hängen bleibt und nicht die anderen Server abklapptert.

Ich möchte nun in das Script einbauen das vorher der Server auf onlinestatus überprüft wird oder dass ssh wenn der Server down ist einfach weitergeht zum nächsten Server.

Mir gefällt die Version mit dem status prüfen und nur dann die Funktion ausführen am besten.
Hat jemand einen Tipp wie man das in einem Bash-script sauber ausprogrammiert?

Hier mal der Code wie er in etwa aussieht.

Code:
For i in $HOSTS
do
ssh $i /usr/local/bin/updatescript
done
 
Meine Idee wäre:

Code:
if [ "hallo" = "`ssh -oConnectTimeout=2 $i 'echo hallo' 2>/dev/null`" ]
then
   echo Server online
  # deine Aktion
else
  echo Server offline
fi

Das würde nicht abfangen, wenn der Server während der Aktion offline geht.

Haveaniceday
 
Das funktioniert nicht. Entweder wenn es im then-ast ist wird der Server immer als offline gewertet selbst wenn er online ist.
Und wenn ich im else Zweig die Aktion drin habe wird jeder Server als online gesehen und somit bleibt er wieder beim ssh-Befehl hängen.

wenn ich den ssh Befehl mit der Option -ConnectTimeout=2 eingebe meldet er ein "Bad configuration option connecttimeout"

Ich benutze Suse Linux 7.0 OpenSSH 2.1.1
 

framp

Moderator
Teammitglied
Wie wäre es mit
Code:
For i in $HOSTS
do
ping -c 1 -W 3 $1 1>/dev/null && ssh $i /usr/local/bin/updatescript
done

BTW: SuSE 7.0 ist schon lange out of Service. Ich würde mal auf OpenSUE 11.2 upgraden :roll:
 
Also in der if-Schleife gefällt mir das besser da ich dann eine Meldung auf den Bildschirm bringen kann, anhand derer ich sehe welcher Server down ist.

Und zum weiteren habe ich vier scripte pro Server zu starten jedesmal den Ping davor zu machen ist unpraktisch...

Außerdem krieg ich invalid option für das große W.

Edit:
mit dem kleinen w funktionierts :-D

Würde mich noch über eine Lösung freuen die mir die if-then-else Funktion erlaubt zu nutzen.
Dann würde ich im else Zweig
Code:
else
echo "Server $i offline"
hinzufügen.
 

framp

Moderator
Teammitglied
Das geht natürlich auch ;)
Code:
HOSTS="192.168.0.5 192.168.0.3"
for i in $HOSTS; do
        ping -c 1 -W 3 $i 1>/dev/null
        if [ $? == 0 ]; then
                echo "$i is online"
                # ssh calls
        else
                echo "$i is offline"
        fi
done

Du hast meinen vorherigen Kommentar zu SuSE 7.0 gelesen?
 
Ja ich hab deinen Kommentar gelesen und hier steht auch schon ein neuer Server und es soll Suse 11.0 drauf kommen. Sobald ich etwas sicherer bin mit dem installieren und konfigurieren kommt auch der Server dran. Aber im moment haben wir ein laufendes System das nicht einfach mal so umgestellt werden kann.

Ich bin ja auch unzufrieden mit der Streuung hier gibt es Suse von 7.0 bis 11.0 das ist so nicht tragbar. Mein Ziel ist es alles möglichst auf 10.3 - 11.0 zu bringen. Vielleicht hole ich mir auch noch zur Serverinstallation das Suse 11.2.

Danke für den Code das kann ich aber erst später ausprobieren muss nämlich jetzt zu einer Schulung.

Edit:

Funktioniert alles prima.

Kann mir noch einer erklären was dieses 1>/dev/null bedeutet. Dabei weiss ich was /dev/null bedeutet aber warum wird das mit einer 1 oder 2 addressiert??
 

framp

Moderator
Teammitglied
Emanuele schrieb:
...Kann mir noch einer erklären was dieses 1>/dev/null bedeutet. Dabei weiss ich was /dev/null bedeutet aber warum wird das mit einer 1 oder 2 addressiert??
Programme haben zwei Ausgabekanäle:Einen für Fehlermeldungen (STDERR) und einen für normale Ausgaben (STDOUT). Alles was auf STDERR von dem Prgramm geschrieben wird kann man mit 2 umleiten - alles von STDOUT mit 1.

D.h. mit 1>/dev/null wird die normale Ausgabe vom ping in den Biteimer umgeleitet damit die Meldung nicht beim Aufruf des Scripts auf der Konsole ausgegeben wird. Mit 2>/dev/null würden alle Fehlermeldungen unterdückt. Eine Spezialität ist noch
2>&1. Damit wird gesagt, dass der Fehlerkanal auf den Standardausgabekanal umgeleitet wird. Es werden also sowohl die Fehlermeldungen als auch normalen Ausgaben auf Kanal 1 zusammengefasst.

Weitere Infos dazu: Einfach nach bash stdout stdin oder bash redirection googeln ;)
 
schon gegoogled. Aber so wie du es erklärt hast hab ich das viel besser verstanden. vor allem das mit 2>&1 das war doch sehr einfach aber vollkommen korrekt erklärt.
 
Oben