Vraag Waarom werkt mijn crontab niet en hoe kan ik het oplossen?


Dit is een Canonical Question over het gebruik van cron & crontab.

U bent hierheen gestuurd omdat de gemeenschap er vrij zeker van is dat het antwoord op uw vraag hieronder te vinden is. Als je vraag hieronder niet wordt beantwoord, zullen de antwoorden je helpen informatie te verzamelen die de community kan helpen. Deze informatie moet worden bewerkt in uw oorspronkelijke vraag.

Het antwoord voor 'Waarom werkt mijn crontab niet en hoe kan ik het oplossen?'is hieronder te zien. Dit gaat over de cron systeem met de crontab gemarkeerd.


193
2017-11-17 04:51


oorsprong


Dit is een enorme dupe van Redenen waarom crontab niet werkt op AskUbuntu. - Dan Dascalescu


antwoorden:


Hoe je al je crontab gerelateerde problemen / problemen oplost (Linux)


Dit is een community wiki, als u merkt dat er iets niet klopt met dit antwoord of als u aanvullende informatie heeft, bewerk deze dan.


Ten eerste, basisterminologie:

  • cron (8) is de daemon die geplande opdrachten uitvoert.
  • crontab (1) is het programma dat wordt gebruikt om gebruikerscrontab (5) -bestanden aan te passen.
  • crontab (5) is een bestand per gebruiker dat instructies voor cron (8) bevat.

Volgende opleiding over cron:

Elke gebruiker op een systeem kan zijn eigen crontab-bestand hebben. De locatie van de root- en gebruikerscrontab-bestanden is systeemafhankelijk maar ze zijn meestal onder /var/spool/cron.

Er is een systeemomvang /etc/crontab bestand, de /etc/cron.d map kan crontab-fragmenten bevatten die ook worden gelezen en uitgevoerd door cron. Sommige Linux-distributies (bijvoorbeeld Red Hat) hebben ook /etc/cron.{hourly,daily,weekly,monthly} Dit zijn mappen, scripts waarin elk uur / dag / week / maand wordt uitgevoerd, met rootrechten.

root kan altijd het crontab-commando gebruiken; gewone gebruikers krijgen al dan niet toegang. Wanneer u het crontab-bestand bewerkt met de opdracht crontab -e en sla het op, crond controleert het op basisgeldigheid maar garandeert niet dat je crontab-bestand correct is gevormd. Er is een bestand met de naam cron.deny welke zal specificeren welke gebruikers geen cron kunnen gebruiken. De cron.deny bestandslocatie is systeemafhankelijk en kan worden verwijderd waardoor alle gebruikers cron kunnen gebruiken.

Als de computer niet is ingeschakeld of crond daemon niet actief is en de datum / tijd voor een opdracht die moet worden uitgevoerd is verstreken, haalt crond geen overhaal uit en voert geen query's uit.

crontab-gegevens, hoe een commando te formuleren:

