Wie kann man einen Unix-Dienst Umgebungsvariablen anzeigen lassen?

52

Ich habe meine Umgebungsvariable gesetzt mit /etc/profile:

export VAR=/home/userhome

Dann wenn ich es tue echo $VARzeigt/home/userhome

Wenn ich jedoch einen Verweis auf diese Variable in die /etc/init.d/servicenameDatei lege , kann sie diese Variable nicht finden. Wenn ich laufe service servicename statusmit /etc/init.d/servicenameDatei mit folgendem Inhalt:

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

es sagt /dir: No such file or directory

Aber es funktioniert wenn ich /etc/init.d/servicename statusstatt renneservice servicename status

Wie kann ich den Unix-Dienst Umgebungsvariablen anzeigen lassen?

altern
quelle
Beachten Sie, dass das rcdirekte Aufrufen des System 5- Skripts auf systemd-Betriebssystemen ebenfalls nicht auf diese Weise funktioniert, da alle Aufrufe des Skripts systemctldurch einen versteckten Hook in Aufrufe von umgewandelt werden.
JdeBP

Antworten:

70

Das Problem ist serviceaber TERM, dass alle Umgebungsvariablen entfernt werden , PATHund LANGdas ist eine gute Sache. Wenn Sie das Skript direkt ausführen, werden die Umgebungsvariablen durch nichts entfernt, sodass alles funktioniert.

Sie möchten sich nicht auf externe Umgebungsvariablen verlassen, da die Umgebungsvariable beim Start wahrscheinlich nicht vorhanden ist und Ihr Init-System sie wahrscheinlich sowieso nicht setzt.

Wenn Sie sich dennoch auf solche Variablen verlassen möchten, geben Sie eine Datei ein und lesen Sie die Variablen aus, z. B. erstellen Sie /etc/default/servicenamemit dem Inhalt:

VAR=value

und entpacke es aus deinem Init-Skript, zB:

[ -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
Ulrich Dangel
quelle
13
Sehr hilfreich, danke. Für andere Linux-Neulinge gibt es hier das kryptische Bash-Zeug. [ ... ]ist eine Abkürzung für eine bedingte Prüfung; siehe diese Antwort . -fist ein ifArgument, um zu prüfen, ob eine Datei existiert. &&ist ein Kurzschlussoperator: Führen Sie den zweiten Befehl nur aus, wenn der erste mit 0 beendet wird. .Quell- oder Punktoperator: Lesen Sie Befehle aus dem Dateinamenargument und führen Sie sie aus. -zist ein ifArgument, um nach einer Zeichenfolge mit der Länge Null zu suchen. >&2Ausgabe an stderr senden. Siehe auch Einführung in if .
Mark Berry
@MarkBerry -fist ein Teil von [, nicht if.
Chris Down
@ ChrisDown, danke. So „ [ ... ]ist eine Abkürzung für einen bedingten testBefehl, siehe diese Antwort . -fIst ein testArgument zu überprüfen , ob eine Datei vorhanden ist .“
Mark Berry
@ MarkBerry Richtig. Sie können sich [(oder test) nur einen anderen Befehl vorstellen - alles, was Sie iftun müssen, ist eine Aktion basierend auf dem Beendigungsstatus durchzuführen.
Chris Down
Ich habe eine ähnliche Situation erlebt, muss mich aber nicht $VARim Init-Skript befinden, sondern muss für ein anderes Programm verfügbar sein. 2 oder 3 Aufrufe nach dem Init-Skript. Z.B. Das init-Skript ruft den start-stop-daemon auf, der das Programm 1 (Java) aufruft und das Programm 2 aufruft, das es benötigt $VAR. Ich habe den Trick in dieser Antwort ausprobiert, aber es scheint in meiner Situation nicht zu funktionieren. Wie kann ich sicherstellen, dass $VARProgramm 2 verfügbar ist?
FrustratedWithFormsDesigner
1

In meinem Fall musste ich ein , RAILS_ENVdie in gesetzt wurde /etc/bash.bashrc: export RAILS_ENV=staging. Ich fügte hinzu $(grep RAILS_ENV /etc/bash.bashrc)und das machte die Variable für das Skript verfügbar. Ich tat es auf diese Weise, also musste ich den Rest der Akte nicht mit einschließen.

geermc4
quelle
-1

Eine hässliche Lösung, die auch funktionieren wird:

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
Maksim
quelle