it-swarm.com.de

Befehl alle x Zeitintervalle im Terminal wiederholen?

Wie kann ich wiederholen einen Befehl in jedem Zeitintervall ausführen, damit ich Befehle für überprüfen oder überwachen Verzeichnisse ausführen kann?

Es ist kein Skript erforderlich, ich brauche nur einen einfachen Befehl, um im Terminal ausgeführt zu werden.

138
user239745

Sie können den Befehl watch verwenden. watch wird verwendet, um einen bestimmten Befehl in regelmäßigen Abständen auszuführen.

Öffnen Sie das Terminal und geben Sie Folgendes ein:

watch -n x <your command>

ändern Sie x in die gewünschte Zeit in Sekunden.

Um weitere Hilfe bei der Verwendung des Befehls watch und seiner Optionen zu erhalten, führen Sie man watch aus oder besuchen Sie diese Seite Link .

Zum Beispiel: Das Folgende listet alle 60er dasselbe auf Terminal, den Inhalt des Desktop-Verzeichnisses, damit Sie wissen, ob Änderungen vorgenommen wurden:

watch -n 60 ls -l ~/Desktop
213
nux

Sie können diesen Befehl auch im Terminal verwenden, abgesehen von der Antwort von nux:

while true; do <your_command>; sleep <interval_in_seconds>; done

Beispiel

while true; do ls; sleep 2; done

Dieser Befehl gibt die Ausgabe von ls im Abstand von 2 Sekunden aus.

Verwenden Ctrl+C um den Prozess zu stoppen.

Es gibt einige Nachteile von watch

  • Es können keine Alias-Befehle verwendet werden.
  • Wenn die Ausgabe eines Befehls ziemlich lang ist, funktioniert das Scrollen nicht richtig.
  • Es gibt einige Probleme, maximales Zeitintervall über einen bestimmten Wert einzustellen.
  • watch interpretiert ANSI-Farbsequenzen, die Escape-Zeichen mit der Option -c oder --color übergeben. Beispielsweise funktioniert die Ausgabe von pygmentize, schlägt jedoch für ls --color=auto fehl.

Unter den oben genannten Umständen kann dies als bessere Option erscheinen.

86
souravc

Ich wollte mich nur den Antworten von souravc und nux anschließen:

  1. Während watch unter Ubuntu einwandfrei funktioniert, möchten Sie vielleicht vermeiden, dass Ihr "Unix-fu" unter FreeBSD rein ist.
  2. _while true; do command; sleep SECONDS; done_ hat auch eine Einschränkung - Ihr Befehl ist möglicherweise schwerer zu töten, wenn Sie STRG + C verwenden. Vielleicht möchten Sie lieber while sleep SECONDS; do command; done - es ist nicht nur kürzer, sondern auch leichter zu unterbrechen. Die Einschränkung ist, dass es zuerst in den Ruhezustand wechselt und dann Ihren Befehl ausführt. Sie müssen also etwas SECONDS warten, bis der Befehl zum ersten Mal ausgeführt wird.
34
d33tah

Klingt nach der idealen Aufgabe für den Daemon cron, mit dem periodische Befehle ausgeführt werden können. Führen Sie den Befehl crontab -e aus, um die Cron-Konfiguration Ihres Benutzers zu bearbeiten. Sein Format ist in crontab (5) dokumentiert. Grundsätzlich haben Sie fünf zeitbezogene, durch Leerzeichen getrennte Felder, gefolgt von einem Befehl:

The time and date fields are:

       field          allowed values
       -----          --------------
       minute         0-59
       hour           0-23
       day of month   1-31
       month          1-12 (or names, see below)
       day of week    0-7 (0 or 7 is Sunday, or use names)

Wenn Sie beispielsweise jeden Dienstag, 11.00 Uhr, ein Python -Skript ausführen möchten:

0 11 * * 1 python ~/yourscript.py

Es gibt auch einige spezielle Namen, die die Zeit ersetzen, wie @reboot. Sehr hilfreich, wenn Sie ein temporäres Verzeichnis erstellen müssen. Aus meiner Crontab (aufgelistet mit crontab -l):

# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"
11
Lekensteyn

Wenn Sie das Dateisystem überwachen, ist inotifywait brillant und belastet Ihr System mit Sicherheit weniger.

Beispiel

In 1st Terminal geben Sie diesen Befehl ein:

$ inotifywait .

Dann in 2nd terminal, jeder Befehl, der das aktuelle Verzeichnis betrifft,

$ touch newfile

Dann wird in dem ursprünglichen Terminal inotifywait aufwachen und das Ereignis melden

