Come impostare correttamente un processo cron cron


36

Ho provato a impostare un processo cron cron per eseguire uno script Bash come root, per eseguire al minuto 7,37, ogni ora, ogni giorno del mese, ogni mese. Questo script si trova /usr/bine denominato tunlrupdate.sh. Aggiorna il DNS di Tunlr.

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

Questo script Bash è disponibile qui .

Quando viene invocato, lo script scrive ciò che sta accadendo in un registro in cui si trova /var/log/tunlr.log

Per aggiungere questo lavoro cron cron ho usato lo standard per il crontab di root

sudo crontab -e

E ho inserito queste 2 righe alla fine. Mi aspetto che cron esegua lo script come root.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

Un comando successivo ha sudo crontab -lconfermato che il processo cron è stato inserito.

Ho riavviato Ubuntu e stavo controllando nel file di registro se il processo cron era stato avviato correttamente. Tuttavia, non esiste nulla nel file di registro che /var/log/tunlr.logsignifica che il lavoro non è mai stato avviato correttamente.

L'ho verificato se avessi eseguito lo script dalla riga di comando

sudo /usr/bin/tunlrupdate.sh

quindi il file di registro viene aggiornato di conseguenza.

Perché questo cron job non funziona come previsto nel mio sistema?

AGGIORNAMENTO 1: Tutte le soluzioni proposte finora non funzionano. Ringrazio Olli per una CLI per elencare il registro di sistema sudo grep CRON /var/log/syslog. Tuttavia ho ricevuto un errore CRON

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

con il PATH suggerito = inserimento e uso del percorso assoluto dalla radice per funzioni nello script o senza queste soluzioni suggerite qui. Ricevo ancora questo errore.

Dopo alcune ricerche ho individuato l'errore nel file /usr/lib/php5/maxlifetimecome spiegato qui :Change #!/bin/sh -e --> #!/bin/sh -x

Quindi elencando il registro errori CRON nel mio sistema

sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

Non riesco ancora a eseguire l'esecuzione dello script bash. Questa volta non viene visualizzato alcun errore nel registro. Per avere la certezza che questo non era il contenuto dello script, ho ridotto lo script alle seguenti 3 righe:

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

Non riesco ancora a completare il lavoro cron. Nulla è scritto nel file di registro. Quindi anche uno script vuoto non può essere eseguito in cron? Non capisco Conosco una sceneggiatura ridotta a queste 2 righe:

#!/bin/bash
exit 0

E ancora lo stesso registro degli errori. Lo script cron non passa attraverso ...


Se vuoi che sia un cronjob "root" devi essere root quindi digita crontab -e. Inoltre devi solo accedere come root (tipo di console "su root") e quindi crontab -e (in questo caso sudo non è necessario).
Wolfgang,

Bene. Non vedo il punto della tua risposta? Digitando $ sudo crontab -e ha fatto il lavoro come riportato da $ sudo crontab -l, cioè la riga che descrive il nuovo lavoro è stata aggiunta al cron del root. Di per sé il lavoro non è presente nell'utente cron, ad esempio $ crontab -l non mostra alcun lavoro cron aggiunto qui.
Antonio,

@WolfgangVogl ha usato "sudo" che funziona come previsto.
Alexis Wilke,

Risposte:


68

Se si desidera eseguire uno script come un normale utente :

crontab -e

E aggiungi la riga:

07,37 * * * * /usr/bin/tunlrupdate.sh

Se vuoi eseguire il tuo script come root :

sudo crontab -e

E aggiungi la stessa riga:

07,37 * * * * /usr/bin/tunlrupdate.sh

@NineCattoRules Se non elimini l'output, cosa vedi?
Angelo Fuchs,

@AngeloFuchs vecchio commento ... sicuramente ho provato quel comando come root ( sudo crontab -einvece che crontab -e). O qualcos'altro, comunque funziona
NineCattoRules,

10

Bene, finalmente la soluzione funzionante. Nel syslog ho visto il ripetitivo e intrigante:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

Sembra che root non sia stato riconosciuto come cmd. Come ho già usato il cron del root usando $ sudo /usr/bin/tunlrupdate.sh. Quindi ho provato con lo script originale (corretto per un errore nella data UNIX cmd:% m che è il mese è stato usato per minuti che è% M) quanto segue (che rimuove la radice dalla cron line):

$ sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

Questa si è rivelata la soluzione finale. [Anche se ho trovato decine di pubblicazioni che affermano la linea errata con radice nella linea cron. È stato un errore].


