Come faccio a creare un crontab tramite uno script


153

Devo aggiungere un cron job tramite uno script che eseguo per configurare un server. Attualmente sto usando Ubuntu. Posso usare crontab -ema questo aprirà un editor per modificare l'attuale crontab. Voglio farlo programmaticamente.

È possibile farlo?




Se stai cercando di modificare o eliminare una voce crontab, vedi la mia soluzione di seguito.
Brian Smith,

Risposte:


11

I lavori Cron di solito sono memorizzati in un file per utente sotto /var/spool/cron

La cosa più semplice da fare è probabilmente creare un file di testo con il lavoro configurato, quindi copiarlo nella cartella spool cron e assicurarsi che disponga delle autorizzazioni giuste (600).


20
La modifica dei file direttamente in / var / spool / cron è disapprovata. In effetti, se guardi i file lì, di solito conterranno avvisi come "NON MODIFICARE QUESTO FILE" come prima riga.
Jared il

12
@Jared Anche se sono abbastanza d'accordo con l'idea, dire che "è malvisto" non aiuta molto. Indica piuttosto quale altro file deve essere modificato, se presente, o spiega manualmente i rischi della modifica dei file. Sto pianificando di creare alcuni lavori cron tramite la riga di comando automatizzata e se la modifica di questo file è sia l'unica opzione, sia senza effetti collaterali significativi, non vedo perché non dovrei usarlo.
Balmipour,

47
Scorri verso il basso per la vera risposta.
John Red,

1
A mio parere, questa risposta è il modo migliore: stackoverflow.com/a/610860/2681752
galaux

2
Ho adottato questo approccio e me ne sono pentito. Su RHEL, la directory / var / spool / cron non è eseguibile a livello mondiale, quindi gli utenti non possono attraversare la directory e modificare i propri file manualmente. Se rendi eseguibile / var / spool / cron world, il tuo sysadmin locale amichevole sarà arrabbiato con te, inoltre la modifica del permesso può essere sovrascritta se il pacchetto cronie viene mai reinstallato o aggiornato.
functionvoid,

384

Ecco un one-liner che non usa / richiede che il nuovo lavoro sia in un file:

