Wie exportiere ich VARs von einer Subshell in eine übergeordnete Shell?


10

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 Subshell exportiert, aber ich möchte, dass sie auch in meiner übergeordneten Shell festgelegt werden. Wenn ich also an der Eingabeaufforderung bin, sind diese Variablen immer noch korrekt festgelegt.

ich weiss Bescheid

. .myscript.sh

Aber gibt es eine Möglichkeit, dies ohne "Sourcing" zu tun? da meine Benutzer oft vergessen, "Quelle".


EDIT1: Entfernen des Teils "exit 0" - ich habe nur getippt, ohne vorher darüber nachzudenken

EDIT2: Um mehr Details darüber hinzuzufügen, warum ich das brauche: 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. Daher haben sie ihre $ BIN, $ CFG, $ ORA_HOME eingerichtet, was auch immer - spezifisch für ihre Apps.

damit

  • $ BIN = / opt / abc / bin # $ ABC_BIN von ABC 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 verwenden, damit sie ihre ENV-Var-Einstellungen hin und her ändern können. ($ BIN sollte gleichzeitig auf $ ABC_BIN zeigen 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 kann 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 Option, die ich in Betracht gezogen habe, besteht darin, Aliase zu schreiben und sie dem Profil jedes Benutzers hinzuzufügen

  • alias 'setup_env =. .myscript.sh '

und führen Sie es mit

  • setup_env parameter1 ... parameterX

das macht für mich jetzt mehr Sinn


Ja - Sie können dies mit einem Alias ​​oder einer Funktion tun (ich bevorzuge Funktionen selbst), bei der Sie die Funktion prod () {export VAR = snoopy; }; und die Funktion dev () {export VAR = woodstock; };
Chris

Antworten:


11

Ich denke, es ist ein "no can do" -Problem ...

Erstens - Sie möchten dieses Skript wegen des Exits 0 am Ende nicht als Quelle verwenden.

Zweitens kann kein untergeordneter Unix-Prozess die Umgebung des übergeordneten Prozesses direkt ändern. Sonst wären alle möglichen verrückten Dinge möglich.

Könnten Sie ihrer Umgebung mit den Standardprofil- oder Bashrc-Dateien etwas hinzufügen oder einen Wrapper für das Programm schreiben, das sie ausführen möchten?

Gestatten Sie mir, das "Wrapper" -Konzept näher zu erläutern.

Angenommen, Sie möchten das Programm snoopy entweder mit PROD oder DEV in der Umgebungsvariablen "OPTIONS" ausführen, je nachdem, ob Sie Produktion oder Entwicklung wünschen. WENN es nicht festgelegt ist, sagen wir, snoopy macht etwas Verrücktes wie das Löschen der Datenbank für Produktion und Entwicklung ...

benenne "snoopy" in snoopy.bin (oder .snoopy.bin) um

Fügen Sie dann an derselben Stelle 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 nicht mit der eigentlichen Datei herumspielen möchten, platzieren Sie dieses Skript irgendwo im Dateisystem, das vor dem eigentlichen Snoopy-Programm im PATH des Benutzers liegt, und haben Sie einen vollständigen Pfad zur Binärdatei in der exec-Anweisung des Skripts ...


5

Die Antwort lautet Sourcing. Mit Sourcing können Sie Variablen in ein Skript in die aktuelle Shell aufnehmen, jedoch niemals als übergeordnetes Element. Es ist wahr, 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 "."

. ./myscript.ksh



3

Vielleicht, wenn Sie versuchen ...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE=`cat fifo`
rm fifo

Es ist nicht gerade ein variabler Export, aber es kann eine grundlegende Kommunikation mit dem übergeordneten Prozess ermöglichen.


1

OK, lach jetzt nicht. 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 execeine untergeordnete $ SHELL in Ihrem Skript, möglicherweise mit einer anderen Eingabeaufforderung (ändern Sie $ PS1, um Benutzer zu benachrichtigen, in welcher Umgebung sie arbeiten, um Verwirrung zu vermeiden).

Ein anderer Ansatz (mein Favorit). Benutzer vergessen, Ihr Skript zu beziehen. Warum ist das so? Beschaffung ist genau der Standardweg. Vielleicht ist eine gute Möglichkeit, sie daran zu erinnern, die erste Zeile ( #!/bin/sh) und dann chmod a-xdiese zu entfernen . Danach kann es noch bezogen werden, aber es kann offensichtlich nicht fälschlicherweise ausgeführt werden.

Rant : Alles in allem habe ich das Gefühl, dass Sie überhaupt eine seltsame Idee hatten. Vielleicht nicht seltsam ... Ich würde sagen, etwas un-Unix im Stil. Ich musste in meinem Leben noch nie eine Umgebung an Eltern exportieren. Ich habe einmal eine ähnliche Situation gesehen - Login .profile mit der Frage, welche von drei verschiedenen Umgebungen für ein einzelnes Oracle-Konto festgelegt werden soll. Schlechte Idee, am Ende stellte sich heraus, dass Benutzer es vorzogen, auf sudo zu migrieren (sie sudo auf drei verschiedene oraxxx-Konten). Was versuchst du zu erreichen, wenn ich fragen darf?

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.