Problema con $ RANDOM in crontab


9

Ho uno strano problema con $ RANDOM in cron. Vorrei eseguire un comando un numero casuale di minuti dopo l'attivazione del cronjob.

Questo esempio funziona direttamente nel terminale e ritarda il comando fino a 30 secondi (sostituisci il comando con quello che vuoi, in realtà è un'eco a / dev / ttyUSB0):

sleep `expr $RANDOM \% 30` ; command

Se la stessa linea viene inserita in crontab, il comando si attiva sempre immediatamente senza ritardo:

* * * * * sleep `expr $RANDOM \% 30` ; command

Se uso un'espressione senza $ RANDOM, funziona benissimo - questo fa un ritardo di 15 secondi:

* * * * * sleep `expr 10 + 5` ; command

In altre parole, sembra che $ RANDOM non funzioni in un cron.

Ma non è semplicemente perché $ RANDOM stesso viene valutato a zero, perché ciò dovrebbe dare un ritardo di 10:

* * * * * sleep `expr $RANDOM \% 30 + 10` ; command

Ho anche provato con && instread di; ma questo non aiuta. In effetti, quindi il comando non si attiva affatto!

Potrei ovviamente inserire il ritardo in uno script che viene quindi chiamato da crontab, ma ciò non spiega il mio problema e non mi fa imparare :-)

È Debian Lenny se questo fa la differenza.

Risposte:


17

cronusa la /bin/shshell per eseguire le attività. In alcune distro, questo è un link simbolico a dash. Nessuno dei due supporta la $RANDOMvariabile, che è bashun'estensione specifica.

  • Con vixie-cron, puoi mettere una linea SHELL=/bin/bashnella parte superiore del tuo crontab.

  • Altrimenti, dovrai accontentarti di bash -c 'echo $RANDOM'o perl -e 'print int(rand(65535))'.

    (Nell'esempio sopra, 65535 è il numero massimo da restituire. Puoi applicare anche altri calcoli all'interno dello script.)

  • In un sistema correttamente configurato, ne saresti stato informato da cronsolo: invia sempre l'output del lavoro, inclusi i messaggi di errore, tramite e-mail. Installa un MTA leggero.


Inoltre, in bash, $(( ))è preferito rispetto a `expr`.


L'ultima volta che ho controllato, /bin/shnon era una vera shell, ma semplicemente un link simbolico alla shell preferita del sysadmin (tipicamente bash o dash) su Debian.
Ciao,

1
@ Hello71: che è quello che ho detto nel post. Tuttavia, è consuetudine invocare il software di sistema /bin/sh(e aspettarsi che sia compatibile con la shell Bourne). Un esempio è la system()funzione in glibc. Pertanto di /bin/shsolito punta alla shell più veloce compatibile con Bourne; e si suppone che l'amministratore di sistema abbia impostato le sue preferenze nella riga appropriata di / etc / passwd, non per far applicare tale preferenza a livello di sistema
user1686

@ Hello71: ... ok, soprattutto quello che ho detto nel post. (Conosco la maggior parte delle altre distribuzioni collegate sha bash, ma non sembra pertinente.)
user1686

Hai ragione, /bin/shpunta al trattino. Fino ad ora, non ho mai sentito parlare di trattino. L'ho cercato ed è una variante leggera di bash. Inoltre, non sapevo che cron funzionasse in un ambiente "paralizzato", ma spiega vari altri problemi che ho avuto in passato. A proposito, ho iniziato a usare $(())ma dato che non ha funzionato ho provato tutti i tipi di variazioni e ho finito con expr- che ovviamente non ha funzionato neanche. Ma è lì che ho finito :-) È possibile eseguire una normale shell bash senza usare le limitazioni bash -c 'xxxx'? A proposito, non è possibile inserire interruzioni di riga nei commenti?
Marlar

@marlar: 1) dashè una shell. Non è più o meno normale di bash. Non è nemmeno una variante. 2) Vedi i punti 1 e 2 nella risposta.
user1686

2

crondi solito viene eseguito con un ambiente meno "completo", il che significa che semplicemente non hai molte delle stesse variabili di ambiente disponibili. Apparentemente $RANDOMè uno di questi, e in effetti il ​​tuo sleepcomando sta semplicemente fallendo con un errore a causa della variabile indefinita - motivo per cui il tuo comando non è stato eseguito affatto quando sei passato a &&invece di ;. (Beh, in realtà, $RANDOMè una funzione Bash, ma cronnon funziona in un ambiente Bash completo, che evidentemente manca di questa funzione.)

Per compiere questo compito, dovrai usare uno script Bash separato, come hai detto. In alternativa, potresti essere in grado di capire un modo per utilizzare cat /dev/urandomdirettamente nel croncomando, ma probabilmente sarebbe più semplice spostare ciò che hai attualmente in uno script Bash separato.


1
Non è carino, ma ho trovato questa soluzione analoga al tuo suggerimento: sleep $ (expr od -An -N1 -i /dev/urandom\% 30); di comando
Marlar

1
$RANDOMnon fa parte di un ambiente "completo". Non ha nulla a che fare con le variabili di ambiente impostate all'avvio del processo. È una variabile speciale creata "al volo" in bash. Il suo nuovo valore viene sempre generato ogni volta che viene letta la variabile. --- cronper impostazione predefinita utilizza /bin/shcosì su sistemi a cui /bin/shnon è collegato bash $RANDOMnon funzionerà per impostazione predefinita.
pabouk,
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.