(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

Il 2>/dev/nullè importante in modo che non si ottiene il no crontab for usernamemessaggio che alcuni nix * producono se non ci sono al momento le voci non crontab.


14
Questa dovrebbe essere la risposta accettata. Solo bisogno di un modo ora per verificare se l'one-liner ho intenzione di aggiungere è già lì o no ...
ChrisPrime

7
... oh aspetta, ecco come fare per controllare se qualcosa è nel crontab di mia dell'utente prima aggiungo con uno script: stackoverflow.com/a/14451184/3686125
ChrisPrime

1
se questo script è inteso come un comando da ripetere e modificare un'attività cron esistente, potrebbe essere utile sostituire la riga esistente in crontab. diversi marker possono essere usati per controllare diverse attività cron (control-marker-1, control-marker-2, ecc ...): (crontab -l 2> / dev / null | grep -v control-marker-1; echo '* / 5 * * * * / path / to / job -with args # control-marker-1') | crontab -
chef

7
Ho scoperto che questo stava rimuovendo le voci crontab esistenti e che avevo anche bisogno di usare un altro utente (root), quindi ho usato quanto segue per mantenere le voci esistenti: echo -e "$(sudo crontab -u root -l)\n* * * * * echo hello > /home/danny/temp.log 2>&1" | sudo crontab -u root -Spero che questo aiuti qualcuno
Danny

60

Per i crontab utente (incluso root), puoi fare qualcosa del tipo:

crontab -l -u user | cat - filename | crontab -u user -

dove il file denominato "nomefile" contiene elementi da aggiungere. Puoi anche fare manipolazione del testo usando sedo un altro strumento al posto di cat. Dovresti usare il crontabcomando invece di modificare direttamente il file.

Un'operazione simile sarebbe:

{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -

Se stai modificando o creando crontab di sistema, questi potrebbero essere manipolati come faresti con normali file di testo. Essi sono memorizzati nelle /etc/cron.d, /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthlydirectory e nei file /etc/crontabe /etc/anacrontab.


Sembrava promettente ma provando il secondo approccio (con echo), ho ottenuto "crontab: errore di utilizzo: il nome del file deve essere specificato per la sostituzione." La pagina man Cron mostra la sintassi come crontab [ -u user ] file, cioè, con un nome file obbligatorio. C'è qualche trucco per convincerlo ad accettare invece i dati inviati?
Mark Berry,

1
@MarkBerry: mi dispiace per quello. In una pipe, è necessario utilizzare un trattino per indicare che l'input proviene da stdin. Correggerò la mia risposta.
In pausa fino a nuovo avviso.

29

In Ubuntu e in molte altre distribuzioni, puoi semplicemente inserire un file nella /etc/cron.ddirectory contenente una singola riga con una voce crontab valida . Non è necessario aggiungere una linea a un file esistente.

Se hai solo bisogno di qualcosa da eseguire ogni giorno, inserisci semplicemente un file /etc/cron.daily. Allo stesso modo, è anche possibile rilasciare i file in /etc/cron.hourly, /etc/cron.monthlye /etc/cron.weekly.


5
Ma devi essere root per farlo.
Keith

17

Una risposta ancora più semplice alla tua domanda sarebbe:

echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root

Puoi configurare cronjobs su server remoti come di seguito:

#!/bin/bash
servers="srv1 srv2 srv3 srv4 srv5"
for i in $servers
  do
  echo "0 1 * * * /root/test.sh" | ssh $i " tee -a /var/spool/cron/root"
done

In Linux, il percorso predefinito del crontabfile è /var/spool/cron/. Qui puoi trovare i crontabfile di tutti gli utenti. Hai solo bisogno di aggiungere la tua voce cronjob al file del rispettivo utente. Nell'esempio sopra, il file crontab dell'utente root viene accodato con un cronjob per essere eseguito /root/test.shogni giorno all'una di notte.


Quello sarebbe /var/spool/cron/crontabs/rootsu Ubuntu.
Íhor Mé,

17

I file Crontab sono semplicemente file di testo e come tali possono essere trattati come qualsiasi altro file di testo. Lo scopo del crontabcomando è rendere più sicura la modifica dei file crontab. Se modificato tramite questo comando, il file viene verificato per errori e salvato solo se non ce ne sono.

crontab [path to file]può essere usato per specificare un crontab memorizzato in un file. Ad esempio crontab -e, questo installerà il file solo se è privo di errori.

Pertanto, uno script può scrivere direttamente file cron tab oppure scriverli in un file temporaneo e caricarli con il crontab [path to temp file]comando. La scrittura direttamente evita di dover scrivere un file temporaneo, ma evita anche il controllo di sicurezza.


2
Per nessuno come me, nota che è crontab [path to file].. Questa è stata sicuramente l'opzione migliore per me, in quanto consente un codice più leggibile. Uso crontab per tracciare i pacchi e cambiare lo sfondo del desktop con lo stato. Quando non mi aspetto pacchi, non è necessario controllare ogni ora. Ecco perché volevo che lo script modificasse automaticamente la frequenza cron.
Rasmus

1
@Rasmus Sembra una sceneggiatura fantastica che mi piacerebbe poter rubare. Qualche possibilità di condivisione tramite una sintesi o simile?
cledoux,

8

(Non ho abbastanza reputazione per commentare, quindi aggiungo come risposta: sentiti libero di aggiungerlo come commento accanto alla sua risposta)

Il one-liner di Joe Casadonte è perfetto, tranne se si esegue con set -e, cioè se lo script è impostato per fallire in caso di errore e se non ci sono ancora cronjobs. In tal caso, il one-liner NON creerà il cronjob, ma NON fermerà lo script. Il fallimento silenzioso può essere molto fuorviante.

Il motivo è che crontab -lritorna con un 1codice di ritorno, facendo sì che il comando successivo (il echo) non venga eseguito ... quindi il cronjob non viene creato. Ma poiché vengono eseguiti come sottoprocesso (a causa della parentesi) non fermano la sceneggiatura.

(È interessante notare che se si esegue di nuovo lo stesso comando, funzionerà: una crontab -volta eseguito una volta, non viene crontab -lancora emesso nulla, ma non viene più restituito un errore (non viene più visualizzato il no crontab for <user>messaggio). Quindi echoviene eseguito il successivo e viene creato il crontab)

In ogni caso, se corri con set -e, la linea deve essere:

(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -

Sì, questo è ancora più perfetto.
Yngve Sneen Lindal il

7

Come correzione a quelli che suggeriscono crontab -l | crontab -: questo non funziona su tutti i sistemi. Ad esempio, ho dovuto aggiungere un lavoro al crontab di root su dozzine di server che eseguono una vecchia versione SUSE (non chiedere perché). I vecchi SUSE antepongono le righe di commento all'output di crontab -l, rendendo crontab -l | crontab -non idempotente (Debian riconosce questo problema nella manpage crontab e ha corretto la sua versione di Vixie Cron per cambiare il comportamento predefinito di crontab -l).

Per modificare i crontab a livello di codice sui sistemi in cui vengono crontab -laggiunti commenti, è possibile provare quanto segue:

EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -

EDITOR=catdice a crontab di usare catcome editor (non il solito vi predefinito), che non cambia il file, ma invece lo copia su stdout. Ciò potrebbe comunque non riuscire se si crontab -prevede un input in un formato diverso da quello degli crontab -eoutput. Non provare a sostituire il finale crontab -con crontab -e- non funzionerà.


4

Bene /etc/crontabsolo un file ASCII quindi il più semplice è solo

 echo "*/15 * * * *   root     date" >> /etc/crontab

che aggiungerà un lavoro che ti invierà un'email ogni 15 minuti. Adatta a tuo piacimento, e prova con grepo altro significa se la linea è già stata aggiunta per rendere idempotente il tuo script.

Su Ubuntu et al., Puoi anche rilasciare i file in /etc/cron.*cui è più facile fare e testare --- inoltre non si scherza con i file di configurazione (di sistema) come /etc/crontab.


1
Penso che tecnicamente non sia necessario per monitorare le modifiche a crontab, anche se in realtà la maggior parte delle implementazioni lo fanno, quindi consiglierei una chiamata a crontab -e in seguito per produrlo. crontab -e onora la variabile EDITOR se la memoria serve, quindi impostandola su / bin / true per il momento dovrebbe solo forzare la rilettura del crontab.
Ulrich Schwarz,

1
Vero ancora su qualsiasi recente sistema Linux crond fa monitor, e lo fa certamente sulla piattaforma dichiarato del PO.
Dirk Eddelbuettel,

Solo se sei root e vuoi che lo script venga eseguito come root. Ciò potrebbe non essere auspicabile nel caso dei PO.
Keith

Non è così, ho molte voci non root in / etc / crontab. Devi semplicemente aggiungere sudo per aggiungere al file. Comunque, come ho già detto, c'è anche /etc/cron.*/ ma devi anche essere root per scrivere lì.
Dirk Eddelbuettel,

2

Ecco come modificare cron una voce senza modificare direttamente il file cron (che è disapprovato).

crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -

Se vuoi rimuovere una voce cron, usa questa:

crontab -l -u <user> | sed '/find/d' | crontab -u <user> -

Capisco che questo non è ciò che Gaurav chiedeva, ma perché non avere tutte le soluzioni in un unico posto?


1

Ho scritto uno strumento di distribuzione crontab in Python: https://github.com/monklof/deploycron

pip install deploycron

Installare il tuo crontab è molto semplice, questo unirà il crontab al crontab esistente del sistema.

from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")

1

È un approccio per aggiungere in modo incrementale il processo cron:

  ssh USER_NAME@$PRODUCT_IP nohup "echo '*/2 * * * * ping -c2 PRODUCT_NAME.com >> /var/www/html/test.html' | crontab -u USER_NAME -"
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.