Domanda Perché gli script di crontab non funzionano?


Spesso, crontab gli script non vengono eseguiti nei tempi previsti o come previsto. Ci sono numerose ragioni per questo:

  1. notazione sbagliata di crontab
  2. problema di autorizzazioni
  3. variabili ambientali

Questo wiki della comunità mira ad aggregare le ragioni principali per crontab gli script non vengono eseguiti come previsto. Scrivi ogni motivo in una risposta separata.

Si prega di includere una ragione per risposta - dettagli sul motivo per cui non viene eseguita - e correggere (es) per quella ragione.

Si prega di scrivere solo problemi specifici per cron, ad es. comandi che vengono eseguiti come previsto dalla shell ma eseguiti erroneamente da cron.


454


origine


Devi chiudere crontab -e affinchè il cron abbia effetto Per esempio usando vim modifico il file e lo uso :w per scriverlo ma il lavoro non viene aggiunto a cron finché non esco anche io. Quindi non vedrò il lavoro fino a dopo :q anche. - DutGRIFF
Penso che il modo migliore per eseguire il debing di cron sia controllare syslog e trovare i problemi. - Suneel Kumar
Nel mio caso - l'e-mail stava andando alla mia cartella SPAM, quindi ..... controlla prima di passare ore al debugging: D - almaruf
Interruzioni di energia elettrica - Josef Klimuk


risposte:


Ambiente diverso

Cron trasmette un set minimo di variabili di ambiente ai tuoi lavori. Per vedere la differenza, aggiungi un lavoro fittizio come questo:

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

Aspettare /tmp/env.output da creare, quindi rimuovere di nuovo il lavoro. Ud B B B B Bud B B B B Bud B B Bud B B B B B B B B B B B B B B B /tmp/env.output con l'output di env corri nel tuo normale terminal.

Un "gotcha" comune qui è il PATH ududud B Bud B B Bud B Bud B Bud B Bud B Bud B B B B B B B B B B Forse lo script di cron usa il comando somecommand trovato in /opt/someApp/bin, a cui hai aggiunto PATH in /etc/environment? cron ignora PATH da quel file, quindi runnning somecommand dal tuo script fallirà quando viene eseguito con cron, ma funziona quando viene eseguito in un terminale. Vale la pena notare che le variabili da /etc/environment verrà passato ai lavori cron, solo che le variabili cron non si impostano in modo specifico, come ad esempio PATH.

Per aggirare questo, basta impostare il proprio PATH variabile nella parte superiore dello script. Per esempio.

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

# rest of script follows

Alcuni preferiscono utilizzare solo i percorsi assoluti per tutti i comandi. Raccomando contro quello. Considera cosa succede se vuoi eseguire il tuo script su un sistema diverso, e su quel sistema, il comando è in /opt/someAppv2.2/bin anziché. Dovresti passare attraverso l'intero script sostituendo /opt/someApp/bin con /opt/someAppv2.2/bin invece di fare solo una piccola modifica sulla prima riga dello script.

È inoltre possibile impostare la variabile PATH nel file crontab, che si applicherà a tutti i lavori cron. Per esempio.

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

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

431



Penso di essermi innamorato di questo, e di una nuova fine alla fine ... doppio smacco. - WernerCD
+1 per env, Mi ero completamente dimenticato di quel comando e pensavo che PATH funzionasse. In realtà, nel mio caso, era davvero leggermente diverso. - Izkata
@ pbr Se tali directory sono lasciate scrivibili ad altri, il sistema è già compromesso. - geirha
@pbr Un sysadmin potrebbe inconsapevolmente eliminare il filesystem di root. Non puoi difenderti dagli amministratori di sistema che commettono errori stupidi. Se installi una versione più recente di un interprete che non è retrocompatibile, mi aspetterei una rottura a prescindere. Il modo corretto di gestirlo è installarlo come un comando diverso. Per esempio. hai python versione 2.xe installa python 3, lo installi come python3, non python. E per quanto riguarda / opt / someApp / bin, perché mai non avrebbe autorizzazioni / proprietà sane? qualsiasi amministratore sano avrebbe garantito permessi / proprietà sane sui file di sistema. - geirha
@ pbr Sembra che potremmo andare avanti all'infinito, sì. Non riesco ancora a capire perché sia ​​una cattiva idea usare PATH. Se hai voglia di discuterne ulteriormente in un mezzo più adatto per la discussione, mi troverai in #ubuntu e #bash, tra gli altri canali, su irc.freenode.net - geirha


Il mio top gotcha: se ti dimentichi di aggiungere una nuova riga alla fine del crontab file. In altre parole, il file crontab dovrebbe terminare con una riga vuota.

Di seguito è la sezione pertinente nelle pagine man per questo problema (man crontab poi salta alla fine):

   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



