Kann ein shell-Skript, das setzen von Umgebungsvariablen der aufrufenden shell?
Ich bin versucht zu schreiben Sie ein shell-Skript, dass, wenn Sie ausgeführt wird, werden einige Umgebungsvariablen setzen, die bleiben werden, legen Sie in die aufrufende shell.
setenv FOO foo
in csh/tcsh, oder
export FOO=foo
in sh/bash nur setzen Sie es während der Skript - Ausführung.
Weiß ich schon, dass
source myscript
wird, führen Sie die Befehle aus der Skript eher als den Start einer neuen shell, und können dazu führen, dass die Einstellung des "Anrufers" - Umgebung.
Aber hier ist der Haken:
Möchte ich dieses script aufrufbar sein, entweder bash oder csh. In anderen Worten, ich möchte die Benutzer entweder die shell ausführen zu können, mein Skript und shell haben, der die Umgebung verändert. So 'Quelle' nicht für mich arbeiten, da ein Benutzer, der csh nicht Quelle ein bash-Skript, und ein Benutzer, der bash kann nicht Quelle ein csh-Skript.
Gibt es irgendeine vernünftige Lösung, die nicht beinhalten, die zum schreiben und pflegen von ZWEI Versionen auf dem Skript?
InformationsquelleAutor der Frage Larry Gritz | 2009-01-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre shell-Prozess hat eine Kopie der Eltern-Umgebung und kein Zugriff auf den parent-Prozess, der die Umgebung zu löschen. Wenn Sie Ihre shell-Prozess beendet ist, werden änderungen, die Sie vorgenommen haben, zu seiner Umwelt verloren. Die Beschaffung eines Skript-Datei ist die am häufigsten verwendete Methode für die Konfiguration einer shell-Umgebung, können Sie wollen einfach nur beißen die Kugel und halten einen für jede der zwei Arten von shell.
InformationsquelleAutor der Antwort converter42
Verwenden Sie die "Punkt-Leerzeichen-script" aufrufen syntax. Zum Beispiel, hier ist, wie es mit dem vollständigen Pfad zu einem Skript:
Und hier ist, wie es zu tun ist, wenn Sie im gleichen Verzeichnis wie das Skript:
Diese führen Sie das Skript in der aktuellen shell anstelle des Ladens ein weiteres (das ist, was passieren würde, wenn Sie nicht
./set_env_vars.sh
). Läuft es denn in der gleichen shell, die Umwelt-Variablen, die Sie festlegen, wird verfügbar sein, wenn er sich beendet.Dies ist das gleiche wie der Aufruf
source set_env_vars.sh
aber es ist kürzer zu geben und möglicherweise in einigen Orten, wosource
nicht.InformationsquelleAutor der Antwort Humberto Romero
Du wirst es nicht ändern, können die Anrufer-shell, weil es in einem anderen Prozesskontext. Wenn untergeordnete Prozesse Erben Ihre shell-Variablen, Sie sind
Erben kopiert sich selbst.
Eine Sache, die Sie tun können, ist, um ein Skript schreiben, das gibt die richtigen Befehle für tcsh
oder der sh basiert, wie es aufgerufen wird. Wenn Sie Skript "setit" dann tun:
und
Nun entweder direkt oder in einem alias, tun Sie dies aus sh
oder das von csh
setit verwendet $0 zu bestimmen, deren Ausgabe Stil.
Diese istwohlfühlend, wie Menschen verwendet, um die Umgebungsvariable TERM setzen.
Der Vorteil hier ist, dass der setit ist einfach geschrieben, in welcher Schale Sie wie in:
mit den symbolischen links, die oben gegeben werden, und das eval der backquoted Ausdruck, das hat das gewünschte Ergebnis.
Zur Vereinfachung der Aufruf für csh, tcsh, oder ähnliche Schalen:
oder für sh, bash, und das wie:
Eine nette Sache über dieses ist, dass Sie nur pflegen Sie die Liste an einem Ort.
In der Theorie könnte man sogar kleben Sie die Liste in eine Datei und setzen
cat nvpairfilename
zwischen "in" und "tun".Dies ist ziemlich viel, wie die login-shell terminal-Einstellungen verwendet, um zu tun: eine script-Ausgabe-Statements ausgeführt werden, in der die login-shell. Ein alias würde in der Regel verwendet werden, um Aufruf-einfach, wie im "tset vt100". Wie bereits in einer anderen Antwort, es gibt auch eine ähnliche Funktionalität in den INN UseNet-news-server.
InformationsquelleAutor der Antwort Thomas Kammeyer
In meine .bash_profile habe ich :
Also, wenn ich wollen, deaktivieren Sie den proxy,
die Funktion(en) ausführen der login-shell und setzt die Variablen
wie erwartet und gewünscht.
InformationsquelleAutor der Antwort chris
Ist es "irgendwie" möglich durch Verwendung von gdb und setenv(3)obwohl ich eine harte Zeit haben, empfehle tatsächlich, dies zu tun. (Zusätzlich, d.h. das aktuellste ubuntu nicht lassen Sie dies tun, ohne dass der kernel mehr Freizügig über ptrace und der gleichen gehen können, für andere Distributionen als auch).
InformationsquelleAutor der Antwort Kjetil Joergensen
Das funktioniert — es ist nicht das, was ich benutzen würde, aber es "funktioniert". Lassen Sie ein Skript erstellen
teredo
die UmgebungsvariableTEREDO_WORMS
:Wird es interpretiert von der Korn-shell exportiert die Umgebungsvariable, und dann ersetzt sich selbst mit einem neuen interaktiven shell.
Bevor dieses Skript ausgeführt wird, haben wir
SHELL
Satz in die Umgebung, um die C-shell und die UmgebungsvariableTEREDO_WORMS
ist nicht gesetzt:Wenn das Skript ausgeführt wird, werden Sie in eine neue shell, anderen interaktiven C-shell, aber die Umgebungsvariable gesetzt:
Beim verlassen dieser shell, die original-shell übernimmt:
Die Umgebungsvariable nicht gesetzt in der original-shell-Umgebung. Wenn Sie
exec teredo
den Befehl ausführen, dann den ursprünglichen interaktiven shell wird ersetzt durch die Korn-shell setzt, die die Umwelt, und dann wiederum wird ersetzt durch einen neuen, interaktiven C-shell:Wenn Sie
exit
(oder Ctrl-D), wird die shell beendet, wahrscheinlich die Protokollierung, die Sie aus diesem Fenster, oder nehmen Sie zurück zur vorherigen Ebene der shell, von wo aus die Experimente gestartet.Den gleichen Mechanismus arbeitet für die Bash oder die Korn shell. Sie können feststellen, dass die Eingabeaufforderung nach der Ausfahrt Befehle erscheint in lustigen stellen.
Hinweis: die Diskussion in den Kommentaren. Dies ist nicht eine Lösung, die ich empfehlen würde, aber es tut Erreichung der genannten Zwecke von einem Skript zum setzen der Umgebung, die mit allen shells funktioniert (das akzeptieren die
-i
option, um eine interaktive shell). Sie könnten auch"$@"
nach der option relais werden alle anderen Argumente, die könnte dann die Schale verwendbar als einen Allgemeinen "set environment und Befehl ausführen" - tool. Möchten Sie vielleicht weglassen-i
wenn es andere Argumente, was zu:Den
"${@-'-i'}"
etwas bedeutet", wenn das argument Liste enthält mindestens ein argument, verwenden Sie das ursprüngliche argument-Liste; andernfalls ersetzen-i
für die nicht-existenten Argumente'.InformationsquelleAutor der Antwort Jonathan Leffler
Sollten Sie Module verwenden, finden Sie unter http://modules.sourceforge.net/
EDIT: Das Modul-Paket wurde nicht aktualisiert, seit 2012 aber funktioniert immer noch ok für die Grundlagen. Alle die neuen features, Glocken und pfeift geschehen in lmod an diesem Tag (welche ich mag es mehr): https://www.tacc.utexas.edu/research-development/tacc-projects/lmod
InformationsquelleAutor der Antwort Davide
Eine andere Möglichkeit, die ich sehe nicht genannt wird, schreiben Sie den Wert der Variablen in eine Datei.
Lief ich in einer sehr ähnlichen Problem, wo ich sein wollte in der Lage zu laufen die letzten test (anstatt alle meine tests). Mein Erster plan war, zu schreiben, einen Befehl zum setzen der env-variable TESTCASE, und haben dann einen anderen Befehl, verwenden Sie diese, um den test auszuführen. Unnötig zu sagen, ich hatte exakt das gleiche Problem wie du.
Aber dann kam ich mit diesem einfachen hack:
Ersten Befehl (
testset
):Zweiten Befehl (
testrun
):InformationsquelleAutor der Antwort dkinzer
Fügen Sie dem-l-flag in der oben in deinem bash-Skript, d.h.
Die Werte mit
NAME1
undNAME2
wird jetzt exportiert wurden, um Ihre aktuelle Umgebung, aber diese änderungen sind nicht permanent. Wenn Sie wollen, dass Sie dauerhaft sein, müssen Sie fügen Sie Sie zu Ihrem.bashrc
- Datei oder einer anderen init-Datei.Aus der man-pages:
InformationsquelleAutor der Antwort cristobal
Können Sie anweisen, den Kind-Prozess zum ausgeben der Umgebungsvariablen (durch Aufruf von "env"), dann die Schleife über den Ausdruck der environment-Variablen im parent-Prozess und rufen Sie "export" auf die Variablen.
Der folgende code basiert auf Aufnahme-Ausgang zu finden . -print0 in einem bash-array
Wenn der parent-shell ist die bash, die Sie verwenden können,
Wenn der parent-shell ist die dash, dann
read
nicht die d-fahne und der code wird komplizierter,InformationsquelleAutor der Antwort klaus se
Können Sie ein anderes aufrufen kann, eine Bash mit den verschiedenen bash_profile.
Auch, Sie können spezielle bash_profile für den Einsatz in multi-bashprofile Umgebung.
Denken Sie daran, dass Sie verwenden können Funktionen innerhalb von bashprofile, und dass Funktionen werden verfügbar weltweit.
zum Beispiel, "Funktion user { USER_NAME export $1 }" kann, setzen Sie die variable in runtime z.B.: Benutzer olegchir && env | grep olegchir
InformationsquelleAutor der Antwort Oleg Chirukhin
Technisch gesehen, die richtige ist -- nur, 'eval' keine Gabel eine andere shell. Jedoch, aus der Sicht der Anwendung, die Sie versuchen zu laufen, in die veränderte Umwelt, die Differenz ist null: das Kind erbt die Umgebung des übergeordneten Objekts, so dass die (modifizierte) Umwelt vermittelt wird, alle absteigende Prozesse.
Ipso facto, die geänderte Umgebungsvariable 'sticks' - solange Sie unter dem übergeordneten Programm/shell.
Wenn es absolut notwendig ist, um die Umgebungsvariable zu bleiben, nachdem die Eltern (Perl oder shell) beendet wurde, ist es notwendig, für die Eltern-shell zu tun, die schweres heben. Eine Methode, die ich gesehen habe in der Dokumentation für das aktuelle Skript, um zu laichen eine ausführbare Datei mit den notwendigen 'export' - Sprache, und dann trick der übergeordneten shell in der Ausführung es-immer in Kenntnis der Tatsache, dass Sie brauchen, um Vorwort den Befehl mit "source", wenn Sie versuchen, zu verlassen, eine nicht-flüchtige version der modifizierten Umgebung hinter sich. Eine Kluge, im besten Fall.
Die zweite Methode ist, ändern Sie das Skript, leitet die shell-Umgebung (.bashrc oder was auch immer) enthalten die geänderten parameter. Das kann gefährlich werden-wenn Sie Schlauch bis die Initialisierung Skript kann es machen Sie Ihre shell nicht verfügbar das nächste mal, wenn es versucht, zu starten. Es gibt viele tools zum ändern der aktuellen shell; durch die Anbringung der notwendigen Optimierungen, um den 'launcher', die Sie effektiv schieben diese änderungen freuen, wie gut.
In der Regel nicht eine gute Idee sein, wenn Sie nur die Umgebung ändert sich für eine bestimmte Anwendung suite, müssen Sie gehen zurück und die Rückkehr der shell starten Skript zu seinem ursprünglichen Zustand (mit vi oder was auch immer) hinterher.
Kurz gesagt, es gibt keine gute (und einfache) Methoden. Vermutlich war dies nur sehr schwierig zu gewährleisten, die Sicherheit des Systems wurde nicht unwiderruflich kompromittiert.
InformationsquelleAutor der Antwort David Lovering
Die kurze Antwort ist Nein, Sie können nicht ändern, die Umgebung des übergeordneten Prozesses, aber es scheint, wie das, was Sie wollen, ist ein Umfeld mit custom environment-Variablen und die shell, die der Benutzer gewählt hat.
Also warum nicht einfach etwas wie
Dann, wenn Sie fertig sind mit der Umwelt, nur
exit
.InformationsquelleAutor der Antwort Andrew
Können Sie immer verwenden Sie Aliase
InformationsquelleAutor der Antwort user1667208
Weitere option ist die Verwendung von "Environment Modules" (http://modules.sourceforge.net/). Leider führt eine Dritte Sprache in den mix. Definieren Sie die Umgebung mit der Sprache Tcl, aber es gibt ein paar praktische Befehle für typische änderungen (anfügen vs. append vs-set). Sie müssen auch Umwelt-Module installiert. Sie können dann mit
module load *XXX*
Namen der Umgebung, die Sie wollen. Der module-Befehl ist im Grunde ein fancy alias für dieeval
Mechanismus oben beschrieben von Thomas Kammeyer. Der wesentliche Vorteil hier ist, dass man um die Umwelt in einer Sprache und setzen auf "Environment Modules", um es zu übersetzen, sh, ksh, bash, csh, tcsh, zsh, python (?!?!!), etc.InformationsquelleAutor der Antwort Howard Hobbes
Habe ich diese vor vielen Jahren. Wenn ich erinnern, richtig, habe ich ein alias in jedem der .bashrc und .cshrc, mit den Parametern, aliasing die jeweiligen Formen der Einstellung der Umwelt zu einer gemeinsamen form.
Dann die Skript-Quelle in jede der beiden Schalen ein Befehl mit, dass die Letzte form, die geeignet ist alias in jeder Schale.
Wenn ich den konkreten Aliase, werde ich Sie posten.
InformationsquelleAutor der Antwort sancho.s
Erstellte ich eine Lösung mit Rohren, eval und signal.
Es funktioniert mit jedem Befehl.
InformationsquelleAutor der Antwort Luiz Angelo Daros de Luca
Unter OS X bash können Sie Folgendes tun:
Erstellen Sie das bash-Skript-Datei zu unset variable
Machen Sie die Datei ausführbar
Alias
Sollte es bereit sein, zu verwenden, so lange Sie den Ordner mit dem Skript-Datei an den Pfad angehängt.
InformationsquelleAutor der Antwort Marton Tatai
Ich nicht sehen, jede Antwort, die dokumentieren, wie Sie arbeiten, um dieses problem mit kooperierenden Prozessen. Ein gemeinsames Muster mit Dingen wie
ssh-agent
ist der Kind-Prozess drucken, ein Ausdruck, der Elternteil kanneval
.Beispielsweise
ssh-agent
hat Optionen, um wählen Sie Csh oder Bourne-kompatible Ausgabe-syntax.(Dies bewirkt, dass der agent zu laufen beginnen, sondern ermöglicht es Ihnen nicht, um es tatsächlich zu verwenden, es sei denn, Sie jetzt kopieren und fügen Sie diese Ausgabe in Ihren shell-prompt.) Vergleichen:
(Wie Sie sehen können,
csh
undtcsh
verwendetsetenv
zu setzen Variablen.)Ihrem eigenen Programm können tun dies auch.
Ihre
makefoo
Skript würde einfach kalkulieren und drucken Sie den Wert und lassen den Anrufer tun, was Sie wollen -- Zuweisung an eine variable ist ein üblicher Fall, aber wahrscheinlich nicht etwas, was Sie wollen, hart-code in das tool, das erzeugt den Wert.InformationsquelleAutor der Antwort tripleee
Es ist nicht das, was ich nennen würde hervorragend, aber dies funktioniert auch, wenn Sie benötigen, rufen Sie das script aus der shell sowieso. Es ist keine gute Lösung, aber für eine einzelne statische variable, es funktioniert gut genug.
1.) Erstellen Sie ein Skript mit einer Bedingung, dass die Ausgänge entweder 0 (Erfolgreich) oder 1 (Nicht erfolgreich)
2.) Erstellen Sie ein alias, das ist abhängig von der exit-code.
Rufen Sie den alias, der das script aufruft, das wertet die Bedingung, die erforderlich ist, um exit zero über das '&& " um, um die Umgebungsvariable in der parent-shell.
Dies ist Treibgut, aber es kann nützlich sein, in eine Prise.
InformationsquelleAutor der Antwort user1802263
Andere als Schriften-Bedingungen je nach dem was $SHELL/$TERM gesetzt ist, Nein. Was ist falsch mit der Verwendung von Perl? Es ist ziemlich allgegenwärtig (ich kann nicht denken, der eine einzelne UNIX-Variante, die hat es nicht), und erspare dir die Mühe.
InformationsquelleAutor der Antwort phresus