Posso eseguire un cron job più frequentemente di ogni minuto?


44

È possibile eseguire un processo cron ogni 30 secondi senza un comando sleep?


4
Qual è la tua intenzione? Cron è lo strumento giusto da usare per questo?
Manuel Faux,

Buona domanda.
Preet Sangha,

Ad esempio, attualmente sto usando cron per modificare l'immagine di sfondo del mio desktop, per eludere i limiti del selettore di immagini di sfondo nativo (non immergermi in sottodirectory). Se volessi passare più spesso di una volta al minuto, avrei incontrato questa limitazione cron. (anche se lo switcher bg nativo ha la stessa limitazione)
donquixote,

Risposte:


36

Se la tua attività deve essere eseguita di frequente, cron è lo strumento sbagliato. A parte il fatto che semplicemente non avvierà i lavori così frequentemente, rischi anche alcuni seri problemi se il lavoro impiega più tempo per l'esecuzione rispetto all'intervallo tra i lanci. Riscrivi la tua attività per demonizzare ed eseguire in modo persistente, quindi avviala da cron se necessario (assicurandoti che non si riavvierà se è già in esecuzione).


18
La parte "si rischiano anche alcuni seri problemi se l'esecuzione del lavoro richiede più tempo dell'intervallo tra i lanci". non è vero e, se lo fosse, si applicherebbe ugualmente ai lavori eseguiti ogni 5 minuti, ogni ora o ogni mese. Questo problema ha soluzioni (utilizzando un pidfile o altro e verificando se il lavoro è già in esecuzione prima di eseguirlo). Quindi il problema è che cron semplicemente non consente quella frequenza, ma non è corretto dire che c'è qualcosa di intrinsecamente sbagliato nell'esecuzione di un'attività ogni meno di un minuto.
matteo,

2
Volevo dire se non usi un pidfile. Se il lavoro viene eseguito ogni X minuti e il completamento richiede più di X minuti, si finirà con l'accumulo di lavori. Se il tuo lavoro è anche limitato da una sorta di risorsa (CPU, larghezza di banda di rete / disco, ecc.), L'esecuzione più alla volta richiederà ancora più tempo per terminare, e alla fine il tuo computer si trasformerà in un disastro.
duskwuff,

2
Puoi usare run-oneper assicurarti che un programma / anche uno script PHP non stia avviando un'istanza duplicata. sudo apt-get install run-onee chiamalo darun-one <normal command>
kouton il

3
Come mostrano le risposte più in basso, è molto possibile, anche se un po 'hacker. Perché lo stai facendo male !!!! la risposta accettata qui, quando non risponde affatto alla domanda?
Qualcuno

@Mantriur Perché l'autore della domanda l'ha trovata utile e l'ha contrassegnata come risposta accettata? :) Ma seriamente, però, hai già identificato il problema da solo: molte delle altre risposte contemporanee hanno proposto soluzioni hacker che non sarebbe saggio da usare in un sistema di produzione. (Inoltre, tieni presente che molte delle altre risposte sono apparse solo anni dopo la domanda, quindi non erano ancora disponibili per l'accettazione!)
duskwuff,

37

Candidato per l' abuso più creativo di un comando Linux:

nohup watch -n 30 --precise yourprog >/dev/null &

Se è yourprogcostituito da:

date +%M.%S.%N >> yourprog.out

quindi yourprog.outpotrebbe apparire come:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

indicando un livello abbastanza buono di precisione.

Ecco una spiegazione delle parti del comando:

  • nohup- Ciò impedisce al comando che lo segue, watchin questo caso, di uscire alla chiusura del terminale.
  • watch- Questo programma esegue ripetutamente un comando. Normalmente la prima schermata di output dal comando viene visualizzata ogni volta che si watchesegue il comando.
  • -n 30- L'intervallo in cui eseguire il comando. In questo caso è ogni trenta secondi.
  • --precise- Senza questa opzione, watchesegue il comando dopo intervalli di secondi. Con esso, ogni avviamento del comando inizia sul dell'intervallo se possibile. Se questa opzione non fosse specificata nell'esempio, i tempi sarebbero più tardi e più tardi di più di 30 secondi ogni volta a causa del tempo impiegato per avviare ed eseguire il comando ( yourprog).
  • yourprog- Il programma o la riga di comando watchda eseguire. Se la riga di comando contiene caratteri speciali per la shell (ad es. Spazio o punto e virgola) dovrà essere citato.
  • >/dev/null- Il maggiore di reindirizza l'output del comando in esecuzione da watchun file, /dev/null. Quel file scarta tutti i dati scritti su di esso. Ciò impedisce che l'output venga scritto sullo schermo o, poiché nohupviene utilizzato, impedisce che l'output venga inviato a un file chiamato nohup.out.
  • &- Il watchcomando viene eseguito in background e il controllo viene restituito al processo terminale o padre.

Si noti che nohupil reindirizzamento dell'output e l' &operatore di controllo in background non sono specifici watch.

Ecco una spiegazione dello yourprogscript di esempio :

  • date- Emette la data e / o l'ora correnti. Può anche impostarli.
  • +%M.%S.%N- Questo specifica il formato di output dateda utilizzare. %Mè il minuto corrente, %Sè il secondo corrente ed %Nè il nanosecondo corrente.
  • >> yourprog.out- Questo reindirizza l'output del datecomando su un file chiamato yourprog.out. Il doppio maggiore di fa sì che l'output venga aggiunto al file su ogni invocazione anziché sovrascrivere il contenuto precedente.

Modifica :

Forse un'altra cosa che potrebbe essere abusata (o forse è un uso legittimo) sono i timer di sistema.

Vedi systemd / Timer come un sostituto cron e Cron vs systemd timer .

Proverò a pubblicare un esempio presto.


