Vraag Waarom werken crontab-scripts niet?


Vaak, crontab scripts worden niet volgens schema of zoals verwacht uitgevoerd. Daar zijn verschillende redenen voor:

  1. verkeerde crontab-notatie
  2. rechten probleem
  3. omgevingsvariabelen

Deze communitywiki heeft als doel de belangrijkste redenen voor te verzamelen crontab scripts worden niet uitgevoerd zoals verwacht. Schrijf elke reden in een afzonderlijk antwoord.

Vermeld één reden per antwoord - details over waarom het niet wordt uitgevoerd - en herstel (en) om die reden.

Schrijf alleen cron-specifieke problemen, bijvoorbeeld opdrachten die worden uitgevoerd zoals verwacht van de shell maar die ten onrechte door cron worden uitgevoerd.


454


oorsprong


Je moet sluiten crontab -e voor de cron om invloed te hebben. Bijvoorbeeld met behulp van vim bewerk ik het bestand en gebruik het :w om het te schrijven, maar de taak wordt niet toegevoegd aan cron totdat ik ook stop. Dus ik zie de baan pas na ik :q ook. - DutGRIFF
Ik denk dat de beste manier om cron te debuggen is om syslog te controleren en de problemen te vinden. - Suneel Kumar
In mijn geval - de e-mail ging naar mijn SPAM-map, dus ..... controleer dat voordat je uren besteedt aan debuggen: D - almaruf
Stroomuitval - Josef Klimuk


antwoorden:


Verschillende omgeving

Cron geeft een minimale set omgevingsvariabelen door aan uw taken. Voeg een dummy-opdracht toe als volgt om het verschil te zien:

* * * * * env> /tmp/env.output

Wachten op /tmp/env.output worden gemaakt en vervolgens de taak opnieuw verwijderen. Vergelijk nu de inhoud van /tmp/env.output met de uitvoer van env ren in je reguliere terminal.

Een veel voorkomende "gotcha" hier is de PATH omgevingsvariabele verschillend. Misschien gebruikt uw cron-script de opdracht somecommand gevonden in /opt/someApp/bin, waaraan je hebt toegevoegd PATH in /etc/environment? cron negeert PATH uit dat bestand, dus runnning somecommand van uw script zal mislukken als het wordt uitgevoerd met cron, maar werkt als het in een terminal wordt uitgevoerd. Het is vermeldenswaard dat variabelen van /etc/environment wordt doorgegeven aan cron-taken, alleen niet de variabelen die cron specifiek zelf instelt, zoals PATH.

Om er omheen te komen, hoeft u alleen die van uzelf in te stellen PATH variabele bovenaan het script. Bijv.

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

Sommigen geven er de voorkeur aan om alleen absolute paden te gebruiken voor alle opdrachten. Ik beveel dat aan. Overweeg wat er gebeurt als u uw script op een ander systeem wilt uitvoeren, en op dat systeem staat het commando in /opt/someAppv2.2/bin in plaats daarvan. Je zou het hele script moeten vervangen /opt/someApp/bin met /opt/someAppv2.2/bin in plaats van alleen een kleine bewerking op de eerste regel van het script uit te voeren.

U kunt ook de variabele PATH instellen in het crontab-bestand, dat van toepassing is op alle cron-taken. Bijv.

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

431



Ik denk dat ik hier gewoon voor viel, en newline op het eind ... dubbel zo stom. - WernerCD
+1 voor env, Ik was die opdracht volledig vergeten en dacht dat PATH aan het werk was. Het was eigenlijk heel anders in mijn geval. - Izkata
@pbr Als dergelijke mappen aan anderen kunnen worden geschreven, is het systeem al in gevaar. - geirha
@pbr Een sysadmin kan onbewust het rootbestandssysteem verwijderen. Je kunt je niet beschermen tegen sysadmins die dwaze fouten maken. Als u een nieuwere versie van een interpreter installeert die niet achterwaarts compatibel is, zou ik toch breken verwachten. De manier om dat aan te pakken, is door het als een ander commando te installeren. Bijv. je hebt python versie 2.x en installeer python 3, je installeert het als python3, niet als python. En wat betreft / opt / someApp / bin, waarom zou het in vredesnaam geen gezonde toestemmingen / eigendom hebben? elke weldenkende admin zou zorgen voor gezonde toestemmingen / eigendom van systeembestanden. - geirha
@pbr Het lijkt erop dat we eeuwig door kunnen gaan, ja. Ik snap nog steeds niet waarom het een slecht idee is om PATH te gebruiken. Als je dit verder wilt bespreken in een medium dat beter geschikt is voor discussie, vind je mij in #ubuntu en #bash, naast andere kanalen, op irc.freenode.net - geirha


