Come posso creare a livello di programmazione un nuovo cron job?
Domanda
Voglio essere in grado di aggiungere programmaticamente un nuovo cron job, qual è il modo migliore per farlo?
Da la mia ricerca , sembra che potrei scaricare l'attuale crontab e quindi aggiungerne uno nuovo, piping che di nuovo in crontab:
(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -
C'è un modo migliore?
Soluzione
Ha sempre funzionato bene per me.
Dovresti considerare uno script leggermente più sofisticato che può fare tre cose.
-
Aggiungi una linea crontab; assicurando che non esisteva. Aggiungere quando esiste già è male.
-
Rimuovi la linea crontab. Forse avvertendo solo se non esistesse.
-
Una combinazione delle due funzioni precedenti per sostituire la linea crontab.
Altri suggerimenti
Il modo migliore se si esegue come root, è di rilasciare un file in /etc/cron.d
se si utilizza un gestore pacchetti per impacchettare il proprio software, è possibile semplicemente impostare i file in quella directory e questi vengono interpretati come se fossero crontab, ma con un campo aggiuntivo per il nome utente, ad es .:
Nome file: /etc/cron.d/per_minute
Contenuto:
* * * * * root / bin / sh /home/root/script.sh
La soluzione di OP ha un bug, potrebbe consentire l'aggiunta di voci due volte, utilizzare di seguito per correggere.
(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -
Per aggiungere qualcosa a cron
(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | sort | uniq | crontab -
Per rimuovere questo da cron
(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | grep -v hupChannel.sh | sort | uniq | crontab -
la speranza potrebbe aiutare qualcuno
Se hai intenzione di farlo per uno scenario run-once solo per scommettere qualcosa, dai un'occhiata a 'at'
Cambia semplicemente l'editor in tee command:
export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e
Supponendo che ci sia già una voce nel tuo crontab, il seguente comando dovrebbe funzionare relativamente bene. Nota che la variabile $ CMD
è lì solo per leggibilità. L'ordinamento prima del filtraggio dei duplicati è importante, poiché uniq
funziona solo su linee adiacenti.
CMD='wget -O - -q http://www.example.com/cron.php"'
(crontab -l ; echo "0 * * * * $CMD") | sort | uniq | crontab -
Se al momento hai un crontab vuoto, riceverai il seguente errore a stderr:
no crontab for user
Se vuoi evitare questo, puoi aggiungere un po 'di complessità e aggiungere qualcosa come questo:
(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//" | sort | uniq | crontab -
man crontab è anche utile:
CRONTAB (1)
nome
crontab - manipulate per-user crontabs (Dillon's Cron)
SINOSSI
crontab file [-u user] - replace crontab from file
crontab - [-u user] - replace crontab from stdin
crontab -l [user] - list crontab for user
Aggiungendo alla risposta di JohnZ, ecco la sintassi per pianificare come root se sei un sudoer:
(sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | sudo crontab -
La maggior parte delle soluzioni qui sono per l'aggiunta di linee al crontab. Se hai bisogno di più controllo, ti consigliamo di controllare l'intero contenuto del crontab.
Puoi usare le tubazioni per farlo in modo abbastanza elegante.
Per riscrivere completamente il crontab, fai
echo "2 2 2 2 2 /bin/echo foobar" |crontab -
Questo dovrebbe essere facile da combinare con altre risposte descritte qui come
crontab -l | <something> | tee |crontab -
Oppure, se hai i contenuti in un file, è ancora più semplice
cat <file> |crontab -
function cronjob_exists($command){
$cronjob_exists=false;
exec('crontab -l', $crontab);
if(isset($crontab)&&is_array($crontab)){
$crontab = array_flip($crontab);
if(isset($crontab[$command])){
$cronjob_exists=true;
}
}
return $cronjob_exists;
}
function append_cronjob($command){
if(is_string($command)&&!empty($command)&&cronjob_exists($command)===FALSE){
//add job to crontab
exec('echo -e "`crontab -l`\n'.$command.'" | crontab -', $output);
}
return $output;
}
append_cronjob('* * * * * curl -s http://localhost/cron/test.php');
Questo verificherebbe per assicurarsi che il tuo comando non esista già prima di aggiungerlo.
crontab -l 2>/dev/null | grep -q '/path/to/script' || echo "5 * * * * /path/to/script" | crontab -
Saluti.
Piping stdout in crontab
non ha installato il nuovo crontab per me su macOS, quindi ho trovato questa soluzione, usando l'editor tee
in una sotto-shell:
(EDITOR=tee && (crontab -l ; echo "@daily ~/my-script.sh" ) | uniq - | crontab -e)
inoltre puoi aggiungere le tue attività a /etc/cron.*/
Ecco un altro modo da evitare, che evita i duplicati
(crontab -l 2>/dev/null | fgrep -v "*/1 * * * * your_command"; echo "*/1 * * * * your_command") | crontab -
Ed ecco un modo per fare la risposta di JohnZ ed evitare il messaggio no crontab for user
, o se devi operare in un ambiente di tipo set -eu
e non puoi se qualcosa restituisce un errore (nel qual caso la parte 2 > / dev / null
è facoltativa):
( (crontab -l 2>/dev/null || echo "") ; echo "0 * * * * your_command") | sort -u - | crontab -
O se vuoi dividere le cose in modo che siano più leggibili:
new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
(echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab -
O opzionalmente rimuovi qualsiasi riferimento a tuo_comando (es: se il programma è cambiato, lo vuoi sempre e solo una volta). In questo caso non abbiamo più bisogno di uniq
(bonus aggiunto, anche l'ordine di inserzione viene preservato):
new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
preceding_cron_jobs=$(echo "$preceding_cron_jobs" | grep -v your_command )
(echo "$preceding_cron_jobs" ; echo "$new_job") | crontab -
Puoi anche modificare direttamente il file di testo della tabella cron, ma la tua soluzione sembra perfettamente accettabile.