./ CREATE newfile2

Oder in einer Schleife

$ while true ; do inotifywait . ; done
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ DELETE newfile
Setting up watches.  
Watches established.
./ CREATE,ISDIR newdir
Setting up watches.  
Watches established.
5
X Tian

sie können Crontab verwenden. Führen Sie den Befehl crontab -e aus, öffnen Sie ihn mit Ihrem bevorzugten Texteditor und fügen Sie diese Zeile hinzu

*/10 * * * *  /path-to-your-command

Dadurch wird Ihr Befehl alle 10 Minuten ausgeführt

* */4 * * *  /path-to-your-command

Dadurch wird Ihr Befehl alle 4 Stunden ausgeführt

Eine andere mögliche Lösung

$ ..some command...; for i in $(seq X); do $cmd; sleep Y; done

X Anzahl der Wiederholungen.

Y Wartezeit bis zur Wiederholung.

Beispiel

$ echo; for i in $(seq 5); do $cmd "This is echo number: $i"; sleep 1;done
4
Maythux

Sie können Ihren eigenen repeat Befehl erstellen, indem Sie die folgenden Schritte ausführen. Credits hier :

Öffnen Sie zuerst Ihre .bash_aliases -Datei:

$ xdg-open ~/.bash-aliases

Fügen Sie als zweites diese Zeilen am Ende der Datei ein und speichern Sie:

repeat() {
n=$1
shift
while [ $(( n -= 1 )) -ge 0 ]
do
    "[email protected]"
done
}

Drittens können Sie entweder Ihr Terminal schließen und wieder öffnen oder Folgendes eingeben:

$ source ~/.bash_aliases

Et voilà! Du kannst es jetzt so benutzen:

$ repeat 5 echo Hello World !!!

oder

$ repeat 5 ./myscript.sh
4
Blufter

Ein weiteres Problem bei dem oben vorgeschlagenen "Watch" -Ansatz besteht darin, dass das Ergebnis nur angezeigt wird, wenn der Vorgang abgeschlossen ist. "date; sleep 58; date" zeigt die 2 Daten erst nach 59 Sekunden an ... Wenn Sie etwas starten, das 4 Minuten läuft und langsam mehrere Seiten mit Inhalten anzeigt, werden Sie es nicht wirklich sehen.

Auf der anderen Seite besteht das Problem beim "while" -Ansatz darin, dass die Aufgabendauer nicht berücksichtigt wird.

while true; do script_that_take_between_10s_to_50s.sh; sleep 50; done

Mit diesem Befehl wird das Skript einmal alle Minuten ausgeführt, manchmal dauert es 1: 40 Minuten. Selbst wenn ein Cron es alle Minuten ausführen kann, ist dies hier nicht der Fall.

Um die Ausgabe auf der Shell zu sehen, während sie generiert wird, und auf die genaue Anforderungszeit zu warten, müssen Sie die Zeit davor und danach betrachten und eine Schleife mit der Zeit ausführen.

So etwas wie:

while ( true ); do
  echo Date starting `date`
  before=`date +%s`
  sleep `echo $(( ( RANDOM % 30 )  + 1 ))`
  echo Before waiting `date`
  after=`date +%s`
  DELAY=`echo "60-($after-$before)" | bc`
  sleep $DELAY
  echo Done waiting `date`
done

Dies gibt Folgendes aus:

Wie Sie sehen, wird der Befehl alle Minuten ausgeführt:

Date starting Mon Dec 14 15:49:34 EST 2015
Before waiting Mon Dec 14 15:49:52 EST 2015
Done waiting Mon Dec 14 15:50:34 EST 2015

Date starting Mon Dec 14 15:50:34 EST 2015
Before waiting Mon Dec 14 15:50:39 EST 2015
Done waiting Mon Dec 14 15:51:34 EST 2015

Ersetzen Sie also einfach den Befehl "sleep echo $(( ( RANDOM % 30 ) + 1 ))" durch einen beliebigen Befehl, der auf dem Terminal/der Shell genau jede Minute ausgeführt wird. Wenn Sie einen anderen Zeitplan wünschen, ändern Sie einfach die "60" Sekunden, je nachdem, was Sie benötigen.

Kürzere Version ohne die Debug-Zeilen:

while ( true ); do
  before=`date +%s`
  sleep `echo $(( ( RANDOM % 30 )  + 1 ))` # Place you command here
  after=`date +%s`
  DELAY=`echo "60-($after-$before)" | bc`
  sleep $DELAY
done
3
jmspaggi