Wie werden globale Umgebungsvariablen beim Booten über ein Skript festgelegt und für eine Anwendung verfügbar, die vor der Anmeldung ausgeführt wird?

17

Ich habe einen Dienst, der beim Booten ausgeführt wird, und in diesem Dienst wird im Hintergrund ein Bash-Skript aufgerufen, das einige Umgebungsvariablen exportiert. Das Problem, das ich habe, ist, dass diese Umgebungsvariablen nicht an das übergeordnete Element des Hintergrundprozesses gesendet werden. Sobald mein Skript ausgeführt ist, sind sie verschwunden.

Darüber hinaus ruft der Dienst nach Ausführung des Skripts ein anderes Skript auf, mit dem eine von mir verwendete Anwendung gestartet wird. Diese Anwendung benötigt Zugriff auf diese Umgebungsvariablen.

Das RHEL-System, auf dem ich es ausführe, soll niemals vom Benutzer angemeldet werden. Es bootet nur und startet die Anwendung. Ich weiß, dass Umgebungsvariablen für einen übergeordneten Prozess / eine übergeordnete Shell nicht wirklich von einer untergeordneten Hintergrundprozess-Shell festgelegt werden können.

Ich brauche eine Möglichkeit, dies durch ein Skript zu tun, das von meinem Dienst aufgerufen wird (allerdings nicht unbedingt im Hintergrund), nicht indem ich sie meinem Dienst hinzufüge (was auch für mich nicht funktionierte) und nicht indem ich sie in einem /etc/environmentoder speichere .profileoder so etwas.

In meinem Dienst habe ich versucht, die Umgebungsvariablen hinzuzufügen (was ich aber nicht tun möchte):

    export TEST=192.168.1.1

Das habe ich auch in meinem Dienst versucht:

    TEST=192.168.1.1
    export TEST=${TEST}

Ich habe versucht zu ändern, wie mein Dienst das Bash-Skript aufruft:

    /bin/asdf/script &

Ich habe auch versucht, das Skript so zu beschaffen, dass es in derselben Shell ausgeführt wird (die ich daraus erhalten habe ):

    . ./bin/asdf/script
    #I'm very confused why this didn't work

Ich fand auch diese , die interessant aussahen , aber es nicht wirklich in meinem Fall pan out.

sqenixs
quelle

Antworten:

12

Sie können versuchen, ein Skript zu erstellen, in dem die Variablen gesammelt werden /etc/profile.d/

Beispiel:

/etc/profile.d/somescript.sh

#!/bin/bash
TEST=$(cat /var/somefile)
export $TEST

/etc/profileführt einen Aufruf aus, in dem ein Skript ausgeführt /etc/profile.d/wird. Dies gilt für alle Benutzer auf dem System, einschließlich root.

madflojo
quelle
Sie können auf etwas hier sein. Ich möchte jedoch nicht genau das tun, da das Skript aus IA-Gründen nicht im Verzeichnis / etc gefunden werden kann. Aber ich denke, ich kann dort einen Symlink erstellen, der auf mein Skript verweist. Um die Sache zu verkomplizieren, stammen einige der Umgebungsvariablen, die vom Skript festgelegt werden, von Umgebungsvariablen, die vom Dienst festgelegt werden. Dies funktioniert möglicherweise nicht, da die Variablen bereits festgelegt sein müssen, bevor das Dienstskript beendet ist, aber nicht zu früh, oder die erforderlichen Umgebungsvariablen wurden noch nicht vom Dienst erstellt.
sqenixs
Ich denke, ich kann die Abhängigkeit von den im Dienst festgelegten Variablen loswerden. In diesem Fall wird es funktionieren, solange das Skript ausgeführt wird, bevor der Dienst gestartet wird. Wissen Sie, wann die Login-Shell gestartet wird? Oder kann ich steuern, wann die Login-Shell startet? Ich habe keinen Dienst dafür im Verzeichnis rcX.d für meinen Runlevel.
sqenixs
1

Es gibt keine Möglichkeit, dass ein Prozess die Umgebung eines anderen vorhandenen Prozesses beeinflusst. Prozesse beeinflussen nur die Umgebung ihrer untergeordneten Prozesse.

Sie müssen diese Umgebungsvariablen also in einem Vorgänger der Anwendung festlegen, die sie benötigt. Anstatt dass Ihr Service das Bash-Skript für die Umgebungseinstellung und die Anwendung separat aufruft, rufen Sie von Ihrem Service ein Bash-Skript auf, das die Umgebungsvariablen festlegt, und starten Sie dann die Anwendung.

#!/bin/bash
. /path/to/environment/variable/setter.bash
exec /path/to/application
Gilles 'SO - hör auf böse zu sein'
quelle
Nach dem, was ich online gelesen habe, gibt es Hacks (etwas, das mit eval in einem Quellenskript oder mit gdb zu tun hat), um es zum Laufen zu bringen. Ich bin nicht besonders daran interessiert, dass es im Hintergrund läuft. Wenn ich die Befehle in der aktuellen "Shell" ausführen kann (befinden Sie sich während des Startvorgangs in einer Shell, wenn Ihr Dienst ausgeführt wird?), Ist das auch in Ordnung.
sqenixs
Leider kann ich die Anwendung nicht über den Dienst starten, da viele verschiedene Prozesse gestartet und Dinge über das Anwendungsstartskript konfiguriert werden und vom Dienst für IA getrennt werden müssen.
sqenixs
@sqenixs Eine Schale ist ein Prozess , wie jedes andere. Es gibt nicht so etwas wie „in einer Schale zu sein“. Wenn Sie von "eval on a source script" sprechen, ist dies ein Protokoll, bei dem ein Programm (das möglicherweise kein Shell-Skript ist) Definitionen in Shell-Syntax ausgibt und von einem Shell-Skript interpretiert wird. Das Setzen von Umgebungsvariablen mit gdb könnte funktionieren, keine Auswirkungen haben oder Ihre Anwendung zum Absturz bringen. Wie Sie sich vorstellen können, wird die Verwendung eines Debuggers in der Produktion nicht empfohlen (und dies wiederum aus gutem Grund).
Gilles 'SO - hör auf böse zu sein'
Es gibt wahrscheinlich eine Lösung für Ihr Problem, aber Sie müssen Ihre Anforderungen präziser formulieren. In Ihrer Frage schreiben Sie: "Nachdem das Skript ausgeführt wurde, ruft der Dienst ein anderes Skript auf, mit dem eine Anwendung gestartet wird." So scheinen Sie eine Lösung zu haben: Setzen Sie die Umgebungsvariablen innerhalb dieses anderen Skript. In einem Kommentar schreiben Sie jedoch, dass Sie die Anwendung nicht über den Dienst starten können. Also, was ist das?
Gilles 'SO- hör auf böse zu sein'
Erstellen oder konfigurieren Sie möglicherweise die Umgebung von / sbin / init zum Startzeitpunkt. Da jeder Prozess sowieso ein Kind von init ist, kann ein Kindprozess die Umgebung erfassen. Nur ein Gedanke / Vermutung.
Nikhil Mulley