Buon punto Olli. Sono d'accordo con te su questo. Per riferimento l'utente crontab è memorizzato in / var / spool / cron / crontabs / nome-utente o per root / var / spool / cron / crontabs / root. Vedi questa pagina askubuntu.com/questions/216692/where-is-the-user-crontab-stored La cartella contenente è già e dà il nome dell'utente.
Antonio,

Bene, non dovresti avere bisogno di queste informazioni, dato che dovresti solo modificare i file crontab con il crontabcomando (tranne i file crontab sotto /etc).
Olli,

1
@Antonio i punteggi con il campo username sono usati solo in /etc/crontab(crontab a livello di sistema). Usando sudo crontab -estai lavorando con il crontab di root che di solito si trova in/var/spool/cron/crontabs
Matijs,

2

Un "problema" con cron è la mancanza di variabili d'ambiente (per ovvi motivi di sicurezza). Probabilmente ti mancano PATH e HOME. Puoi definirli direttamente nello script o nel file crontab.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

Dovrai testare fino a quando tutte le variabili necessarie non saranno definite come richiesto dallo script.


1
Questa è l'unica risposta che ha funzionato per me. Ho copiato le istruzioni SHELL e PATH dal /etc/crontabfile e le ho incollate nel sudo crontab -ee il comando è stato eseguito come root senza problemi. Grazie!
Terrance,

0

I messaggi di errore Cron vengono di solito, per impostazione predefinita, inviati via e-mail. Puoi verificare se c'è e-mail per root con sudo mail, o semplicemente controllando il contenuto di /var/mail/root, ad es sudo less /var/mail/root.


Se i messaggi di posta elettronica non aiutano, controlla anche /var/log/syslog:

sudo grep CRON /var/log/syslog

Come già detto da Alexis Wilke, cron ha un meccanismo diverso per impostare le variabili di ambiente.

La tua sceneggiatura ha bisogno

PATH=/sbin:/bin:/usr/bin

al crontab. HOMEnon dovrebbe essere necessario. Dovresti usare percorsi assoluti nei tuoi script, ad es. /bin/dateInvece di date. Puoi trovare i percorsi corretti per ogni comando con which command_name, ad es

$ which date
/bin/date

Eseguendo il tuo grep CRON suggerito in / var / log / syslog Ho ottenuto il folle 11 febbraio 14:37:01 Marius-PC CRON [7826]: (root) CMD (root /usr/bin/tunlrupdate.sh) 11 febbraio 14: 37:01 Marius-PC CRON [7825]: (root) MAIL (inviato 1 byte di output; ma ha ottenuto lo stato 0x00ff, # 012) 11 febbraio 14:39:01 Marius-PC CRON [7849]: (root) CMD ( [-x / usr / lib / php5 / maxlifetime] && [-d / var / lib / php5] && find / var / lib / php5 / -depth -mindepth 1 -maxdepth 1 -type f -cmin + $ (/ usr / lib / php5 / maxlifetime)! -execdir fuser -s {} 2> / dev / null \; -delete) Se aggiungo alcune definizioni per il PATH in cron, queste non influiranno sul mio sistema $ PATH?
Antonio,

Quell'output dice che ha provato a inviare qualcosa tramite e-mail ma non è riuscito. Ciò significa che non viene visualizzato il messaggio di errore /var/mail/root. Puoi risolvere il problema o provare conPATH=...
Olli,

@Antonio, in alternativa, usa questa versione rattoppata
Olli,

Grazie. So di non aver configurato la posta elettronica di sistema e di essere a conoscenza del fatto che non è stato eseguito. Avevo già modificato lo script per utilizzare il percorso assoluto per qualsiasi funzione chiamata. L'ultima cosa è stata la mia domanda precedente: una definizione PATH all'interno di crontab non rovinerà la mia variabile $ PATH di sistema?
Antonio,

1
Nel frattempo ero occupato a correggere un bug nel formato della data dallo script originale. Stava usando% m (che è per il mese NON minuto) invece di% M ...
Antonio,

0

Puoi aggiungere questa riga nel tuo script. Quindi, dopo aver controllato i log cron e aver verificato che il tuo lavoro è stato eseguito, puoi ottenere lo stesso $ PATH di crontabs.

/bin/echo $PATH > /root/path.txt

E probabilmente la cosa migliore che puoi fare per diagnosticare i problemi negli script cron è ottenere tutte le variabili d'ambiente di SO con il comando env nel tuo script. Quindi aggiungi questa riga al tuo script. Quindi è possibile analizzare l'outputallEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

Un altro trucco è dirigere l'output dello script in un posto. Aggiungere il /root/log.log. In questo modo tutto l'output dello script verrà mantenuto/root/log.log

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

Inoltre è possibile pianificare l'esecuzione dello script ogni minuto per facilitare i test e i controlli.

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.