Een crontab-opdracht wordt vertegenwoordigd door een enkele regel. Je kunt niet gebruiken \ om een ​​opdracht over meerdere regels uit te breiden. De hash (#) teken staat voor een opmerking, wat betekent dat alles op die regel genegeerd wordt door cron. Voorlopende spatie en lege regels worden genegeerd.

Wees ERG voorzichtig bij het gebruik van het percentage (%) teken in je commando. Tenzij ze zijn ontsnapt \% ze worden omgezet in nieuwe regels en alles na de eerste niet-escaped % wordt doorgegeven aan je commando op stdin.

Er zijn twee indelingen voor crontab-bestanden:

  • Gebruiker crontabs

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  *   command to be executed
    
  • Systeembreed /etc/crontab en /etc/cron.d fragmenten

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  * user-name  command to be executed
    

Merk op dat de laatste een gebruikersnaam vereist. De opdracht wordt uitgevoerd als de genoemde gebruiker.

De eerste 5 velden van de regel vertegenwoordigen de tijd (en) waarop de opdracht moet worden uitgevoerd. U kunt nummers of waar van toepassing dag- / maandnamen gebruiken in de tijdsspecificatie.

  • De velden worden gescheiden door spaties of tabs.
  • Een komma (,) wordt gebruikt om een ​​lijst te specificeren, bijv. 1,4,6,8, wat betekent: lopen op 1,4,6,8.
  • Bereiken worden gespecificeerd met een streepje (-) en kan worden gecombineerd met lijsten, b.v. 1-3,9-12 wat betekent dat tussen 1 en 3 en vervolgens tussen 9 en 12.
  • De / karakter kan worden gebruikt om een ​​stap b.v. 2/5 wat betekent beginnend bij 2 dan elke 5 (2,7,12,17,22 ...). Ze wikkelen niet voorbij het einde.
  • Een asterisk (*) in een veld betekent het volledige bereik voor dat veld (bijv. 0-59 voor het minuutveld).
  • Bereiken en stappen kunnen worden gecombineerd b.v. */2 betekent beginnend bij het minimum voor het relevante veld en vervolgens elke 2, bijvoorbeeld 0 voor minuten (0,2 ... 58), 1 voor maanden (1,3 ... 11) enz.

Debronende cron-commando's

Controleer de post! Standaard verzendt cron elke uitvoer van de opdracht naar de gebruiker die de opdracht uitvoert. Als er geen uitvoer is, is er geen e-mail. Als u wilt dat cron e-mail naar een ander account verzendt, kunt u de MAILTO-omgevingsvariabele instellen in het crontab-bestand, bijvoorbeeld

MAILTO=user@somehost.tld
1 2 * * * /path/to/your/command

Leg de uitvoer zelf vast

1 2 * * *  /path/to/your/command &>/tmp/mycommand.log

waarbij stdout en stderr worden vastgelegd in /tmp/mycommand.log

Kijk naar de logs; cron logt zijn acties via syslog, die (afhankelijk van je setup) vaak naar toe gaan /var/log/cron of /var/log/syslog.

Indien nodig kunt u de cron-instructies filteren met b.v.

grep CRON /var/log/syslog 

Nu we de basisbeginselen van cron hebben besproken, waar de bestanden zijn en hoe ze te gebruiken, laten we enkele veelvoorkomende problemen bekijken.

Controleer of cron actief is

Als cron niet actief is, worden uw opdrachten niet gepland ...

ps -ef | grep cron | grep -v grep

zou je zoiets moeten geven

root    1224   1  0 Nov16 ?    00:00:03 cron

of

root    2018   1  0 Nov14 ?    00:00:06 crond

Als het niet opnieuw wordt gestart

/sbin/service cron start

of

/sbin/service crond start

Er kunnen andere methoden zijn; gebruik wat je distro biedt.

cron voert uw opdracht uit in een beperkte omgeving.

Welke omgevingsvariabelen beschikbaar zijn, is waarschijnlijk zeer beperkt. Meestal krijgt u alleen een paar gedefinieerde variabelen, zoals $LOGNAME, $HOME, en $PATH.

Van bijzonder belang is het PATH is beperkt tot /bin:/usr/bin. De overgrote meerderheid van 'mijn cron-script werkt niet', problemen worden veroorzaakt door dit beperkende pad. Als uw opdracht zich op een andere locatie bevindt, kunt u dit op een aantal manieren oplossen:

  1. Geef het volledige pad naar uw opdracht.

    1 2 * * * /path/to/your/command
    
  2. Geef een geschikt pad in het crontab-bestand

    PATH=/usr:/usr/bin:/path/to/something/else
    1 2 * * * command 
    

Als uw opdracht andere omgevingsvariabelen vereist, kunt u deze ook in het crontab-bestand definiëren.

cron voert uw opdracht uit met cwd == $ HOME

Ongeacht waar het programma dat u uitvoert zich op het bestandssysteem bevindt, de huidige werkdirectory van het programma wanneer cron het programma uitvoert, is de basismap van de gebruiker. Als u toegang hebt tot bestanden in uw programma, moet u hier rekening mee houden als u relatieve paden gebruikt, of (bij voorkeur) gewoon overal volledig gekwalificeerde paden gebruikt en iedereen een hoop verwarring bespaart.

Het laatste commando in mijn crontab loopt niet

Cron vereist over het algemeen dat opdrachten worden beëindigd met een nieuwe regel. Bewerk je crontab; ga naar het einde van de regel die de laatste opdracht bevat en voeg een nieuwe regel in (druk op Enter).

Controleer het crontab-formaat

U kunt geen Crontab opgemaakte crontab gebruiken voor / etc / crontab of de fragmenten in /etc/cron.d en vice versa. Een door een gebruiker geformatteerde crontab bevat geen gebruikersnaam op de zesde positie van een rij, terwijl een crontab met systeemindeling de gebruikersnaam bevat en de opdracht als die gebruiker uitvoert.

Ik plaats een bestand in /etc/cron.{hourly,daily,weekly,monthly} en het loopt niet

  • Controleer of de bestandsnaam geen extensie heeft run-delen
  • Zorg ervoor dat het bestand uitvoerrechten heeft.
  • Vertel het systeem wat te gebruiken bij het uitvoeren van uw script (bijv #!/bin/sh bovenaan)

Cron date gerelateerde bugs

Als uw datum onlangs is gewijzigd door een gebruiker of systeemupdate, tijdzone of andere, zal crontab zich onregelmatig gaan gedragen en bizarre bugs vertonen, soms werken, soms niet. Dit is de poging van crontab om te proberen "te doen wat je wilt" wanneer de tijd daaronder verandert. Het veld 'minuut' wordt niet meer effectief nadat het uur is gewijzigd. In dit scenario worden alleen sterretjes geaccepteerd. Start cron opnieuw en probeer het opnieuw zonder verbinding te maken met internet (dus de datum heeft geen kans om te resetten naar een van de tijdservers).

Procenttekens, nogmaals

Om het advies over procenttekens te benadrukken, hier is een voorbeeld van wat cron met hen doet:

# cron entry
* * * * * cat >$HOME/cron.out%foo%bar%baz

maakt het ~ / cron.out-bestand met de 3 regels

foo
bar
baz

Dit is bijzonder opdringerig bij het gebruik van de date commando. Zorg ervoor dat u aan de procenttekens ontsnapt

* * * * * /path/to/command --day "$(date "+\%Y\%m\%d")"

273
2017-10-09 15:29



Misschien wil ik ook in de sectie 'restricted env' vermelden dat LD_LIBRARY_PATH mogelijk ook extra directory's moet instellen voor het geval dat uw cron-taak faalt vanwege het niet kunnen vinden van gedeelde bibliotheken. - DavidJ
merk op dat je zelfs zoiets als dit kunt schrijven: 35 1,5-23 / 2 * * * do_something in plaats van 35,1,5,7,9, .. * * * Daarnaast dit crontab.guru vertaalt de invoer die u in menselijke taal invoert. - Dennis Nolte
De output capture werkt niet voor mij, misschien vanwege de sh-shell. Ik denk dat dit draaglijker is: ... /path/to/your/command >/tmp/mycommand.log 2>&1 - chus
dit werkte voor mij: sudo apt-get install postfix - jmunsch
is cron job ook afhankelijk van hoe zwaar is het bestand? Omdat ik een eenvoudige Hello-wereld in cron runde, werkte het. Maar mijn tweede code was een beetje zwaar en wordt normaal gesproken wel uitgevoerd, maar met cron wordt er geen enkele uitvoer in het bestand weergegeven. - Devendra Bhat


Als uw cronjobs niet meer werken, controleert u of uw wachtwoord niet is verlopen. Sindsdien zijn alle cron-taken gestopt.
Er zullen berichten in staan /var/log/messages vergelijkbaar met de onderstaande hieronder die problemen met de authenticatie van de gebruiker laten zien:

(username) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)


18
2018-02-04 20:29



Ik heb dit ook net gekregen (foutberichtbestand / var / log / syslog voor mij). In mijn geval een doos van DigitalOcean die, op het moment dat ze zijn aangemaakt, het root-wachtwoord (optioneel) naar een ander wachtwoord reset, en blijkbaar totdat je daar naar binnen gaat en het verandert, lopen alle cron-taken niet. Jammer. Fix is ​​zoiets als sudo -u root passwd - rogerdpack


Debian Linux en zijn afgeleide (Ubuntu, Mint, enz.) Hebben enkele eigenaardigheden die kunnen voorkomen dat uw cron-taken worden uitgevoerd; in het bijzonder, de bestanden in /etc/cron.d, /etc/cron.{hourly,daily,weekly,monthly} moet:

  • eigendom zijn van root
  • alleen schrijfbaar door root
  • niet beschrijfbaar zijn door een groep of andere gebruikers
  • heb een naam zonder punten '.' of een ander speciaal teken maar '-' en '_'.

De laatste doet regelmatig nietsvermoedende gebruikers pijn; in het bijzonder elk script in een van deze mappen genaamd whatever.sh, mycron.py, testfile.pl, etc. zal niet uitgevoerd worden, ooit.

In mijn ervaring was dit specifieke punt veruit de meest voorkomende reden voor een niet-uitvoerende cronjob op Debian en derivaten.

Zien man cron voor meer informatie, indien nodig.


15
2017-11-17 14:37





Ongebruikelijke en onregelmatige schema's

Cron wordt allesbehalve beschouwd als een erg eenvoudige planner en de syntaxis stelt een beheerder niet gemakkelijk in staat iets minder vaak voorkomende planningen te formuleren.

Overweeg de volgende taak die gewoonlijk wordt uitgelegd "rennen command elke 5 minuten ":

*/5 * * * * /path/to/your/command

versus:

*/7 * * * * /path/to/your/command

welke doet niet altijd rennen command elke 7 minuten.

Vergeet niet dat de / karakter kan worden gebruikt om een ​​stap in te voeren, maar die stappen wikkelen niet voorbij het einde van een reeks, b.v. */7 die overeenkomt met elke 7e minuut van de minuten 0-59  d.w.z. 0,7,14,21,28,35,42,49,56 maar tussen het een uur en het volgende er zal zijn slechts 4 minuten tussen de batches, na 00:56 een nieuwe serie begint om 01:00, 01:07 etc. (en batches zullen niet worden uitgevoerd 01:03 , 01:10 , 01:17 enz.).


Wat te doen in plaats daarvan?

Maak meerdere batches

In plaats van een enkele cron-taak maakt u meerdere batches die gecombineerd resulteren in het gewenste schema.

Als u bijvoorbeeld elke 40 minuten een batch wilt uitvoeren (00:00, 00:40, 01:20, 02:00 enzovoort), maakt u twee batches, een die tweemaal wordt uitgevoerd op de even uren en de tweede die alleen de oneven uren uitvoert:

# The following lines create a batch that runs every 40 minutes i.e.

# runs on   0:00, 0:40,        02:00, 02:40         04:00 etc to 22:40
0,40 */2 * * * /path/to/your/command

# runs on               01:20,               03:20,       etc to 23:20
20 1/2 * * * /path/to/your/command

# Combined: 0:00, 0:40, 01:20, 02:00, 02:40, 03:20, 04:00 etc.

Voer uw batch minder vaak uit 

In plaats van elke 7 minuten uw batch uit te voeren, wat een moeilijk schema is om op te splitsen in meerdere batches, voert u het in plaats daarvan elke 10 minuten uit.

Voer uw batches vaker uit 

Veel oneven schema's evolueren omdat de batchruntimes toenemen / fluctueren en dan worden de batches ingepland met een beetje extra veiligheidsmarge om te voorkomen dat opeenvolgende runs van dezelfde batch elkaar overlappen en gelijktijdig worden uitgevoerd.

In plaats daarvan, denk anders en creëer een cronjob die netjes zal falen wanneer een vorige run nog niet is voltooid, maar die anders zal lopen. Zie dit Q & A:

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job --minutely

Op dezelfde manier kunt u de tijdstempel van de laatste succesvolle run in batch laten opnemen en aan het begin van de batch controleren of het gewenste interval tussen batches al is verstreken en wordt uitgevoerd en op een andere manier netjes wordt afgesloten.

In bash de seven-minute-job zou er ongeveer zo uitzien als:

#!/bin/bash
# seven-minute-job
# This batch will only run when 420 seconds (7 min) have passed
# since the file /tmp/lastrun was either created or updated

if [ ! -f /tmp/lastrun ] ; then
    touch /tmp/lastrun
fi

if [ $(( $(date +%s) - $(date -r /tmp/lastrun +%s) )) -lt 420 ] ; then
    echo "The minimum interval of 7 minutes between successive batches hasn't passed yet."
    exit
fi

echo "Start running your batch"

date > /tmp/lastrun

Welke je dan veilig (poging) kunt uitvoeren om elke minuut:

* * * * * /path/to/your/seven-minute-job

Gebruik geen cron

Als uw behoeften complex zijn, kunt u overwegen een geavanceerder product te gebruiken dat is ontworpen om complexe planningen uit te voeren (verdeeld over meerdere servers) en dat triggers, opdrachtafhankelijkheden, foutafhandeling, controles van nieuwe pogingen enz. Ondersteunt. taakplanning en / of "workload automation".


10
2017-10-23 04:45





PHP-specifieke

Als je een cron-baan hebt zoals:

php /bla/bla/something.php >> /var/logs/somelog-for-stdout.log

En in het geval van fouten verwachten, dat ze naar u worden verzonden, maar niet - controleer dit.

PHP verstuurt standaard geen fouten naar STDOUT. @zien https://bugs.php.net/bug.php?id=22839

Om dit op te lossen, voeg je in cli`s php.ini of in je regel (of in je bash-wrapper voor PHP) deze toe:

  • --define display_startup_errors = 1
  • --define display_errors = 'stderr'

Met de eerste instelling kunt u fatale mensen zoals 'Memory oops' en 2nd - omleiden naar STDERR. Pas nadat je goed hebt geslapen, omdat alles naar de e-mail van je root wordt gestuurd in plaats van alleen maar ingelogd.


8



Dat foutenrapport werd in 2007 gesloten met de status van de patch die werd toegevoegd aan de PHP 5.2+ vestigingen. Weet je zeker dat dit nodig is? Ik heb zojuist PHP 5.4 geprobeerd en het lijkt goed te werken. (Het is echter nog steeds nodig voor PHP 4). - Xeoncross
@Xeoncross zie datum van antwoord :) - gaRex
Ja, dat is wat mij verwarde sinds je in 2013 hebt geantwoord en het kaartje was in '07. - Xeoncross