6
Sto dando +1 per la guancia pura
Matt Simmons il

2
Sarebbe bello avere qualche spiegazione in più con questa risposta. Il comando nohup è nuovo per me. Internet mi dice che è da ignorare il segnale di riaggancio. Il che mi lascia ancora confuso.
donquixote,

2
@donquixote: è importante riconoscere che il comando nel suo insieme nella mia risposta non è una cosa raccomandata da fare, quindi l'uso della parola "abuso". Tuttavia, al fine di chiarire un po 'le cose per te poiché sono incluse tecniche utili, proverò a descriverne alcune. Il &comando esegue il comando in background, restituendo immediatamente il controllo al prompt dei comandi. L'uso del nohupcomando fa sì che il processo in background (in questo caso watch) ignori il segnale di blocco che viene inviato all'uscita della shell, ad esempio quando si chiude il terminale. ...
In pausa fino a nuovo avviso.

1
... Il reindirizzamento dell'output mediante >/dev/nullcausa l' esclusione dell'output e impedisce la creazione di un nohup.outfile che altrimenti verrebbe creato quando l'output standard è un terminale.
In pausa fino a nuovo avviso.

1
@donquixote: non tra 30 secondi, ogni 30 secondi. Il resto è farlo funzionare incustodito in background per essere più simile a cron. Se si desidera utilizzare sleep, è necessario scrivere un ciclo in modo che il processo si ripeta ( watchfa questo ripetendo per te, come fa cron). Avresti ancora bisogno nohupe &. Un ulteriore problema con sleepsarebbe la deriva del tempo. L' --preciseopzione di watchevita questo. Senza di esso o quando si utilizza sleepin un ciclo, l'intervallo di tempo ha il tempo necessario per l'esecuzione dei comandi o dello script, in modo che ogni esecuzione sia successiva e successiva rispetto a ...
Pausa fino a ulteriore avviso.

13

Cron è progettato per svegliarsi ad ogni minuto, quindi non è possibile farlo senza un po 'di hacking, ad esempio dormire come hai detto.


10
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

Non dimenticare di scrivere qualcosa nel tuo programma in modo che esca se un'istanza precedente è già in esecuzione.

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

Naturalmente, ciò lascia ancora una piccola opportunità di fallimento, quindi cerca su Google una soluzione migliore applicabile al tuo ambiente.


è stato chiesto:without a sleep command
Philippe,

10
Gli altri visitatori che trovano questa domanda non si preoccupano se viene utilizzato il comando sleep :)
donquixote,

8

Puoi farlo con software di terze parti.

Un'opzione che ha funzionato bene per me è frequ-cron

Permette la precisione in millisecondi e ti dà la possibilità di rinviare l'esecuzione successiva fino a quando quella attuale è uscita.


1
Frequent-cron ha funzionato bene anche per noi e alimenta molti dei nostri sistemi di produzione. Non abbiamo mai avuto problemi con questo.
Homer6

2

Avrei un paio di preoccupazioni:

(1) a volte un sistema si impegna e non può avviare esattamente le cose sul punto di 30 secondi, è quindi possibile che nello stesso momento in cui si esegue un lavoro venga visualizzato un altro lavoro e quindi si abbiano 2 (o più) lavori che fanno lo stesso cosa. A seconda della sceneggiatura, potrebbero esserci delle interferenze significative qui. Pertanto, la codifica in uno script di questo tipo dovrebbe contenere un po 'di codice per assicurare che sia in esecuzione solo un'istanza dello script dato contemporaneamente.

(2) Lo script potrebbe avere un sacco di sovraccarico e consumare più risorse di sistema di quanto tu possa desiderare. Questo è vero se si è in competizione con molte altre attività di sistema.

Quindi, come ha scritto un poster, in questo caso prenderei seriamente in considerazione l'idea di inserire un demone in esecuzione con processi aggiuntivi per assicurarmi che rimanga in esecuzione se è di importanza cruciale per le tue operazioni.


1

la mia soluzione più semplice e preferita per questo compito:

voce cron:
* * * * * flock -w0 /path/to/script /path/to/script

script:
while true;do echo doing something; sleep 10s;done

alternativa pigra: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

o

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

professionisti

  • l'uso del flockcomando evita di eseguire lo script da più istanze contemporaneamente. Può essere molto importante nella maggior parte dei casi.
  • flocke i watchcomandi sono disponibili sulla maggior parte delle installazioni di Linux

cons

  • l'arresto di questo tipo di "Servizio" richiede due passaggi
    • commentare la voce cron
    • uccidi lo script o il watchcomando

2
Qualcuno può spiegarlo a un neofita di Linux - con pro e contro? Grazie ..
a20,

@asvany Penso che mi piaccia questa soluzione ma come a20, potresti pubblicare qualche spiegazione per il "verde" di Linux, per favore? ty.
JoelAZ

0

Una soluzione, se è per il tuo script o se puoi avvolgerlo:

  1. Ottieni e ricorda l'ora di inizio.
  2. Se è presente un file di blocco, che toccherai in seguito, e lo script non è in esecuzione da 60 secondi, attendi un secondo e ricontrolla. (es. while / sleep) *
  3. Se il file di blocco è ancora presente dopo che sono trascorsi 60 secondi, uscire con un avviso di blocco non aggiornato.
  4. Tocca il file di blocco.
  5. Mentre lo script non è in esecuzione da 60 secondi, esegui il ciclo dell'attività effettiva con la durata del sonno desiderata.
  6. Elimina il file di blocco.
  7. Aggiungi minutamente cron.
  8. Bob e `tuo zio.

Meno mal di testa rispetto alla creazione e al monitoraggio di un demone.

* Se stai usando PHP, ricorda clearstatcache ().

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.