Dove posso impostare le variabili di ambiente che crontab utilizzerà?
-
19-09-2019 - |
Domanda
Ho un crontab in esecuzione ogni ora.L'utente che lo esegue ha variabili di ambiente nel file .bash_profile
che funzionano quando l'utente esegue il lavoro dal terminale, tuttavia, ovviamente questi non vengono rilevati da crontab quando viene eseguito.
Ho provato a inserirli .profile
E .bashrc
ma ancora non sembrano essere presi.Qualcuno sa dove posso mettere le variabili di ambiente che crontab può raccogliere?
Soluzione
avere 'cron' eseguire uno script di shell che imposta l'ambiente prima di eseguire il comando.
Sempre.
# @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
# Crontab file for Home Directory for Jonathan Leffler (JL)
#-----------------------------------------------------------------------------
#Min Hour Day Month Weekday Command
#-----------------------------------------------------------------------------
0 * * * * /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
1 1 * * * /usr/bin/ksh /work1/jleffler/bin/Cron/daily
23 1 * * 1-5 /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
2 3 * * 0 /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
21 3 1 * * /usr/bin/ksh /work1/jleffler/bin/Cron/monthly
Gli script in ~ / bin / Cron sono tutti i link a un singolo script, 'runcron', che si presenta come:
: "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
#
# Commands to be performed by Cron (no debugging options)
# Set environment -- not done by cron (usually switches HOME)
. $HOME/.cronfile
base=`basename $0`
cmd=${REAL_HOME:-/real/home}/bin/$base
if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi
exec $cmd ${@:+"$@"}
(Scritto utilizzando un vecchio standard di codifica -. Al giorno d'oggi, userei uno shebang '! #' All'inizio)
Il '~ / .cronfile' è una variazione sul mio profilo per l'uso da cron - rigorosamente non interattiva e non facendo eco per il gusto di essere rumoroso. Si potrebbe organizzare per eseguire il .profile e così via, invece. (La roba REAL_HOME è un artefatto del mio ambiente -. Si può fingere che è lo stesso di $ HOME)
Quindi, questo codice legge l'ambiente appropriato e poi esegue la versione non-Cron del comando dalla mia home directory. Così, per esempio, il mio comando 'feriale' appare come:
: "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
# Commands to be done each weekday
# Update ICSCOPE
n.updics
Il comando 'quotidiano' è semplice:
: "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
#
# Commands to be done daily
# Nothing -- most things are done on weekdays only
exit 0
Altri suggerimenti
È possibile definire variabili di ambiente nel crontab per sé quando si esegue crontab -e
dalla riga di comando.
LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h dom mon dow command
* * * * * sleep 5s && echo "yo"
Questa funzione è disponibile solo per alcune implementazioni di cron. Ubuntu e Debian attualmente utilizzano vixie-cron che permette questi per essere dichiarati nel file crontab (anche GNU mcron ).
Archlinux e RedHat uso Cronie che non fa consentono variabili d'ambiente da dichiarare e getterà gli errori di sintassi nel cron.log. Soluzione alternativa può essere fatto per-voce:
# m h dom mon dow command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"
ho ottenuto una soluzione in più per questo problema:
0 5 * * * . $HOME/.profile; /path/to/command/to/run
In questo caso si riprenderà tutta la variabile d'ambiente definita nel file $HOME/.profile
.
Naturalmente $HOME
non è anche impostato, è necessario sostituirlo con il percorso completo del vostro $HOME
.
Impostazione Vars in /etc/environment
anche lavorato per me in Ubuntu. A partire da 12.04, variabili in /etc/environment
vengono caricati per cron.
Ampliando esempio @carestad, che trovo più facile, è quello di eseguire lo script con cron e avere l'ambiente nello script.
Nel file di crontab -e:
SHELL=/bin/bash
*/1 * * * * $HOME/cron_job.sh
Nel file di cron_job.sh:
#!/bin/bash
source $HOME/.bash_profile
some_other_cmd
Qualsiasi comando dopo che la fonte di Bash_profile avrà il proprio ambiente come se collegato.
Se si avvia gli script si sta eseguendo attraverso cron con:
#!/bin/bash -l
Si dovrebbero prendere le variabili d'ambiente ~/.bash_profile
Per quanto mi riguarda ho dovuto impostare la variabile d'ambiente per un'applicazione PHP. I resloved aggiungendo il seguente codice al mio crontab.
$ sudo crontab -e
crontab:
ENVIRONMENT_VAR=production
* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php
e dentro doSomethingWonderful.php ho potuto ottenere il valore di ambiente con:
<?php
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"
Spero che questo aiuta!
Qualunque sia impostato in crontab
sarà disponibile nelle cronjobs, sia direttamente che tramite le variabili negli script.
usarli nel definizione del cronjob
È possibile configurare crontab
in modo che imposta le variabili che poi la può cronjob uso:
$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello
Ora il file /tmp/hello
mostra le cose come:
$ cat /tmp/hello
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016
Usali nello script gestito da cronjob
È possibile configurare crontab
in modo che imposta le variabili che poi gli script possono utilizzare:
$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh
E dire che lo script /tmp/myscript.sh
è come questo:
echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res
Si genera un file di proiezione /tmp/myoutput.res
:
$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...
Al posto di
0 * * * * sh /my/script.sh
Utilizzare bash -l -c
0 * * * * bash -l -c 'sh /my/script.sh'
Ampliando @ Robert Brisita ha appena ampliata, anche se non si desidera impostare tutte le variabili del profilo nello script, è possibile selezionare le variabili da esportare sulla parte superiore dello script
Nel file di crontab -e:
SHELL=/bin/bash
*/1 * * * * /Path/to/script/script.sh
In script.sh
#!/bin/bash
export JAVA_HOME=/path/to/jdk
some-other-command
Un altro modo: ispirato da questo questa risposta - per "iniettare" le variabili è il seguente (esempio fcron):
%daily 00 12 \
set -a; \
. /path/to/file/containing/vars; \
set +a; \
/path/to/script/using/vars
Da help set
:
-a Contrassegna le variabili modificate o create per l'esportazione.
L'uso di + invece di - fa sì che questi flag vengano disattivati.
Quindi tutto quello che c'è in mezzo set -
E set +
viene esportato in env
ed è quindi disponibile per altri script, ecc.Senza usare set
le variabili vengono originate ma vivono set
soltanto.
A parte questo, è utile passare variabili anche quando un programma richiede l'esecuzione di un account non root ma avresti bisogno di alcune variabili all'interno dell'ambiente dell'altro utente.Di seguito è riportato un esempio che passa nullmailer vars per formattare l'intestazione dell'e-mail:
su -s /bin/bash -c "set -a; \
. /path/to/nullmailer-vars; \
set +a; \
/usr/sbin/logcheck" logcheck
Ho provato la maggior parte delle soluzioni fornite, ma niente ha funzionato in un primo momento. Si scopre, però, che non sono state le soluzioni che non sono riusciti a lavorare. A quanto pare, il mio file ~/.bashrc
inizia con il seguente blocco di codice:
case $- in
*i*) ;;
*) return;;
esac
Questo è fondamentalmente un case statement
che controlla l'attuale serie di opzioni nella shell corrente per determinare che la shell è in esecuzione in modo interattivo.
Se il guscio sembra essere in esecuzione interattivamente, allora si perviene ad approvvigionarsi file ~/.bashrc
.
Tuttavia, in una shell invocata dal cron
, la variabile $-
non contiene il valore che indica i
interattività.
Pertanto, il file non viene mai ~/.bashrc
provenienza completamente. Di conseguenza, le variabili di ambiente non ha mai avuto insieme.
Se questo sembra essere il problema, non esitate a commentare il blocco di codice come segue e riprovare:
# case $- in
# *i*) ;;
# *) return;;
# esac
Spero che questo risulta utile
Sto usando Oh-my-zsh
nel mio macbook così ho provato molte cose per ottenere viene eseguita l'operazione crontab ma alla fine, la mia soluzione era anteponendo il .zshrc
prima del comando da eseguire.
*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js
Questa attività viene eseguita ogni 30 minuti e utilizza il profilo .zshrc
per eseguire il mio comando nodo.
Non dimenticare di utilizzare il punto prima della $HOME
var.