Vraag Herhaal een opdracht elke x tijdsinterval in terminal?


Hoe kan ik herhaling een opdracht voor elk tijdsinterval, zodat ik opdrachten kan uitvoeren controleren  of toezicht houden  mappen?

Er is geen script nodig, ik heb alleen een eenvoudige opdracht nodig die in de terminal moet worden uitgevoerd.


123
2018-03-06 15:52


oorsprong




antwoorden:


Je kunt gebruiken watch opdracht, kijk maar wordt gebruikt om elk aangewezen commando op regelmatige intervallen uit te voeren.

Open Terminal en typ:

watch -n x <your command>

verandering X om de tijd te zijn in seconden die u wilt.

Voor meer hulp bij het gebruik van de watch commando en zijn opties, uitvoeren man watch of bezoek dit Link.

Bijvoorbeeld : het volgende zal lijst, elke 60s, op dezelfde Terminal, de inhoud van de Desktop-directory zodat u weet of er wijzigingen hebben plaatsgevonden:

watch -n 60 ls -l ~/Desktop

189
2018-03-06 15:54



+1 maar wees voorzichtig wanneer u uitbreidingen gebruikt. Probeer bijvoorbeeld het verschil tussen watch -n 1 'echo $COLUMNS' en watch -n 1 echo $COLUMNS bij het wijzigen van het formaat van je terminal - de eerste wordt elke seconde uitgebreid, maar de laatste wordt maar één keer uitgebreid voor  watch begint. - l0b0
omlaag kiezers moeten op zijn minst een commando achterlaten om mijn antwoord te bewerken, als ik het mis heb - nux
Ik weet dat ik een pedante ben en een grammaticale Nazi, maar de taal (mis) gebruik op SE maakt me gek. - Agi Hammerthief
+1 voor het beantwoorden van de vraag, zelfs als je Engels niet 100% perfect is. - dotancohen
Is er een manier om te gebruiken watch met "geschiedenis ingeschakeld" type commando? Ik hou ervan om te gebruiken watch, maar soms zie ik ook liever een logboek van vorige uitvoeringen, in plaats van alleen de laatste. En ja, ik weet dat ik scripting kan gebruiken (while true) om dit te bereiken, maar met behulp van de watch gebruik is zoveel schoner! - rinogo


Je kunt dit commando ook gebruiken in terminal, behalve het antwoord van nux:

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

Voorbeeld

while true; do ls; sleep 2; done

Deze opdracht zal de uitvoer van afdrukken ls met een interval van 2 sec.

Gebruik Ctrl+C om het proces te stoppen.

Er zijn weinig nadelen van watch

  • Het kan geen gealiaste commando's gebruiken.
  • Als de uitvoer van een opdracht vrij lang is, werkt scrollen niet correct.
  • Er is wat moeite om in te stellen maximaal tijdsinterval voorbij bepaalde waarde.
  • watch zal ANSI-kleursequenties interpreteren die escape-tekens doorgeven -c of --color keuze. Bijvoorbeeld de uitvoer van pygmentize zal werken, maar het zal mislukken ls --color=auto.

In de bovenstaande omstandigheden kan dit een betere optie lijken.


75
2018-03-06 16:00



watch bestaat daarvoor, dit is een beetje nutteloos, zou ik zeggen - Bruno Pereira
Ik beweer niet dat dit antwoord op de eerste plaats moet worden gebruikt. watch is in de meeste gevallen goed. Daarom heb ik in het begin 'afgezien van het antwoord van nux' genoemd. Maar er zijn weinig problemen mee watch bijvoorbeeld Eén kan geen gealiaste commando's gebruiken met watch. Neem bijvoorbeeld ll die is gealiast voor ls -laF maar kan niet worden gebruikt met watch. Ook als de uitvoer van een opdracht vrij lang is, zult u problemen ondervinden bij het gebruik van scrollen watch. In deze enkele speciale gevallen kan dit antwoord een betere optie lijken. - souravc
@souravc Mijn versie van watch staat in ieder geval het -c of --color opties voor colorized output. - ikdc
while sleep x is beter - het is makkelijker om te doden. - d33tah
Dit is een leuk alternatief en, in tegenstelling tot watch, het houdt de opdrachtgeschiedenis bij. - adelriosantiago


Ik wilde gewoon meedoen souravc en nuxantwoorden:

  1. Terwijl watch zal perfect werken op Ubuntu, je zou dat willen vermijden als je wilt dat je "Unix-fu" zuiver is - op FreeBSD bijvoorbeeld, is watch een commando om "op een andere tty-regel te snuffelen".
  2. while true; do command; sleep SECONDS; done heeft ook een waarschuwing - je commando kan moeilijker zijn om te gebruiken CTR + C. U wilt misschien liever while sleep SECONDS; do command; done - het is niet alleen korter, maar ook gemakkelijker te onderbreken. Het voorbehoud is dat het eerst zal slapen en dan je opdracht uitvoeren, dus je moet wat wachten SECONDS voordat het eerste optreden van het commando zal plaatsvinden.

31
2018-03-08 15:51



Hopelijk is het aanvaardbaar als een antwoord in plaats van een opmerking - ik wilde hier een andere oplossing laten zien en commentaar zou me eigenlijk minder aandacht geven. - d33tah
Waarom maakt het precies uit waar je zet sleep in de while lus? Ik kon geen verschil vinden, Ctrl + C brak de lus ogenblikkelijk maakt niet uit wat. - dessert
@ dessert: hangt ervan af wat je probeert uit te maken denk ik. Normaal gesproken zou ctrl + c je gewoon doden command en sleep en alleen breken als je doodt true. - d33tah


