Bash-Sequenz:Warten Sie auf die Ausgabe und starten Sie dann das nächste Programm
Frage
In meinem Fall muss ich rennen openvpn
bevor Sie per SSH auf einen Server zugreifen, und das openvpn
Der Befehl gibt „Initialisierungssequenz abgeschlossen“ aus.
Ich möchte also, dass mein Skript das einrichtet openvpn
und dann per SSH rein.
Meine Frage ist:Wie führt man einen Befehl in Bash im Hintergrund aus und wartet darauf, dass er „abgeschlossen“ zurückgibt, bevor man ein anderes Programm ausführt?
Meine aktuelle Vorgehensweise besteht darin, zwei Terminalfenster geöffnet zu haben, von denen eines Folgendes ausführt:
sudo openvpn --config FILE
und im anderen führe ich aus:
ssh SERVER
Sobald mir im ersten Terminalbereich der Text „Initialisierungssequenz abgeschlossen“ angezeigt wurde.
Lösung
Es scheint, als ob du es willst Führen Sie openvpn als Prozess im Hintergrund aus, während die Standardausgabe im Vordergrund verarbeitet wird.
exec 3< <(sudo openvpn --config FILE)
sed '/Initialization Sequence Completed$/q' <&3 ; cat <&3 &
# VPN initialization is now complete and running in the background
ssh SERVER
Erläuterung
Teilen wir es in Stücke:
echo <(sudo openvpn --config FILE)
werde so etwas ausdrucken/dev/fd63
- Die
<(..)
läuft openvpn im Hintergrund und... - hängt seine Standardausgabe an einen Dateideskriptor an, der von ausgedruckt wird
echo
- Die
exec 3< /dev/fd63
- (Wo /dev/fd63 ist der aus Schritt 1 gedruckte Dateideskriptor)
- Dadurch wird die Shell angewiesen, den Dateideskriptor zu öffnen (/dev/fd63) zum Lesen, und...
- Machen Sie es im Dateideskriptor verfügbar
3
sed '/Initialization Sequence Completed$/q' <&3
- Jetzt rennen wir sed im Vordergrund, aber lassen Sie es aus dem Dateideskriptor lesen
3
wir haben gerade erst eröffnet - sobald sed sieht, dass die aktuelle Zeile mit „Initialization Sequence Completed“ endet, wird beendet (die /Q Teil)
- Jetzt rennen wir sed im Vordergrund, aber lassen Sie es aus dem Dateideskriptor lesen
cat <&3 &
- openvpn wird weiterhin in den Dateideskriptor schreiben
3
und schließlich blockieren, wenn nichts daraus gelesen wird - Um das zu verhindern, rennen wir Katze im Hintergrund, um den Rest der Ausgabe zu lesen
- openvpn wird weiterhin in den Dateideskriptor schreiben
Die Grundidee ist Laufen openvpn
im Hintergrund, aber erfassen Sie seine Ausgabe irgendwo, damit wir einen Befehl im Vordergrund ausführen können, der blockiert, bis er die magischen Worte „Initialisierungssequenz abgeschlossen“ liest.Der obige Code versucht, dies zu tun, ohne unübersichtliche temporäre Dateien zu erstellen. Eine einfachere Möglichkeit könnte jedoch darin bestehen, einfach eine temporäre Datei zu verwenden.
Andere Tipps
Verwenden -m 1
zusammen mit --line-buffered
in grep, um einen grep nach der ersten Übereinstimmung in einem kontinuierlichen Stream zu beenden.Das sollte funktionieren:
sudo openvpn --config FILE | grep -m "Initialization Sequence Completed" --line-buffered && ssh SERVER