GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Ssh bewirkt, dass While-Schleife stoppt?

Ich habe es endlich geschafft, ein Problem einzukochen, mit dem ich seit einigen Wochen zu kämpfen habe. Ich verwende SSH mit „autorisierten Schlüsseln“, um Befehle remote auszuführen. Alles ist in Ordnung, außer wenn ich es in einer While-Schleife mache. Die Schleife endet nach Abschluss einer Iteration mit einem ssh-Befehl.

Lange Zeit dachte ich, das sei eine Art ksh-Verrücktheit, aber jetzt entdeckte ich, dass sich bash tatsächlich identisch verhält.

Ein kleines Beispielprogramm, um das Problem zu reproduzieren. Dies wird aus einer größeren Implementierung destilliert, die Snapshots erstellt und sie zwischen den Knoten in einem Cluster repliziert.

#!/bin/bash

set -x

IDTAG=".*zone"
MARKER="mark-$(date +%Y.%m.%d.%H.%M.%S)"
REMOTE_HOST=sol10-target
ZFSPARENT=rpool

ssh $REMOTE_HOST zfs list -t filesystem -rHo name,mounted $ZFSPARENT | grep "/$IDTAG    " > /tmp/actionlist

#for RMT_FILESYSTEM in $(cat /tmp/actionlist)
cat /tmp/actionlist | while read RMT_FILESYSTEM ISMOUNTED
do
   echo ${RMT_FILESYSTEM}@${MARKER}
   [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
   echo Remote Command Return Code: $?
done

(Beachten Sie, dass es gemäß der Definition des Verhaltens der zfs-Listenoption „-H“ ein TAB-Zeichen im grep-Suchausdruck gibt.)

Mein Beispiel hat einige ZFS-Dateisysteme für das Stammverzeichnis, wobei alle „Zonen“ ihr Stammdateisystem auf einem Datensatz haben, der ähnlich wie

benannt ist

POOL/Zonen/App1Zone
POOL/Zonen/Gruppe2/App2Zone

usw.

Die obige Schleife sollte einen Snapshot für jeden der ausgewählten Datensätze erstellen, aber stattdessen arbeitet sie nur mit dem ersten und wird dann beendet.

Dass das Programm die richtige Anzahl an Datensätzen findet, lässt sich leicht überprüfen, indem man die Datei „/tmp/actionlist“ überprüft, nachdem das Skript existiert.

Wird der ssh-Befehl beispielsweise durch einen echo-Befehl ersetzt, dann durchläuft die Schleife alle Eingabezeilen. Oder mein Favorit – stellen Sie dem anstößigen Befehl ein „Echo“ voran.

Wenn ich stattdessen eine for-Schleife verwende, funktioniert es auch, aber aufgrund der potenziellen Größe der Liste der Datensätze könnte dies Probleme mit der maximalen erweiterten Befehlszeilenlänge verursachen.

Ich bin mir jetzt zu 99,999 % sicher, dass nur Schleifen mit ssh-Befehlen Probleme bereiten!

Beachten Sie, dass die Iteration, in der der ssh-Befehl ausgeführt wird, abgeschlossen ist! Es ist, als ob die Daten, die in die while-Schleife geleitet werden, plötzlich verloren gehen … Wenn die ersten paar Eingabezeilen keinen ssh-Befehl ausführen, wird die Schleife fortgesetzt, bis sie tatsächlich den SSH-Befehl ausführt.

Auf meinem Laptop, auf dem ich das teste, habe ich zwei Solaris 10-VMs mit nur etwa zwei oder drei Beispieldatensätzen, aber das Gleiche passiert auf den großen SPARC-Systemen, auf denen dies live gehen soll, und es gibt viele Datensätze.

Verwandte:Wie ändere ich die Cron-Shell (sh zu bash)?

Akzeptierte Antwort:

SSH liest möglicherweise von der Standardeingabe und frisst Ihre Aktionsliste auf. Versuchen Sie, die Standardeingabe von ssh nach /dev/null:

umzuleiten
ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER} </dev/null

Als allgemeine Regel gilt:Beim Ausführen von Befehlen, die die Standardeingabe unter einem while read beeinträchtigen können -Stil-Schleife, ich mag es, den gesamten Schleifenkörper in geschweiften Klammern einzuschließen:

cat /tmp/uuoc | while read RMT_FILESYSTEM ISMOUNTED
do {
    echo ${RMT_FILESYSTEM}@${MARKER}
    [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
    echo Remote Command Return Code: $?
} < /dev/null; done

Linux
  1. Übergeben von Variablen im Remote-SSH-Befehl

  2. Linux Befehl remote ausführen

  3. SSH - So fügen Sie den Befehl -t in die Datei ~/.ssh/config ein

  4. Bash Loop - Wie stoppe ich die Schleife, wenn ich in einem Befehl Strg-C drücke?

  5. Linux-Befehl zum Warten auf das Hochfahren eines SSH-Servers

Bash-while-Schleife

SSH-Befehl

So übergeben Sie das Passwort an den SSH-Befehl in Linux

Die While-Schleife in Shell-Skripten

Verwendung von und in der Bash-While-Schleife

Wie man SSH Bruteforce stoppt/verhindert