it-swarm.com.de

Wie schreibe ich ein Bash-Skript, um die globale Umgebungsvariable festzulegen?

Vor kurzem habe ich ein Skript geschrieben, das eine Umgebungsvariable einstellt.

#!/bin/bash

echo "Pass a path:"
read path
echo $path

defaultPath=/home/$(whoami)/Desktop

if [ -n "$path" ]; then
    export my_var=$path
else
    echo "Path is empty! Exporting default path ..."
    export my_var=$defaultPath
fi

echo "Exported path: $my_var"

Es funktioniert einfach großartig, aber das Problem ist, dass my_var nur lokal verfügbar ist. Ich meine im Konsolenfenster, wo ich das Skript ausgeführt habe. 

Wie schreibe ich ein Skript, mit dem ich global Umgebungsvariable exportieren kann, die überall sichtbar sind?

35
Katie

Jede Shell hat ihre eigene Umgebung. Es gibt keine Universal - Umgebung, die in allen Konsolenfenstern magisch erscheint. Auf eine in einer Shell erstellte Umgebungsvariable kann nicht in einer anderen Shell zugegriffen werden.

Es ist noch restriktiver. Wenn eine Shell eine Subshell erzeugt, hat diese Subshell Zugriff auf die Umgebungsvariablen des übergeordneten Elements. Wenn diese Subshell jedoch eine Umgebungsvariable erstellt, ist sie in der übergeordneten Shell nicht verfügbar.

Wenn alle Ihre Shells Zugriff auf denselben Variablensatz benötigen, können Sie eine startup -Datei erstellen, die diese für Sie festlegt. Dies geschieht in BASH über die $HOME/.bash_profile- und $HOME/.bashrc-Dateien und über $HOME/.profile, falls $HOME/.bash_profile nicht existiert. Andere Shells haben einen eigenen Satz von Startdateien. Eine wird für Anmeldungen verwendet, und eine wird für Shells verwendet, die ohne Anmeldungen erstellt werden. In der Manpage erfahren Sie genau, welche Startskripts verwendet werden und in welcher Reihenfolge sie ausgeführt werden.

Sie können versuchen, Shared Memory zu verwenden, aber ich glaube, dass dies nur während der Ausführung von Prozessen funktioniert. Wenn Sie also einen Weg gefunden haben, ein Shared Memory festzulegen, würde es verschwinden, sobald der Befehl beendet ist. (Außer bei Named Pipes habe ich selten Shared Memory verwendet). Ansonsten gibt es wirklich keine Möglichkeit, eine Umgebungsvariable in einer Shell festzulegen und von einer anderen Shell automatisch abgerufen zu werden. Sie können versuchen, named Pipes oder diese Umgebungsvariable in eine Datei zu schreiben, damit andere Shells sie aufnehmen können.

Stellen Sie sich die Probleme vor, die auftreten könnten, wenn jemand ohne mein Wissen die Umgebung einer Shell ändern könnte.

35
David W.

Führen Sie einfach Ihr Shell-Skript aus, dem "." (Punkt Leerzeichen) vorangestellt ist.

Dadurch führt das Skript die Anweisungen in der ursprünglichen Shell aus. Somit sind die Variablen auch nach Abschluss des Skripts noch vorhanden

Ex:

cat setmyvar.sh
export myvar=exists

. ./setmyvar.sh

echo $myvar
exists
83
JDembinski

Aus dem zweiten Absatz der Antwort von David W. wurde folgendes extrahiert: "Wenn eine Shell eine Subshell erzeugt, hat diese Subshell Zugriff auf die Umgebungsvariablen des übergeordneten Elements. Wenn diese Subshell jedoch eine Umgebungsvariable erstellt, ist sie in der übergeordneten Shell nicht verfügbar. "

Wenn ein Benutzer die übergeordnete Shell auf Ihre neuen Umgebungsvariablen zugreifen muss, geben Sie einfach den folgenden Befehl in der übergeordneten Shell ein:

source <your_subshell_script>

oder über eine Verknüpfung

. <your_subshell_script>
2
Jonathan L

Sie müssen die Variable in Ihr .profile unter /home/$USER/.profile einfügen

Sie können das mit diesem Befehl tun:

echo 'TEST="hi"' >> $HOME/.profile

Oder bearbeiten Sie die Datei mit emacs, zum Beispiel ..__ Wenn Sie diese Variable für alle Benutzer festlegen möchten, müssen Sie/etc/profile (root) bearbeiten.

2
MarcD

~/.bin/SOURCED/lazy-Skript zum Speichern und Laden von Daten als flache Dateien für das System. 

[ ! -d ~/.megadata ] && mkdir ~/.megadata

function save_data {
[ -z "$1" -o -z "$2" ] && echo 'save_data [:id:] [:data:]' && return
local overwrite=${3-false}
[ "$overwrite" = 'true' ] && echo "$2" > ~/.megadata/$1 && return
[ ! -f ~/.megadata/$1 ]   && echo "$2" > ~/.megadata/$1 || echo ID TAKEN set third param to true to overwrite
}