Mijn beste gotcha: Als je vergeet om een ​​nieuwe regel toe te voegen aan het einde van de crontab het dossier. Met andere woorden, het crontab-bestand moet eindigen met een lege regel.

Hieronder vindt u de relevante sectie in de manpagina's voor dit probleem (man crontab ga dan verder naar het einde):

   Although cron requires that each entry in a crontab end  in  a  newline
   character,  neither the crontab command nor the cron daemon will detect
   this error. Instead, the crontab will appear to load normally. However,
   the  command  will  never  run.  The best choice is to ensure that your
   crontab has a blank line at the end.

   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

291



dit is zo'n showstopper, hoe komt het dat het niet is opgelost in zoveel jaren van cron? - Capi Etheriel
Lijkt te worden hersteld in Vixie cron: man crontab op Ubuntu 10.10 zegt: "cron vereist dat elke invoer in een crontab eindigt op een nieuwlijnteken Als de laatste invoer in een crontab de nieuwe regel mist, zal cron de crontab (ten minste gedeeltelijk) afgebroken beschouwen en weigeren deze te installeren." (En de datum aan het einde is 19 april 2010.) - Marius Gedminas
@barraponto Dit is eigenlijk een fout in nieuwe teksteditors. Het teken "newline" hoort een a te zijn lijnafsluiting teken, dus de laatste regel in een tekstbestand hoort te eindigen in een nieuwlijnteken dat niet in de editor wordt weergegeven. Vi en vim gebruiken het personage correct, en cron werd gebouwd voordat de nieuwe editors hun vreemde gedrag begonnen ... Dus speel het spel op te slaan en inclusief een lege regel. - Izkata
Als u crontab bewerkt met crontab -e het controleert de syntaxis van het bestand voordat een save wordt toegestaan, inclusief een controle op de nieuwe regel. - Tom Harrison Jr
@ Chan-HoSuh, volgens de man-pagina "cron vereist dat elke invoer in een crontab eindigt in een nieuwlijnteken. Als de laatste invoer in een crontab de newline mist, zal cron de crontab (ten minste gedeeltelijk) verbroken beschouwen en weigeren installeer het." Dit gedrag zal worden opgeroepen bij het bewerken en dan het crontab opslaan met behulp van de -e optie en is onafhankelijk van de editor. - Tom Harrison Jr


Cron-daemon is niet actief. Ik heb dit een paar maanden geleden echt verpest.

Type:

pgrep cron 

Als u geen nummer ziet, is cron niet actief. sudo /etc/init.d/cron start kan worden gebruikt om cron te starten.

EDIT: in plaats van init-scripts op te roepen via /etc/init.d, gebruikt u de service nut, b.v.

sudo service cron start

125



Bedankt dat je me pgrep hebt laten zien. Ik bleef ps doen -ef | grep foo - ripper234
Je zou ook kunnen gebruiken pidof cron die resultaten weglaat voor andere applicaties die ook het woord 'cron' hebben, zoals crontab. - Pithikos
Raar, al deze geven me niets om te laten zien dat cron draait, maar als ik ren sudo service cron start ik krijg start: Job is already running: cron - Colleen
service crond start als zijn centos / RHEL - Srihari Karanth


De bestandsnamen van het script in cron.d/, cron.daily/, cron.hourly/, etc., mag geen punt bevatten (.), anders lopen onderdelen ze over.

Zie run-parts (8):

   If neither the --lsbsysinit option nor the --regex option is given then
   the names must consist entirely of upper and lower case  letters,  dig‐
   its, underscores, and hyphens.

   If  the  --lsbsysinit  option  is given, then the names must not end in
   .dpkg-old  or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong  to
   one  or more of the following namespaces: the LANANA-assigned namespace
   (^[a-z0-9]+$);   the   LSB   hierarchical   and   reserved   namespaces
   (^_?([a-z0-9_.]+-)+[a-z0-9]+$);  and  the  Debian cron script namespace
   (^[a-zA-Z0-9_-]+$).