questo è un tale showstopper, come mai non è stato risolto in così tanti anni di cron? - Capi Etheriel
Sembra essere risolto in Vixie cron: man crontab su Ubuntu 10.10 dice che "cron richiede che ogni voce in un crontab finisca in un carattere di nuova riga." Se l'ultima voce in un crontab manca la newline, cron considererà il crontab (almeno parzialmente) danneggiato e rifiuterà di installarlo. " (E la data alla fine è il 19 aprile 2010.) - Marius Gedminas
@barraponto Questo è in realtà un bug nei nuovi editor di testo. Il personaggio "newline" dovrebbe essere un fine della linea carattere, quindi la riga finale in un file di testo dovrebbe terminare con un carattere di fine riga che non viene mostrato nell'editor. Vi e Vim usano correttamente il carattere, e cron è stato creato prima che i nuovi editor iniziassero il loro strano comportamento ... Quindi, lo salvano e includono una riga vuota. - Izkata
Se modifichi crontab usando crontab -e controllerà la sintassi del file prima di consentire un salvataggio, incluso un controllo per newline. - Tom Harrison Jr
@ Chan-HoSuh, secondo la pagina di manuale "cron richiede che ogni voce in un crontab finisca in un carattere di nuova riga." Se l'ultima voce in un crontab manca la nuova riga, cron considererà il crontab (almeno parzialmente) interrotto e si rifiuterà di installalo. " Questo comportamento verrà invocato durante la modifica, quindi salvando il crontab utilizzando il comando -e opzione, ed è indipendente dall'editor. - Tom Harrison Jr


Il demone Cron non è in esecuzione. Ho davvero sbagliato con questo alcuni mesi fa.

Genere:

pgrep cron 

Se non vedi alcun numero, cron non è in esecuzione. sudo /etc/init.d/cron start può essere usato per avviare cron.

EDIT: Invece di invocare gli script di init tramite /etc/init.d, utilizzare il servizio utilità, ad es.

sudo service cron start

125



Grazie per avermi mostrato pgrep. Ho continuato a fare ps -ef | Grep Foo - ripper234
Puoi anche usare pidof cron che ometterà i risultati per altre applicazioni che hanno anche la parola "cron", come crontab. - Pithikos
Strano, tutti questi non mi danno nulla per mostrare cron è in esecuzione, ma se corro sudo service cron start ottengo start: Job is already running: cron - Colleen
service crond start se il suo centos / RHEL - Srihari Karanth


Il nome del file di script in cron.d/, cron.daily/, cron.hourly/, ecc., non dovrebbe contenere punti (.), altrimenti le parti di esecuzione salteranno loro.

Vedi 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_-]+$).

Quindi, se hai uno script di cron backup.sh, analyze-logs.pl in cron.daily/ directory, è meglio rimuovere i nomi delle estensioni.


83



