Come rendere il servizio unix vedere le variabili di ambiente?


52

Ho impostato la mia variabile d'ambiente usando /etc/profile:

export VAR=/home/userhome

Quindi se lo faccio echo $VARlo dimostra/home/userhome

Ma quando inserisco il riferimento a questa variabile nel /etc/init.d/servicenamefile, non riesco a trovare questa variabile. Quando corro service servicename statususando il /etc/init.d/servicenamefile con il seguente contenuto:

case "$1" in
status)    
    cd $VAR/dir
    ;;
esac

dice /dir: No such file or directory

Ma funziona se corro /etc/init.d/servicename statusinvece diservice servicename status

Come posso fare in modo che il servizio Unix veda le variabili di ambiente?


Notare che richiamando il sistema 5 rcscript direttamente anche non funziona in questo modo su sistemi operativi systemd, come tutte le chiamate di script vengono trasformati in invocazioni di systemctlda un gancio nascosto.
JdeBP,

Risposte:


70

Il problema è serviceeliminare tutte le variabili d'ambiente ma TERM, PATHed LANGè una buona cosa. Se si esegue direttamente lo script, nulla rimuove le variabili di ambiente, quindi tutto funziona.

Non vuoi fare affidamento su variabili di ambiente esterne perché all'avvio la variabile di ambiente probabilmente non è presente e il tuo sistema init probabilmente non la imposta comunque.

Se vuoi ancora fare affidamento su tali variabili, procurati un file e leggi le variabili da esso, ad esempio crea /etc/default/servicenamecon il contenuto:

VAR=value

e procuralo dal tuo script init, ad esempio:

[ -f /etc/default/service-name ] && . /etc/default/service-name

if [ -z "$VAR" ] ;  then
  echo "VAR is not set, please set it in /etc/default/service-name" >&2
  exit 1
fi

case "$1" in
status)    
    cd "$VAR"/dir
    ;;
esac

13
Molto utile, grazie. Per altri neofiti di Linux, ecco la roba criptica di Bash. [ ... ]è una scorciatoia per un test condizionale; vedi questa risposta . -fè un ifargomento per verificare l'esistenza del file. &&è un operatore in corto circuito: esegue il secondo comando solo se il primo esce con 0. .operatore sorgente o punto: legge ed esegue i comandi dall'argomento nomefile. -zè un ifargomento per verificare la presenza di una stringa di lunghezza zero. >&2invia output a stderr. Vedi anche Introduzione a if .
Mark Berry,

@MarkBerry -fè parte di [, no if.
Chris Down,

@ Chris, grazie. Quindi " [ ... ]è una scorciatoia per un testcomando condizionale ; vedere questa risposta . -fÈ un testargomento per verificare se esiste un file".
Mark Berry,

@MarkBerry Correct. Puoi pensare [(o test) come solo un altro comando: tutto ifciò che devi fare è agire in base allo stato di uscita.
Chris Down,

Mi sono imbattuto in una situazione simile a questa, ma non ho bisogno $VARdi essere nello script init, ho bisogno che sia disponibile per un diverso programma 2 o 3 chiamate a valle dello script init. Per esempio. Lo script init chiama start-stop-daemon che chiama Program 1 (Java) che chiama Program 2 di cui ha bisogno $VAR. Ho provato il trucco in questa risposta, ma non sembra funzionare nella mia situazione. Come posso assicurarmi che $VARsarà disponibile per il Programma 2?
FrustratedWithFormsDesigner

1

Nel mio caso, avevo bisogno di un RAILS_ENVche è stato fissato in /etc/bash.bashrc: export RAILS_ENV=staging. Ho aggiunto $(grep RAILS_ENV /etc/bash.bashrc)e questo ha reso la variabile disponibile per lo script. L'ho fatto in questo modo, quindi non ho dovuto includere il resto del file.


-1

Una brutta soluzione che funzionerà anche:

function exec() {
    args=( $@ )
    command=${args[0]}
    dummy=${args[1]}
    whoami=`whoami`
    if [ -z "$dummy" ]; then
        me=`basename $0`
        runuser -l ${whoami} -c "bash /etc/init.d/${me} ${command} dummy"
    else
       printenv
   fi
}

case $1 in
    status)
        status
        ;;
    start|stop|kill|restart)
        exec $*
        ;;
    *)
        usage
esac
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.