Wiederholen Sie den Terminalbefehl bis zur angegebenen Ausgabe

8

Ich möchte einen Alias ​​definieren, der alle x Sekunden einen Befehl ausführt, bis ein zugrunde liegender Prozess eine bestimmte Ausgabe liefert. Dann sollte der Befehl nicht mehr ausgeführt werden.

Ist das möglich und wenn ja, wie? Hilfe wird sehr geschätzt.

Ich bin fast zufrieden mit

alias test1='while true; do <command>; sleep 1; done'

außer ich muss es manuell stoppen und kann es daher nicht dazu bringen, einen neuen Befehl auszuführen, sobald er fertig ist.

Der Grund für die Frage: Dropbox synchronisiert sich bei der Arbeit schlecht. Manchmal muss ich es neu starten. Ich möchte dies mit einem Befehl tun, der auch angibt, wann die Synchronisierung abgeschlossen ist, z. B. mit

alias drop='dropbox stop && dropbox start && while true; do dropbox status; sleep 1; done'

Ich möchte, dass die Wiederholung gestoppt wird, wenn Dropbox 'Up to date' ausgibt.

Rasmus
quelle

Antworten:

10

Legen Sie eine Bedingung für die while-Schleife fest

Wenn Sie ersetzen

while true

durch:

while [ "$(dropbox status)" != "Up to date" ]

es funktioniert so wie du es beschreibst.

Der Befehl

Das Stoppen / Starten Dropboxund Beenden nach Abschluss der Synchronisierung erfolgt dann wie folgt:

dropbox stop && dropbox start && while  [ "$(dropbox status)" != "Up to date" ]; do dropbox status; sleep 1; done

Oder besser (um eine Verdoppelung zu verhindern dropbox status):

dropbox stop && dropbox start && while  [ "$(dropbox status)" != "Up to date" ]; do echo "Updating"; sleep 1 ; done && echo "Finished"

Erläuterung

while truewartet auf eine Unterbrechungsbedingung innerhalb der Schleife (die niemals auftritt), while [ "$(dropbox status)" != "Up to date"unterbricht jedoch die Schleife, wenn sie dropbox status zurückkehrtUp to date

Jacob Vlijm
quelle
Vielen Dank! Ich habe mich für Ihren ersten Vorschlag entschieden. Ich mag den expliziten Status, den er bietet.
Rasmus
2
@Rasmus Immer glücklich, wenn es funktioniert :)
Jacob Vlijm
5

Verwenden Sie, wie Jacob sagt, die Bedingung für die Schleife. Ich schlage eine untilSchleife vor:

dropbox stop && dropbox start && 
until dropbox status | grep -q "Up to date";
do 
  sleep 1; 
done

untilwird ausgeführt, bis der Befehl true zurückgibt. dropbox statusDann enthält die Ausgabe Up to date.

muru
quelle
Danke, Muru! Die Verwendung des Befehls 'till' in Kombination mit 'grep' ist sehr informativ. Ich bin mir sicher, dass es für andere Dinge nützlich sein wird - im Moment habe ich mich für Jacobs erste Lösung entschieden, da mir der explizite Status gefällt, den sie bietet.
Rasmus
2
@Rasmus sicher. :) Nur ein Hinweis: Sie können den gleichen Test durch [ "$(dropbox status)" != "Up to date" ]mit until- ersetzen Sie einfach !=mit =. Im Wesentlichen untilist whilemit Engation.
Muru
Nochmals vielen Dank! Ich habe nur die Dinge geändert, um es auszuprobieren. Ich klatsche in die Hände - das ist eine sehr lustige Art, Dinge zu lernen!
Rasmus
1

Definieren Sie es als eine Funktion in Ihrem $HOME/.bashrc

syncDropBox()
{
dropbox stop && \
dropbox start && 
while true; 
do 
  STAT="$(dropbox status)"
  if [ "$STAT" = "Up to date"  ] ; then
  break # or add more commands to finilize the process
  fi
  sleep 1; 
done
}

Jetzt habe ich keine dropboxcmd-App. Je nachdem, wie der Status ausgegeben wird, können Sie sie mit AWKoder verarbeiten grep.

Beachten Sie jedoch, dass Sie die Ausgabe entweder auf Wert speichern oder die Ausgabe auf einen anderen Befehl umleiten und auswerten können. Sobald wir eine bestimmte Ausgabezeichenfolge erhalten - break

Sergiy Kolodyazhnyy
quelle
Danke, Serg. Dies ist eine interessante Alternative zum Definieren eines Alias ​​und funktioniert wie ein Zauber.
Rasmus