Es gibt einen integrierten Unix-Befehl, repeat
dessen erstes Argument angibt, wie oft ein Befehl wiederholt werden soll, wobei der Befehl (mit allen Argumenten) durch die verbleibenden Argumente für angegeben wird repeat
.
Zum Beispiel,
% repeat 100 echo "I will not automate this punishment."
wird die angegebene Zeichenfolge 100 Mal wiedergeben und dann anhalten.
Ich hätte gerne einen ähnlichen Befehl - nennen wir es ihn forever
- der ähnlich funktioniert, mit der Ausnahme, dass das erste Argument die Anzahl der Sekunden angibt, die zwischen den Wiederholungen eine Pause eingelegt werden muss und der sich für immer wiederholt. Zum Beispiel,
% forever 5 echo "This will get echoed every 5 seconds forever and ever."
Ich dachte, ich würde fragen, ob so etwas existiert, bevor ich es schreibe. Ich weiß, es ist wie ein zweizeiliges Perl- oder Python-Skript, aber vielleicht gibt es eine Standardmethode dafür. Wenn nicht, können Sie eine Lösung in Ihrer bevorzugten Skriptsprache, Rosetta Stone, veröffentlichen .
PS: Vielleicht ist es eine bessere Möglichkeit, dies zu verallgemeinern repeat
, wenn Sie sowohl die Anzahl der Wiederholungen (-1 bedeutet unendlich) als auch die Anzahl der Sekunden zwischen den Wiederholungen angeben. Die obigen Beispiele würden dann werden:
% repeat 100 0 echo "I will not automate this punishment."
% repeat -1 5 echo "This will get echoed every 5 seconds forever."
quelle
type repeat
und lassen Sie mich wissen, woher kommt?repeat
ist ein eingebauter Befehl in csh und tcsh.Antworten:
Versuchen Sie den
watch
Befehl.Damit:
Der Befehl wird jede Sekunde ausgeführt (naja, technisch gesehen, jede Sekunde plus die Zeit, die für
command
die Ausführung benötigt wird, dawatch
(zumindest dieprocps
undbusybox
Implementierungen) nur eine Sekunde zwischen zwei Läufen voncommand
) für immer ruht.Möchten Sie den Befehl
exec
statt an übergebensh -c
, verwenden Sie die-x
Option:Unter macOS können Sie
watch
von Mac-Ports Folgendes erhalten :Oder Sie können es von Homebrew bekommen :
quelle
while true; do X; sleep Y; done
- das ist viel besser.cmdwatch
unter FreeBSD aufgerufen (von den Ports aus:)sysutils/cmdwatch
.Bash
while
+sleep
:Hier ist das Gleiche wie bei einem Einzeiler mit Kurzschrift (aus den Kommentaren unten):
Wird verwendet
;
, um Befehle zu trennen undsleep 1
für denwhile
Test zu verwenden, da immer true zurückgegeben wird. Sie können weitere Befehle in die Schleife einfügen - trennen Sie sie einfach mit;
quelle
sleep
nicht immer wahr zurück. Ī̲ verwendet solche Schleifen (wenn auch mit längerer Verzögerung), weil es eine Möglichkeit gibt, sie ordnungsgemäß zu beenden, indem der Schlafprozess abgebrochen wird.Dies ist nur eine kürzere Version anderer
while+sleep
Antworten. Wenn Sie diese Art von Aufgaben häufig ausführen, erspart dies Ihnen unnötiges Drücken von Tasten, und wenn Ihre Befehlszeile länger wird, ist dies ein bisschen einfacher. Aber dieser fängt mit dem Schlafen an.Dies ist im Allgemeinen nützlich, wenn Sie einer einzeiligen Ausgabe wie der Maschinenlast folgen müssen:
quelle
while clear; do date; command;sleep 5; done
while sleep
Kombination, spart Tastenanschläge!Ein Problem, das alle bisher veröffentlichten Antworten haben, ist, dass die Zeit, zu der der Befehl ausgeführt wird, abweichen kann. Wenn Sie beispielsweise einen
sleep 10
Befehl zwischen zwei Befehlen ausführen und die Ausführung des Befehls 2 Sekunden dauert, wird er alle 12 Sekunden ausgeführt. Wenn die Laufzeit unterschiedlich lang ist, kann die Laufzeit auf lange Sicht unvorhersehbar sein.Dies könnte genau das sein, was Sie wollen; Verwenden Sie in diesem Fall eine der anderen Lösungen, oder verwenden Sie diese, aber vereinfachen Sie den
sleep
Aufruf.Bei einer Auflösung von einer Minute werden Cron-Jobs zur angegebenen Zeit ausgeführt, unabhängig davon, wie lange die einzelnen Befehle dauern. (Tatsächlich wird ein neuer Cron-Job gestartet, auch wenn der vorherige noch ausgeführt wird.)
Hier ist ein einfaches Perl-Skript, das bis zum nächsten Intervall ruht. In einem Intervall von beispielsweise 10 Sekunden wird der Befehl möglicherweise um 12:34:00, 12:34:10, 12:34:20 usw. ausgeführt, selbst wenn die Befehl selbst dauert mehrere Sekunden. Wenn der Befehl länger als
interval
Sekunden ausgeführt wird, wird das nächste Intervall übersprungen (im Gegensatz zu cron). Das Intervall wird relativ zur Epoche berechnet, sodass um Mitternacht UTC ein Intervall von 86400 Sekunden (1 Tag) ausgeführt wird.quelle
while :; do sleep 1m & command; wait; done
wait
auf alle warten). Das lässt sich beheben, indem Siewait
auf "wait $!
Wo$!
ist die PID dessleep
Prozesses ?" Ändern . Poste dies als Antwort und ich stimme dem zu. In einer interaktiven Shell wird jedoch eine gewisse Fremdausgabe erzeugt.Ich denke, alle Antworten hier sind entweder zu kompliziert oder beantworten stattdessen eine andere Frage:
Die eigentliche Frage war:
Dies sind zwei sehr unterschiedliche Dinge, wenn der Befehl einige Zeit in Anspruch nimmt.
Nehmen Sie zum Beispiel das Skript
foo.sh
(stellen Sie sich vor, dies ist ein Programm, das einige Sekunden benötigt).Sie möchten dies jede Sekunde ausführen, und die meisten würden vorschlagen
watch -n1 ./foo.sh
, oderwhile sleep 1; do ./foo.sh; done
. Dies ergibt jedoch die Ausgabe:Welches ist nicht genau jede Sekunde ausgeführt. Selbst mit der
-p
Flagge istman watch
das Ergebnis dasselbe , wie auf der Seite vorgeschlagen.Eine einfache Möglichkeit, die gewünschte Aufgabe zu erledigen, besteht darin, den Befehl im Hintergrund auszuführen. Mit anderen Worten:
Und das ist alles was dazu gehört.
Du
sleep 0.5
könntest es alle 500 ms mit laufen lassen , oder was hast du.quelle
while :; do sleep 1 & ./foo.sh; wait; done
date +"%H:%M:%S.%N"
in foo.sh, um zu sehen, wie der Bruchteil in jeder Schleife langsam zunimmt.In
bash
:(
echo
Kann durch einen beliebigen Befehl ersetzt werden ...Oder in
perl
:Wo
print "I will not automate this punishment in absurdum.\n"
könnte mit "jedem" Befehl mit Backticks (`) ersetzt werden.Fügen Sie für eine Pause eine
sleep
Anweisung in die for-Schleife ein:und
quelle
while [ 0 ]
ist ein schlechter Weg, um es zu schreiben. Dies bedeutet, dass0
es sich um eine Zeichenfolge mit einer Länge> 0 handeltwhile [ 1 ]
oderwhile [ jeff ]
dasselbe tun würde. Besser schreibenwhile true
.while :
Letzte Bash> = 4.2 unter neueren Linux-Kernel, basierte Antwort.
Um die Ausführungszeit zu begrenzen, gibt es keine Gabeln ! Es werden nur eingebaute verwendet.
Dafür verwende
read
ich stattdessen die eingebaute Funktionsleep
. Leider funktioniert das nicht mit kleinen Sessions.Schnelle Bash- Funktion "
repeat
" wie gewünscht:Kleiner Test mit zitierten Strings:
Abhängig von der Granularität und Dauer des übermittelten Befehls ...
Unter neueren Linux-Kerneln gibt es ein Protokoll,
/proc/timer_list
das Zeitinformationen in Nanosekunden enthält.Wenn Sie einen Befehl genau einmal pro Sekunde ausführen möchten, muss der Befehl in weniger als einer Sekunde beendet sein! Und von dort müssen Sie
sleep
nur den Rest der aktuellen Sekunde.Wenn die Verzögerung wichtiger ist und Ihr Befehl keine nennenswerte Zeit benötigt, können Sie:
Wenn Sie jedoch eine feinere Granularität erzielen möchten, müssen Sie:
Verwenden Sie Nanosekunden-Informationen, um bis zum Beginn einer Sekunde zu warten ...
Dafür habe ich eine kleine Bash-Funktion geschrieben:
Nach der Beschaffung können Sie:
laufen
${command[@]}
direkt auf der Kommandozeile, als zu vergleichendies muss genau dasselbe Ergebnis liefern.
Stellt die Bash- Funktion "
repeat
" wie gewünscht ein:Sie könnten dies beziehen:
Dann probiere es aus:
quelle
read -t
ist ein eingebautes , währendsleep
es nicht ist. Dies könnte Randeffekte haben (dh das Drücken von [key: return] unterbricht leise den Schlaf ), aber dies könnte durch Testen$foo
Möchtest du das ausprobieren (Bash)?
quelle
repeat
ist spezifisch für csh und tcsh.Perl
quelle
Bash und einige seiner verwandten Shells haben die praktische
(( ... ))
Notation, in der arithmetische Ausdrücke ausgewertet werden können.Als Antwort auf Ihre dritte Herausforderung, bei der sowohl die Anzahl der Wiederholungen als auch die Verzögerung zwischen den einzelnen Wiederholungen konfigurierbar sein sollten, haben Sie folgende Möglichkeiten:
Diese Antwort leidet auch unter der Zeitverschiebung, die in Keiths Antwort behandelt wird .
quelle
Wie von gbrandt erwähnt, sollte der
watch
Befehl unbedingt verwendet werden , wenn er verfügbar ist. Auf einigen Unix-Systemen ist es jedoch nicht standardmäßig installiert (zumindest dort, wo ich arbeite).Hier ist eine andere Lösung mit leicht unterschiedlicher Syntax und Ausgabe (funktioniert in BASH und SH):
Bearbeiten: Ich habe einige "." in der letzten echo aussage ... holdover aus meinen perl tagen;)
quelle
while [ 1 ]
funktioniert nur, weil 1 wie ein String behandelt wirdwhile [ -n 1 ]
.while [ 0 ]
oderwhile [ jeff ]
würde das gleiche tun.while true
macht viel mehr Sinn.Wenn Sie keine Meldung auf Ihrem Bildschirm anzeigen möchten und es sich leisten können, den Auftrag in Minuten zu wiederholen, ist crontab möglicherweise das beste Werkzeug. Wenn Sie beispielsweise Ihren Befehl jede Minute ausführen möchten, schreiben Sie Folgendes in Ihre
crontab
Datei:Bitte schauen Sie sich das Tutorial für weitere Beispiele an. Sie können die Timings auch einfach mit Crontab Code Generator einstellen .
quelle
Was wäre, wenn wir beide hätten?
Hier ist die Idee: Mit nur "Intervall" wird es für immer wiederholt. Mit "Intervall" und "Zeiten" wird diese Anzahl von Malen wiederholt, getrennt durch "Intervall".
Die Verwendung :
Der Algorithmus lautet also:
Deshalb :
quelle
sleep
sie akzeptiert werden.Am Ende habe ich eine Variante der Antwort von swalog erstellt. Mit seiner musste man X Sekunden auf die erste Iteration warten, ich renne auch meine so in den Vordergrund ..
quelle
Schnell, schmutzig und wahrscheinlich gefährlich zu booten, aber wenn Sie abenteuerlustig sind und wissen, was Sie tun, setzen Sie dies in
repeat.sh
undchmod 755
es,Rufe es mit auf
./repeat.sh <command> <interval>
Mein spidey sense sagt, dass dies wahrscheinlich ein böser Weg ist, mein spidey sense richtig?
quelle
sleep $1; shift; "$@"
oder ähnliches wäre viel besser.Sie können ein Skript von init ausführen (indem Sie eine Zeile zu / etc / inittab hinzufügen). Dieses Skript muss Ihren Befehl ausführen, sich für die Zeit, die Sie warten möchten, in den Ruhezustand versetzen, bis das Skript erneut ausgeführt wird, und es beenden. Init startet Ihr Skript nach dem Beenden erneut.
quelle
Einfache Möglichkeit, einen Auftrag von crontab mit einem Intervall von weniger als einer Minute zu wiederholen (Beispiel: 20 Sekunden):
crontab: * * * * * script.sh
script.sh:
quelle
Sie können die Leistung vom Python-Interpreter aus der Shell beziehen.
Ersetzen Sie fünf in einer beliebigen Zeit (Sek.).
Achtung: Mit UMSCHALT + EINGABETASTE geben Sie die Eingabe in der Shell zurück. Und vergessen Sie nicht, in jede Zeile der while-Schleife 4 SPACE- Einrückungen einzugeben.
quelle
python
"s"os.system()
eine Shell ausführt, um die Befehlszeile zu interpretieren. Das Aufrufenpython
von "s" , um Shells in einer Schleife auszuführen, um einen Befehl regelmäßig auszuführen, ist also ein wenig übertrieben. Sie können genauso gut alles in der Shell tun.Diese Lösung funktioniert unter MacOSX 10.7. Das funktioniert wunderbar.
In meinem Fall
oder
um meinen Desktop ständig aufzuräumen.
quelle
sleep
Befehl haben?while [ 0 ]
ist ein seltsamer Weg, eine Endlosschleife zu schreiben; Dies funktioniert, weil dertest
Befehl (auch bekannt als[
) eine nicht leere Zeichenfolge als wahr behandelt.while : ; do ... ; done
ist idiomatischer, oder wenn Sie es vorziehen, können Sie verwendenwhile true ; do ... ; done
.Sie könnten diese rekursive Funktion beziehen:
oder fügen Sie hinzu:
und das Skript aufrufen.
quelle
Um einen Befehl in einem Konsolenfenster wiederholt auszuführen, führe ich normalerweise Folgendes aus:
while true; do (run command here); done
Dies funktioniert auch für mehrere Befehle, um beispielsweise eine ständig aktualisierte Uhr in einem Konsolenfenster anzuzeigen:
while true; do clear; date; sleep 1; done
quelle
quelle
Mit
zsh
und einersleep
Implementierung, die Gleitkomma-Argumente akzeptiert:Oder für
forever
:Wenn Ihr
sleep
Floats nicht unterstützt, können Sie es jederzeit als Wrapper umzsh
daszselect
Built-In neu definieren:quelle
... Ich frage mich, wie viel komplizierte Lösungen bei der Lösung dieses Problems erstellt werden können.
Es kann so einfach sein ...
setze dort 1 nächste Zeile an das Ende der Datei wie:
Wenn Sie alle 1 Sekunde etwas ausführen möchten, geben Sie Folgendes ein:
und innerhalb dieser file.sh sollte sein:
und das ist alles!
GENIESSEN!
quelle
funktioniert bei mir.
quelle