Klinkt als de ideale taak voor de cron daemon die het mogelijk maakt om periodieke commando's uit te voeren. Voer de ... uit crontab -e opdracht om de cron-configuratie van uw gebruiker te bewerken. Het formaat is gedocumenteerd in crontab (5). In principe heb je vijf tijdgerelateerde, spaties gescheiden velden gevolgd door een opdracht:

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)

Als u bijvoorbeeld elke dinsdag om 11 uur een Python-script wilt uitvoeren:

0 11 * * 1 python ~/yourscript.py

Er zijn ook enkele speciale namen die de tijd vervangen, zoals @reboot. Zeer nuttig als u een tijdelijke map moet maken. Van mijn crontab (vermeld bij crontab -l):

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

11
2018-03-07 18:54



De vraag vraagt ​​hoe iets periodiek in de terminal kan worden uitgevoerd. cron draait achter de schermen in plaats van in de terminal - northern-bradley


Als u het bestandssysteem bewaakt, dan inotifywait is geweldig en voegt zeker minder belasting toe aan je systeem.

Voorbeeld:

In 1 terminal type deze opdracht:

$ inotifywait .

Dan in 2e terminal, elke opdracht die van invloed is op de huidige directory,

$ touch newfile

In de originele terminal wordt inotifywait dan gewekt en wordt de gebeurtenis gerapporteerd

./ CREATE newfile2

Of in een lus

$ 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
2018-03-06 16:35



de gebruiker heeft je verteld, geen script, en misschien wil hij niets controleren - nux
Ik heb hem niet gezegd om een ​​script te schrijven, ik stelde voor dat als ze in een lus wachten om naar een bepaalde gebeurtenis in het bestandssysteem te kijken, dan inotifywait nuttig is en minder bronnen gebruikt dan het herhalen van een opdracht. Ik voer vaak verschillende opdrachten uit op een opdrachtregel, bijvoorbeeld grep something InALogFile|less is dat een script? - X Tian
het is een goed antwoord, probeer het te bewerken om er eenvoudiger uit te zien. - nux
Wat is eenvoudiger dan . Ik kan het bevel niet nalaten. - X Tian
Bedankt @XTian, ​​een geweldig commando. Ik zag ook nu in de manpagina die je kunt toevoegen -m continu monitoren zonder lus. - yoniLavi


U kunt uw eigen maken repeat commando om de volgende stappen uit te voeren; credits hier:

Open eerst uw .bash_aliases het dossier:

$ xdg-open ~/.bash-aliases

Ten tweede, plak deze regels onderaan het bestand en sla op:

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

Ten derde: sluit of open je terminal of typ:

$ source ~/.bash_aliases

En voila ! Je kunt het nu als volgt gebruiken:

$ repeat 5 echo Hello World !!!

of

$ repeat 5 ./myscript.sh

4
2017-08-08 19:38



er is een kleine typfout in de regel xdg-open ~ /. bas-aliases. het zou moeten zijn: xdg-open ~ / .bash_aliases (di: underscore) - ssinfod


je kunt crontab gebruiken. voer het commando uit crontab -e en open het met uw gewenste teksteditor en voeg vervolgens deze regel toe

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

Hiermee voer je elke tien minuten je opdracht uit

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

Hiermee voer je elke vier uur je opdracht uit

Een andere mogelijke oplossing

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

X aantal keren herhalen.

Y tijd om te wachten om te herhalen.

Voorbeeld:

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

4
2018-03-07 05:57



Waarom is dit een verbetering? Je hebt zojuist een extra, onnodige, stap toegevoegd door de opdracht als een variabele op te slaan. De enige dingen die dit doet is i) het langer maken om te typen ii) dwingt je om alleen eenvoudige commando's te gebruiken, geen leidingen of doorverwijzingen etc. - terdon♦
Verwijder de extra variabele - Maythux


Een andere zorg met de hierboven voorgestelde 'kijk'-benadering is dat het resultaat alleen wordt weergegeven als het proces is voltooid. "date; sleep 58; date" geeft de 2 datums pas weer na 59 seconden ... Als u iets vier minuten lang laat draaien, worden er langzaam meerdere pagina's met inhoud weergegeven, u zult het niet echt zien.

Aan de andere kant is de zorg met de "while" -benadering dat de taakduur niet in aanmerking wordt genomen.

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

Hiermee loopt het script soms elke minuut af, soms duurt het 1m40. Dus zelfs als een cron het elke minuut kan uitvoeren, hier doet hij dat niet.

Dus om de uitvoer op de shell te zien zoals deze is gegenereerd en te wachten op de exacte aanvraagtijd, moet u de tijd ervoor en daarna bekijken en met de tijd mee gaan.

Zoiets als:

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

Dit zal dit weergeven:

Zoals u kunt zien, wordt de opdracht elke minuut uitgevoerd:

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

Vervang gewoon de slaap echo $(( ( RANDOM % 30 ) + 1 ))"commando met wat je maar wilt en dat zal worden uitgevoerd, op de terminal / shell, precies elke minuut. Als je een ander schema wilt, verander dan de" 60 "seconden met wat je ooit nodig hebt.

Kortere versie zonder de foutopsporingslijnen:

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

2
2017-12-14 20:56



Reageren op mezelf ... Als uw opdracht meer duurt dan de vertraging die u configureert, krijgt $ DELAY een negatieve waarde en mislukt het slaapcommando, zodat het script meteen opnieuw wordt opgestart. Dat moet je weten. - jmspaggi