È una caratteristica non un bug - mantiene cose come myscript.backup o myscript.original o myscript.rpm-new dall'esecuzione proprio accanto a myscript. - pbr
@ pbr: ha senso. Almeno sarebbe stato utile per il debug se run-parts --test (o un'altra opzione immaginaria come --debug emetterebbe i file che salta incluso il motivo. - Rabarberski
Se questa è una caratteristica, non è una bella cosa :( Molte persone usano il punto nel nome del file (backup.sh è il più comune). Se vuoi che uno script smetta di funzionare, il metodo più logico sarà rimuoverlo dalla directory "cron.d". - MatuDuke
Questa è una caratteristica così brutta che è effettivamente un bug. È prassi comune richiedere un finale particolare (come ".list" o ".cron" o qualcosa del genere) se le persone vogliono assicurarsi che le cose vengano eseguite solo quando lo si desidera. Il punto di prelievo arbitrario come probabile separatore per ".bak" o ".temp" o qualsiasi altra cosa, è completamente imprevedibile tranne nel modo in cui confonderebbe prevedibilmente le persone. Finiture legittime come ".sh" e ".pl" sono state utilizzate da decenni. Molte persone usano "_bak" o "_temp" o "-bak" invece di un punto, comunque. Questa è una scelta di design orribile; è un bug di progettazione al meglio. - Teekin


In molti ambienti cron esegue i comandi usando sh, mentre molte persone pensano che userà bash.

Suggerimenti per testare o correggere questo per un comando in errore:

  • Prova a eseguire il comando in sh per vedere se funziona
  • Avvia il comando in una sottoshell di bash per assicurarti che venga eseguito in bash:
    bash -c "mybashcommand"
  • Chiedi a cron di eseguire tutti i comandi in bash impostando la shell nella parte superiore di crontab:
    SHELL=/bin/bash
  • Se il comando è uno script, assicurati che lo script contenga uno shebang:
    #!/bin/bash

55



il suggerimento di bash è molto utile, ha risolto il problema con il mio cron. - Maxim Galushka
Questo mi ha causato solo 1 ora di fiddling / risoluzione dei problemi. Ancora più sconcertante se non si è a conoscenza del problema è che lo script verrà eseguito manualmente bene se la shell è tipica bash, ma non con cron. Grazie! - Hendy
Molto tempo fa mi sono imbattuto in qualcosa di correlato: il comando source è in bash ma non sh. In cron / sh, usa un punto: . envfile piuttosto che source envfile. - kungphu


Ho avuto alcuni problemi con i fusi orari. Cron era in esecuzione con il nuovo fuso orario dell'installazione. La soluzione era riavviare cron:

sudo service cron restart

34



Sì, dopo aver modificato il fuso orario su un sistema, è necessario riavviare ogni servizio che si preoccupa di che ora è o riavviare. Preferisco il riavvio, per essere sicuro di aver catturato tutto. - pbr
Oh, per l'amor di Dio, ammazzato per ore su questo. Riprovato il servizio dopo * * * * * touch /tmp/cronworks non ha fatto nulla, eppure c'è RELOAD al cronlog. - НЛО


Se il comando crontab ha a % simbolo in esso, cron cerca di interpretarlo. Quindi se stavi usando qualsiasi comando con a % in esso (come ad esempio una specifica di formato per il comando date) è necessario sfuggire.

Questo e altri buoni trucchi qui:
http://www.pantz.org/software/cron/croninfo.html


29



Questo è ciò che ha causato il fallimento del mio lavoro Cron nell'ultima settimana. Alla fine ho capito che il mio appuntamento non aveva un carattere di fuga (barra inversa per le altre persone che cercano il personaggio di fuga). Sìì! - Valien
Guarda anche Come posso eseguire date all'interno di un lavoro di cron tab? - Jared Beck
Anche questo mi ha un po 'addosso. Grazie! - stefansundin


Il percorso assoluto deve essere utilizzato per gli script:

Per esempio, /bin/grep dovrebbe essere usato al posto di grep:

# m h  dom mon dow   command
0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors

Invece di:

# m h  dom mon dow   command
0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors

Questo è particolarmente complicato, perché lo stesso comando funzionerà quando eseguito dalla shell. La ragione è questa cron non ha lo stesso PATH variabile di ambiente come utente.


28



vedi la risposta di geirha, puoi (devi) definire il PATH di cron - Capi Etheriel
Bzzt. NON è necessario definire il PERCORSO: utilizzare i percorsi assoluti è la migliore pratica qui. "perché un eseguibile può essere altrove su qualche altro computer" non briscola "Voglio che esegua esattamente questo programma e non qualcuno che qualcuno metta nel percorso di fronte al mio programma originale" - pbr
Sì, questo è stato per me, al di fuori del cron ho potuto eseguire direttamente il comando, all'interno del cron che era necessario completo /usr/bin/whatever sentiero - Anentropic


È anche possibile che la password dell'utente sia scaduta. Anche la password di root può scadere. Puoi tail -f /var/log/cron.log e vedrete cron fall con password scaduta. È possibile impostare la password per non scadere in questo modo: passwd -x -1 <username>

In alcuni sistemi (Debian, Ubuntu) la registrazione di cron non è abilitata di default. In /etc/rsyslog.conf o /etc/rsyslog.d/50-default.conf la linea:

# cron.*                          /var/log/cron.log

dovrebbe essere modificato (sudo nano /etc/rsyslog.conf) non commentato per:

cron.*                          /var/log/cron.log

Dopo ciò, è necessario riavviare rsyslog tramite

/etc/init.d/rsyslog restart

o

service rsyslog restart 

Fonte: Abilita la registrazione crontab in Debian Linux

In alcuni sistemi (Ubuntu) il file di registrazione separato per cron non è abilitato di default, ma i registri relativi a cron vengono visualizzati nel file syslog. Si può usare

cat /var/log/syslog | grep cron

per visualizzare i messaggi relativi a cron.


23



Ho Debian (wheezy) ma non c'è /etc/init.d/rsyslog, solo inetutils-syslogd e sysklogd. Devo installare qualcosa o semplicemente riavviare uno dei due? - hgoebl


Cron sta chiamando uno script che non è eseguibile.

Correndo chmod +x /path/to/scrip lo script diventa eseguibile e dovrebbe risolvere questo problema.


21



Questo non è unico a crone facilmente rintracciabile semplicemente cercando di eseguire /path/to/script dalla riga di comando. - Adam Matan
Se sei abituato a eseguire script con . scriptname o sh scriptname o bash scriptnameallora questo diventa a cron-specifico problema - Eliah Kagan


Se il cronjob richiama applicazioni GUI, devi dire loro che DISPLAY dovrebbero usare.

Esempio: avvio di Firefox con cron.

Il tuo script dovrebbe contenere export DISPLAY=:0 da qualche parte.


16



aplay aveva bisogno di questo per qualche ragione. grazie - IljaBek
* * * * * export DISPLAY=:0 && <command> - LoMaPh