save_data computer engine
cat ~/.megadata/computer
save_data computer engine
save_data computer megaengine true

function get_data {
[ -z "$1" -o -f $1 ] && echo 'get_data [:id:]' && return


[ -f ~/.megadata/$1 ]   && cat ~/.megadata/$1 || echo ID NOT FOUND
:
}

get_data computer
get_data computer
1
Arcabard

Wenn Sie Umgebungsvariablen in Shell-Skripts dynamisch festlegen und referenzieren müssen, gibt es eine Problemumgehung. Beurteilen Sie selbst, ob es sich lohnt zu tun, aber hier ist es.

Die Strategie besteht darin, ein "set" -Skript zu haben, das dynamisch ein "load" -Skript schreibt, das Code zum Setzen und Exportieren einer Umgebungsvariablen enthält. Das "load" -Skript wird dann periodisch von anderen Skripts ausgeführt, die auf die Variable verweisen müssen. Übrigens, die gleiche Strategie könnte durch Schreiben und Lesen einer Datei anstelle einer Variablen erfolgen.

Hier ist ein kurzes Beispiel ...

Set_Load_PROCESSING_SIGNAL.sh

#!/bin/bash
PROCESSING_SIGNAL_SCRIPT=./Load_PROCESSING_SIGNAL.sh
echo "#!/bin/bash" > $PROCESSING_SIGNAL_SCRIPT
echo "export PROCESSING_SIGNAL=$1" >> $PROCESSING_SIGNAL_SCRIPT
chmod ug+rwx $PROCESSING_SIGNAL_SCRIPT

Load_PROCESSING_SIGNAL.sh (wird dynamisch erstellt, wenn das obige ausgeführt wird)

#!/bin/bash
export PROCESSING_SIGNAL=1

Sie können dies mit Test_PROCESSING_SIGNAL.sh testen

#!/bin/bash
PROCESSING_SIGNAL_SCRIPT=./Load_PROCESSING_SIGNAL.sh
N=1
LIM=100
while [ $N -le $LIM ]
do
# DO WHATEVER LOOP PROCESSING IS NEEDED
echo "N = $N"
sleep 5
N=$(( $N + 1 ))

# CHECK PROCESSING_SIGNAL
source $PROCESSING_SIGNAL_SCRIPT
if [[ $PROCESSING_SIGNAL -eq 0 ]]; then
# Write log info indicating that the signal to stop processing was detected
# Write out all relevent info
# Send an alert email of this too
# Then exit
echo "Detected PROCESSING_SIGNAL for all stop. Exiting..."
exit 1
fi
done
1
wxwizard

In UNIX gibt es wirklich keine globale Umgebung.

Jeder Prozess verfügt über eine Umgebung, die ursprünglich vom übergeordneten Element geerbt wurde, ist jedoch nach der ersten Erstellung lokal für den Prozess.

Sie können nur Ihre eigenen Einstellungen ändern, es sei denn, Sie verwenden dabei einen Debugger.

1
perh

Umgebungsvariablen sind immer "lokal", um die Ausführung des Exportbefehls zu verarbeiten, um Umgebungsvariablen für Unterprozesse festzulegen. Unter .bashrc können Sie Umgebungsvariablen zu Beginn einer Bash-Shell festlegen. Was Sie zu tun versuchen, scheint nicht möglich zu sein, da ein Prozess keine Umgebungsvariablen eines anderen Prozesses ändern kann (oder auf ihn zugreifen kann).

1

Sie können die Datei ~/.bashrc oder ~/.bash_profile aktualisieren, die zum Initialisieren der Umgebung verwendet wird.

1
Jin Kim

schreiben Sie es in eine temporäre Datei, sagen wir ~/.myglobalvar und lesen Sie es von überall aus

echo "$myglobal" > ~/.myglobalvar
1
Sergio Abreu

Schauen Sie sich das Ladeverhalten Ihrer Shell an (erklärt in der Manpage, normalerweise bezogen auf .XXXshrc oder .profile). Einige Konfigurationsdateien werden beim Anmelden einer interaktiven Shell geladen, andere werden bei jeder Ausführung einer Shell geladen. Wenn Sie Ihre Variable in letzterem platzieren, kann dies zu dem gewünschten Verhalten führen, z. Wenn die Variable immer mit dieser eindeutigen Shell festgelegt ist (z. B. bash).

1
count0

Tatsächlich habe ich einen Weg gefunden, dies zu erreichen (was in meinem Fall war, ein Bash-Skript zu verwenden, um eine Reihe von Sicherheitsberechtigungen festzulegen)

Ich rufe einfach bash aus dem Skript heraus auf und die erzeugte Shell hat jetzt die Exportwerte

export API_USERNAME=abc
export API_PASSWORD=bbbb
bash

wenn Sie nun die Datei mit ~/.app-x-setup.sh aufrufen, erhalten Sie eine interaktive Shell mit diesen Umgebungswerten

1
Dinis Cruz