Dus, als je een cron-script hebt backup.sh, analyze-logs.pl in cron.daily/ map, kunt u de extensienamen het beste verwijderen.


83



Het is een functie geen bug - het houdt dingen zoals myscript.backup of myscript.original of myscript.rpm-new van rechts naast myscript. - pbr
@pbr: is logisch. Het zou tenminste nuttig zijn geweest voor het debuggen als run-parts --test (of een andere denkbeeldige optie zoals --debug zou de bestanden exporteren die het overslaat inclusief de reden. - Rabarberski
Als dit een functie is, is het geen leuke :( Veel mensen gebruiken de punt in de bestandsnaam (backup.sh is de meest voorkomende). Als je een script wilt stoppen met uitvoeren, is de meest logische methode om verwijder het uit de map "cron.d". - MatuDuke
Dit is zo'n slechte eigenschap dat het in feite een bug is. Het is gebruikelijk om een ​​bepaald einde (zoals ".list" of ".cron" of zoiets) te vereisen als mensen ervoor willen zorgen dat dingen alleen worden uitgevoerd als ze bedoeld zijn. Het willekeurig kiezen van een punt als een waarschijnlijk scheidingsteken voor ".bak" of ".temp" of wat dan ook, is volledig onvoorspelbaar, behalve op de manier dat het mensen op voorspelbare wijze in verwarring brengt. Legitieme eindes zoals ".sh" en ".pl" worden al decennia wijdverspreid gebruikt. Veel mensen gebruiken echter "_bak" of "_temp" of "-bak" in plaats van een punt. Dit is een vreselijke ontwerpkeuze; het is hoogstens een design-bug. - Teekin


In veel omgevingen voert cron opdrachten uit met behulp van sh, terwijl veel mensen aannemen dat het zal gebruiken bash.

Suggesties om dit te testen of op te lossen voor een falende opdracht:

  • Probeer de opdracht in te voeren sh om te zien of het werkt
  • Wikkel het commando in een bash-subshell om ervoor te zorgen dat het wordt uitgevoerd in bash:
    bash -c "mybashcommand"
  • Laat cron alle opdrachten in bash uitvoeren door de shell boven aan je crontab in te stellen:
    SHELL=/bin/bash
  • Als het commando een script is, zorg er dan voor dat het script een shebang bevat:
    #!/bin/bash

55



bash suggestie is zeer nuttig, opgelost probleem met mijn cron. - Maxim Galushka
Dit zorgde er gewoon voor dat ik 1 uur lang gehannes / troubleshooten. Nog meer verbijsterend als je je niet bewust bent van het probleem, zal het script prima worden uitgevoerd als je de typische shell bent bash, maar niet met cron. Bedankt! - Hendy
Lang geleden kwam ik iets gerelateerd tegen: het commando source is in bash maar niet sh. Gebruik in cron / sh een punt: . envfile liever dan source envfile. - kungphu


Ik had wat problemen met de tijdzones. Cron liep met de verse installatietijdzone. De oplossing was om cron opnieuw te starten:

sudo service cron restart

34



Ja, na het wijzigen van de tijdzone op een systeem, moet u elke service opnieuw starten die aangeeft hoe laat het is, of opnieuw opstarten. Ik geef de voorkeur aan de reboot, om er zeker van te zijn dat ik alles heb gevangen. - pbr
Oh godzijdank, dood hier uren over. Geprobeerd service opnieuw opstarten na * * * * * touch /tmp/cronworksdeed niets, maar toch RELOAD bij cronlog. - НЛО


Als je crontab-commando een heeft % symbool erin, probeert cron het te interpreteren. Dus als je een commando gebruikt met een % erin (zoals een indelingsspecificatie voor het datumcommando) moet je eraan ontsnappen.

Dat en andere goede vondsten hier:
http://www.pantz.org/software/cron/croninfo.html


29



Dit is de reden waarom mijn Cron-taak de afgelopen week is mislukt. Eindelijk uitgevonden dat mijn datum geen escape-teken had (backslash voor andere mensen die op zoek zijn naar wat het escape-personage is). Yay! - Valien
Zie ook Hoe kan ik uitvoeren? date binnenkant van een cron tab-opdracht? - Jared Beck
Dit is mij ook een beetje. Bedankt! - stefansundin