Ich habe es endlich geschafft, ein Problem, mit dem ich seit ein paar Wochen zu kämpfen habe, zu lösen. Ich verwende SSH mit "autorisierten Schlüsseln", um Befehle aus der Ferne auszuführen. Alles ist in Ordnung, außer wenn ich es in einer while-Schleife mache. Die Schleife wird beendet, nachdem eine Iteration mit einem ssh-Befehl abgeschlossen wurde.
Lange Zeit dachte ich, dies sei eine Art von Seltsamkeit, aber jetzt stellte ich fest, dass sich Bash tatsächlich identisch verhält.
Ein kleines Beispielprogramm, um das Problem zu reproduzieren. Dies stammt aus einer größeren Implementierung, die Snapshots erstellt und diese auf die 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 der Ausdruck grep search ein TAB-Zeichen enthält, wie in der Definition des Verhaltens der Option "-H" der ZFS-Liste festgelegt.)
In meinem Beispiel gibt es einige ZFS-Dateisysteme für das Stammverzeichnis, in denen sich für alle "Zonen" das Root-Dateisystem in einem Dataset befindet, das dem folgenden ähnlich ist
POOL / zonen / app1zone
POOL / zonen / gruppe2 / app2zone
etc.
Die obige Schleife sollte einen Schnappschuss für jeden der ausgewählten Datensätze erstellen, funktioniert jedoch nur mit dem ersten und wird dann beendet.
Dass das Programm die richtige Anzahl von Datensätzen findet, kann leicht durch Überprüfen der Datei "/ tmp / actionlist" bestätigt werden, nachdem das Skript vorhanden ist.
Wenn der Befehl ssh beispielsweise durch einen Echo-Befehl ersetzt wird, durchläuft die Schleife alle Eingabezeilen. Oder mein Favorit - stelle "Echo" vor den beleidigenden Befehl.
Wenn ich stattdessen eine for-Schleife verwende, funktioniert dies ebenfalls. Aufgrund der potenziellen Größe der Liste der Datensätze kann dies jedoch zu Problemen mit der maximalen erweiterten Befehlszeilenlänge führen.
Ich bin mir jetzt zu 99,999% sicher, dass nur die Schleifen mit ssh-Befehlen Probleme bereiten!
Beachten Sie, dass die Iteration, in der der Befehl ssh ausgeführt wird, abgeschlossen ist! Es ist, als ob die in die while-Schleife eingespeisten Daten plötzlich verloren gehen ... Wenn die ersten Eingabezeilen keinen ssh-Befehl ausführen, wird die Schleife fortgesetzt, bis der SSH-Befehl tatsächlich ausgeführt wird.
Auf meinem Laptop, auf dem ich dies teste, habe ich zwei Solaris 10-VMs mit nur 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.
quelle
actionlist
. Versuchen Sie, die Standardeingabe von ssh auf/dev/null
Antworten:
SSH liest möglicherweise von der Standardeingabe und frisst Ihre Aktionsliste auf. Versuchen Sie, die Standardeingabe von ssh nach / dev / null umzuleiten:
Wenn
while read
ich Befehle ausführe, die die Standardeingabe unter einer -style-Schleife stören könnten , möchte ich den gesamten Schleifenkörper in geschweifte Klammern setzen:quelle
( </tmp/file [ -z "$SOMEVAR" ] && awk '{print "X", $0}' )
sich auch bei geschweiften Klammern unterscheidet. Ich meine in Bezug auf die produzierte Ausgabe, nicht über die Tatsache, dass die schließende geschweifte Klammer in einer neuen Zeile sein muss ...-n
Option, das stdin aus / dev / null (effektiv) wieder zu öffnen.sudo
mit dem Befehl in der Schleife?