
Ich habe ein Korn-Shell-Skript
#!/bin/ksh
# set the right ENV
case $INPUT in
abc)
export BIN=${ABC_BIN}
;;
def)
export BIN=${DEF_BIN}
;;
*)
export BIN=${BASE_BIN}
;;
esac
# exit 0 <- bad idea for sourcing the file
jetzt werden diese VARs nur in eine Untershell exportiert, ich möchte aber, dass sie auch in meiner übergeordneten Shell festgelegt werden, sodass diese Variablen immer noch korrekt festgelegt sind, wenn ich mich an der Eingabeaufforderung befinde.
ich weiss Bescheid
. .myscript.sh
aber gibt es eine Möglichkeit, dies ohne „Quellenangabe“ zu tun? da meine Benutzer die „Quellenangabe“ oft vergessen.
EDIT1: Entfernen des Teils „exit 0“ – das habe ich einfach getippt, ohne vorher nachzudenken
EDIT2: Um genauer zu beschreiben, warum ich dies benötige: Meine Entwickler schreiben Code für (der Einfachheit halber) 2 Apps: ABC & DEF. Jede App wird in der Produktion von den separaten Benutzern usrabc und usrdef ausgeführt, die daher ihr eigenes $BIN, $CFG, $ORA_HOME usw. eingerichtet haben – spezifisch für ihre Apps.
Also
- ABCs $BIN = /opt/abc/bin # $ABC_BIN im obigen Skript
- DEFs $BIN = /opt/def/bin # $DEF_BIN
usw.
Jetzt können Entwickler auf der Dev-Box sowohl ABC als auch DEF gleichzeitig unter ihrem eigenen Benutzerkonto „justin_case“ entwickeln, und ich lasse sie die Datei (oben) als Quelle angeben, damit sie ihre ENV-Variableneinstellungen hin- und herschalten können. ($BIN sollte einmal auf $ABC_BIN verweisen und dann muss ich zu $BIN=$DEF_BIN wechseln.)
jetzt sollte das Skript auch neue Sandboxen für die parallele Entwicklung derselben App usw. erstellen. Dadurch muss ich dies interaktiv tun und nach dem Namen der Sandbox usw. fragen.
- /home/justin_case/sandbox_abc_beta2
- /home/justin_case/sandbox_abc_r1
- /home/justin_case/sandbox_def_r1
Die andere Möglichkeit, die ich in Betracht gezogen habe, ist das Schreiben von Aliasnamen und das Hinzufügen dieser zu den Profilen aller Benutzer.
- Alias „setup_env=. .myscript.sh“
und führen Sie es mit
- setup_env Parameter1 ... ParameterX
das macht für mich jetzt mehr Sinn
Antwort1
Ich glaube, das ist ein Problem der Art „das geht nicht“ …
Erstens: Sie würden dieses Skript nicht als Quelle verwenden wollen, da am Ende Exit 0 erscheint.
Zweitens kann kein Unix-Kindprozess die Umgebung des übergeordneten Prozesses direkt ändern. Sonst wären alle möglichen verrückten Dinge möglich.
Könnten Sie mit dem Standardprofil oder den Bashrc-Dateien etwas zu ihrer Umgebung hinzufügen oder könnten Sie einen Wrapper für das Programm schreiben, das sie ausführen möchten?
Lassen Sie mich näher auf das „Wrapper“-Konzept eingehen.
Angenommen, Sie möchten das Programm snoopy entweder mit PROD oder DEV in der Umgebungsvariable „OPTIONS“ ausführen, je nachdem, ob Sie Produktion oder Entwicklung möchten. Wenn es nicht festgelegt ist, macht snoopy beispielsweise etwas Verrücktes, wie die Datenbank für Produktion und Entwicklung zu löschen ...
„snoopy“ in snoopy.bin (oder .snoopy.bin) umbenennen
Fügen Sie dann am selben Speicherort ein Skript mit dem Namen „snoopy“ ein, das Folgendes enthält:
#!/bin/sh
export OPTIONS
case "$OPTIONS"
in
PROD) ;;
DEV) ;;
*) OPTIONS=DEV ;;
esac
#the binary is actually named snoopy.bin
exec "$0.bin" "$@"
Wenn Sie die eigentliche Datei nicht verändern möchten, platzieren Sie dieses Skript irgendwo im Dateisystem, wo es im Pfad des Benutzers vor dem eigentlichen Schnüffelprogramm steht, und geben Sie in der Exec-Anweisung des Skripts einen vollständigen Pfad zur Binärdatei an …
Antwort2
Die Antwort ist Sourcing. Sourcing ermöglicht es Ihnen, Variablen in ein Skript einzubinden,aktuellShell, aber niemals ein übergeordnetes Element davon. Es stimmt, Sie müssen darauf achten, keinen Exit-Befehl oder ähnliches zu verwenden, da dies Ihre aktuelle Shell schließen würde.
Sie können ein Skript mit dem "." als Quelle angeben, d. h.
. ./meinscript.ksh
Antwort3
Vielleicht, wenn Sie es versuchen ...
#!/bin/bash
mknod fifo p
(
echo 'value' > fifo &
)
VARIABLE=`cat fifo`
rm fifo
Es handelt sich dabei nicht direkt um den Export von Variablen, aber es kann eine grundlegende Kommunikation mit dem übergeordneten Prozess ermöglichen.
Antwort4
OK, jetzt nicht lachen. Eine sehr schnelle und sehr schmutzige Lösung ist, hinzuzufügen
echo "Please copy and paste this command:"
echo ""
echo "export BIN=\"$BIN\""
zu Ihrem Skript.
Ein anderer Ansatz. Nur exec
ein untergeordnetes $SHELL in Ihrem Skript, möglicherweise mit einer anderen Eingabeaufforderung (ändern Sie $PS1, um Benutzer darüber zu informieren, in welcher Umgebung sie arbeiten, um Verwirrung zu vermeiden).
Ein anderer Ansatz(mein Favorit). Benutzer vergessen, Ihr Skript als Quelle anzugeben. Warum ist das so? Die Angabe der Quelle ist genau die Standardmethode. Vielleicht ist eine gute Möglichkeit, sie daran zu erinnern, die erste Zeile ( #!/bin/sh
) und dann chmod a-x
it zu entfernen. Es kann danach immer noch als Quelle angegeben werden, aber es kann offensichtlich nicht versehentlich ausgeführt werden.
Schimpfen: Alles in allem finde ich, dass Sie von Anfang an eine seltsame Idee hatten. Vielleicht nicht seltsam ... ich würde sagen, im Stil eher nicht Unix-mäßig. Ich musste in meinem Leben noch nie eine Umgebung in ein übergeordnetes Element exportieren. Ich habe einmal eine ähnliche Situation erlebt – login .profile fragte, welche von drei verschiedenen Umgebungen für ein einzelnes Oracle-Konto festgelegt werden sollte. Schlechte Idee, am Ende stellte sich heraus, dass die Benutzer lieber zu sudo migrierten (sie führten sudo zu drei verschiedenen Oraxxx-Konten aus). Was versuchen Sie damit zu erreichen, wenn ich fragen darf?