Nehmen wir an, ich habe ein Shell / Bash-Skript mit dem Namen test.sh
:
#!/bin/bash
TESTVARIABLE=hellohelloheloo
./test2.sh
Mein test2.sh
sieht so aus:
#!/bin/bash
echo ${TESTVARIABLE}
Das funktioniert nicht. Ich möchte nicht alle Variablen als Parameter übergeben, da dies imho übertrieben ist.
Gibt es einen anderen Weg?
Antworten:
Sie haben grundsätzlich zwei Möglichkeiten:
export TESTVARIABLE
), bevor Sie das 2. Skript ausführen.. test2.sh
und es wird in der gleichen Shell ausgeführt. Auf diese Weise können Sie komplexere Variablen wie Arrays problemlos gemeinsam nutzen, das andere Skript kann jedoch auch Variablen in der Quellshell ändern.AKTUALISIEREN:
Zum
export
Festlegen einer Umgebungsvariablen können Sie entweder eine vorhandene Variable verwenden:Dies sollte in beide arbeiten
bash
undsh
.bash
ermöglicht auch die Kombination wie folgt:Dies funktioniert auch in meinem
sh
(was zufällig istbash
, können Sie verwenden, umecho $SHELL
zu überprüfen). Aber ich glaube nicht, dass das garantiert in allen funktioniertsh
, also gehen Sie am besten auf Nummer sicher und trennen Sie sie.Jede Variable, die Sie auf diese Weise exportieren, wird in von Ihnen ausgeführten Skripten angezeigt, zum Beispiel:
Asche:
b.sh:
Dann:
Die Tatsache, dass dies beide Shell-Skripte sind, ist ebenfalls nur ein Zufall. Umgebungsvariablen können an jeden von Ihnen ausgeführten Prozess übergeben werden. Wenn wir stattdessen Python verwenden, sieht dies möglicherweise folgendermaßen aus:
Asche:
b.py:
Beschaffung:
Stattdessen könnten wir so beschaffen:
Asche:
b.sh:
Dann:
Dies "importiert" mehr oder weniger den Inhalt von
b.sh
direkt und führt ihn in derselben Shell aus . Beachten Sie, dass wir die Variable nicht exportieren mussten, um darauf zuzugreifen. Dies teilt implizit alle Variablen, die Sie haben, und ermöglicht es dem anderen Skript, Variablen in der Shell hinzuzufügen / zu löschen / zu ändern. Natürlich sollten in diesem Modell beide Skripte dieselbe Sprache (sh
oderbash
) haben. Um ein Beispiel zu geben, wie wir Nachrichten hin und her weitergeben können:Asche:
b.sh:
Dann:
Dies funktioniert genauso gut in
bash
. Es macht es auch einfach, komplexere Daten wie Arrays oder assoziative Arrays zu teilen, die Sie nicht als Umgebungsvariable ausdrücken können (zumindest ohne Ihr schweres Heben).quelle
Fatal Error gab eine einfache Möglichkeit: Quelle dein zweites Skript! Wenn Sie befürchten, dass dieses zweite Skript einige Ihrer wertvollen Variablen verändert, können Sie es jederzeit in einer Unterschale abrufen:
Durch die Klammern wird die Quelle in einer Subshell ausgeführt, sodass die übergeordnete Shell die Änderungen nicht sehen kann
test2.sh
.Es gibt noch eine andere Möglichkeit, auf die hier unbedingt Bezug genommen werden sollte: Verwenden
set -a
.Aus der POSIX-
set
Referenz :Aus dem Bash-Handbuch :
Also in deinem Fall:
Beachten Sie, dass in den Spezifikationen nur angegeben ist, dass
set -a
die Variable für den Export markiert ist . Das ist:wird wiedergegeben
c
und weder eine leere Zeile nochb
(das heißt,set +a
die Markierung für den Export wird nicht aufgehoben, noch wird der Wert der Zuweisung nur für die exportierte Umgebung "gespeichert"). Dies ist natürlich das natürlichste Verhalten.Fazit: Die Verwendung von
set -a
/set +a
kann weniger mühsam sein als das manuelle Exportieren aller Variablen. Es ist der Beschaffung des zweiten Skripts überlegen, da es für jeden Befehl funktioniert, nicht nur für diejenigen, die in derselben Shell-Sprache geschrieben sind.quelle
Es gibt tatsächlich einen einfacheren Weg als das Exportieren und Deaktivieren oder erneutes Sourcing (zumindest in Bash, solange Sie die Umgebungsvariablen manuell übergeben können):
lass a.sh sein
und b.sh sein
Beobachtete Ausgabe ist
Die Magie liegt in der letzten Zeile von
a.sh
, woMessage
nur für die Dauer des Aufrufs von./b.sh
auf den Wert vonsecret
von gesetzt wirda.sh
. Im Grunde ist es ein bisschen wie benannte Parameter / Argumente. Darüber hinaus funktioniert es sogar für Variablen wie$DISPLAY
, die steuern, auf welchem X Server eine Anwendung gestartet wird.Denken Sie daran, dass die Liste der Umgebungsvariablen nicht unendlich lang ist. Auf meinem System mit einem relativ Vanille-Kernel
xargs --show-limits
wird mir mitgeteilt , dass die maximale Größe des Argumentpuffers 2094486 Byte beträgt. Theoretisch verwenden Sie Shell-Skripte falsch, wenn Ihre Daten größer sind (Pipes, irgendjemand?)quelle
Neben der Antwort auf Fatal Error gibt es noch eine Möglichkeit, die Variablen an ein anderes Shell-Skript zu übergeben.
Die oben vorgeschlagene Lösung weist einige Nachteile auf:
using Export
: Dadurch wird die Variable außerhalb ihres Gültigkeitsbereichs angezeigt, was keine gute Entwurfspraxis ist.using Source
: Es kann zu Namenskollisionen oder versehentlichem Überschreiben einer vordefinierten Variablen in einer anderen Shell-Skriptdatei kommen, die eine andere Datei bezogen hat.Es gibt eine andere einfache Lösung, die wir verwenden können. In Anbetracht des von Ihnen veröffentlichten Beispiels
test.sh
test2.sh
Ausgabe
Es ist auch wichtig zu beachten, dass dies
""
notwendig ist, wenn wir Mehrwortzeichenfolgen übergeben. Nehmen wir noch ein Beispielmaster.sh
Slave1.sh
Slave2.sh
Ausgabe
Dies geschieht aus den in diesem Link treffend beschriebenen Gründen
quelle
source
ist eigentlich eine gute Sache. In Bezug auf Ihre Sorge: Versehentliches Überschreiben einer vordefinierten Variablen können Sie immer in einer Subshell eingeben. Damit ist das Problem vollständig gelöst.( . ./test2.sh )
. Durch die Klammern wird Bash seinen Inhalt in einer Unterschale ausführen.Wenn Sie in Bash die Variable innerhalb einer Unterschale in Klammern wie gezeigt exportieren, vermeiden Sie, dass die exportierten Variablen verloren gehen:
Der Vorteil hierbei ist, dass nach dem Ausführen des Skripts über die Befehlszeile kein $ TESTVARIABLE in Ihre Umgebung gelangt:
quelle
$
Eingabeaufforderung) die exportierte Datei nie angezeigt wird$TESTVARIABLE
. Beim Exportieren wird lediglich eine Kopie einer Variablen an alle nachfolgenden untergeordneten Prozesse übergeben. Es ist nicht möglich, Variablen in der Kette an übergeordnete Prozesse zu übergeben, es sei denn, Sie speichern den Wert im Speicher und lesen diesen Speicher später im übergeordneten Prozessskript. Das Weiterleiten an eine zweite Kopie des übergeordneten Skripts ist möglich, dies wäre jedoch nicht der gleiche Vorgang . Eine ausgezeichnete Erklärung finden Sie hier .Eine andere Option ist die Verwendung
eval
. Dies ist nur geeignet, wenn die Zeichenfolgen vertrauenswürdig sind. Das erste Skript kann die Variablenzuweisungen wiedergeben:echo "VAR=myvalue"
Dann:
eval $(./first.sh) ./second.sh
Dieser Ansatz ist von besonderem Interesse, wenn sich das zweite Skript, für das Sie Umgebungsvariablen festlegen möchten, nicht in Bash befindet und Sie
export
die Variablen auch nicht verwenden möchten , möglicherweise weil sie vertraulich sind und Sie nicht möchten, dass sie bestehen bleiben.quelle
Eine andere Möglichkeit, die für mich etwas einfacher ist, ist die Verwendung von Named Pipes. Named Pipes boten die Möglichkeit, Nachrichten zwischen verschiedenen Prozessen zu synchronisieren und zu senden.
Beschämen:
B.bash:
Verwendung:
B.bash wartet auf eine Nachricht und sobald A.bash die Nachricht sendet, setzt B.bash seine Arbeit fort.
quelle