Teilen Sie Umgebungsvariablen zwischen Bash und Fisch

12

Bash- und Fish-Skripte sind nicht kompatibel, aber ich hätte gerne eine Datei, die einige Umgebungsvariablen definiert, die sowohl von Bash als auch von Fish initialisiert werden sollen.

Meine vorgeschlagene Lösung besteht darin, eine ~/.envDatei zu definieren , die die folgende Liste von Umgebungsvariablen enthält:

PATH="$HOME/bin:$PATH"
FOO="bar"

Ich könnte es dann einfach in bash ausgeben und ein Skript erstellen, das es in das Fischformat konvertiert und das in fish ausgibt.

Ich dachte, dass es eine bessere Lösung geben könnte, und fordere daher eine bessere Möglichkeit, Umgebungsvariablen zwischen Bash-Fischen auszutauschen.

Hinweis: Ich verwende OS X.


Hier ist eine Beispieldatei .env, für die ich möchte, dass sowohl fish als auch bash die lächerliche fish-Syntax verwenden (vorausgesetzt, ~ / bin und ~ / bin2 sind leere Verzeichnisse):

setenv _PATH "$PATH"
setenv PATH "$HOME/bin"
setenv PATH "$PATH:$HOME/bin2"
setenv PATH "$PATH:$_PATH"
Tyilo
quelle

Antworten:

16

bash hat eine spezielle Syntax zum Setzen von Umgebungsvariablen, während fish eine eingebaute verwendet. Ich würde vorschlagen, Ihre .env-Datei so zu schreiben:

setenv VAR1 val1
setenv VAR2 val2

und dann setenventsprechend in den jeweiligen Schalen zu definieren. In der Bash (zB .bashrc):

function setenv() { export "$1=$2"; }
. ~/.env

In Fischen (zB config.fish):

function setenv; set -gx $argv; end
source ~/.env

Beachten Sie, dass PATH eine spezielle Behandlung erfordert, da es sich um ein Array in fish, aber um eine durch Doppelpunkte getrennte Zeichenfolge in bash handelt. Wenn Sie es vorziehen, setenv PATH "$HOME/bin:$PATH"in .env zu schreiben , können Sie fish's setenv folgendermaßen schreiben:

function setenv
    if [ $argv[1] = PATH ]
        # Replace colons and spaces with newlines
        set -gx PATH (echo $argv[2] | tr ': ' \n)
    else
        set -gx $argv
    end
 end

Dadurch werden Elemente in PATH, die Leerzeichen, Doppelpunkte oder Zeilenumbrüche enthalten, falsch behandelt.

Die Ungeschicklichkeit in PATH beruht darauf, dass durch Doppelpunkte getrennte Zeichenfolgen mit echten Arrays verwechselt werden. Die bevorzugte Methode, um bei Fischen an PATH anzuhängen, ist einfach set PATH $PATH ~/bin.

lächerlich_fisch
quelle
1
Funktioniert der PATHFix für Fische mit Pfaden mit: Leerzeichen? Zeilenumbrüche? andere Dinge, auf die Sie achten sollten?
Tyilo
[ist sowohl in Bash als auch in Fish integriert, daher sollte PATH nicht richtig eingestellt sein, um verwendet zu werden [. Das setenv-Beispiel sollte mit allen Zeichen in PATH außer Doppelpunkten und Zeilenumbrüchen funktionieren.
ridiculous_fish
Beim Ersetzen trdurch /usr/bin/trI und Verwenden der .envin meiner Frage angegebenen Datei werden beim Starten des Fisches viele Fehler angezeigt. Ich denke nicht, dass die PATH-Behandlung korrekt ist.
Tyilo
Oh, richtig, Fische trennen es in Anführungszeichen. Ich werde den Kommentar aktualisieren.
ridiculous_fish
Ja, es funktioniert jetzt. Ich glaube nicht, dass eine andere Shell (außer Fisch?) Pfade mit Doppelpunkten in PATH zulässt.
Tyilo
6

Es gibt (jetzt?) Einen einfacheren Weg, wie @ Zanchey hier antwortet

Fish Shell: So legen Sie mithilfe des Exports mehrere Umgebungsvariablen aus einer Datei fest

Die Zusammenfassung ist jedoch:

Fisch:

echo -e "foo=3\nfoobar=4" > .env; export (cat .env); env | grep foo

Bash:

echo -e "foo=3\nfoobar=4" > .env; export $(cat .env | xargs); env | grep foo

mit dem Unterschied, dass $und die Verwendung vonxargs

Chris Conover
quelle
Viel bequemer und ohne spezielle Syntax. Vielen Dank
Panayotis
Funktioniert nicht für Arrays wie $ PATH
JanKanis
5

Die meisten Unix-Systeme verwenden PAM . Das pam_envModul liest eine Datei, die Ihrer sehr ähnlich ist .env.

Unter Linux , pam_envliest eine Systemdatei /etc/environmentund eine Benutzerdatei ~/.pam_environment. Unter OS X (und anderen * BSDs, die ebenfalls OpenPAM verwenden) wird anscheinend pam_envnur die Systemdatei gelesen, sodass Sie auf diese Weise keine Variablen pro Benutzer festlegen können, sondern nur für alle Benutzer.

Gilles 'SO - hör auf böse zu sein'
quelle
1

Wenn Sie die Antwort von @ ridiculous_fish mit der folgenden Funktion für bash erweitern, funktioniert dies auch für Arrays, die Leerzeichen enthalten, z. B. $PATHwenn Sie Leerzeichen in Ihren Pfaden haben. Ist setenvjedoch in der Fischstandardbibliothek heutzutage bereits als Funktion definiert, so habe ich den Namen hier in geändertshenv

function shenv { 
        var="$1"
        shift
        export "$var=$(printf "%s\n" "$@" | paste -s -d: -)"
}
. ~/.env

Jetzt können Sie in Ihrer .envDatei Array-Komponenten als separate Argumente für den setenvBefehl angeben :

shenv PATH /my/path /my/path\ with\ spaces "/my/quoted path" $PATH

Für fish @ ridiculous_fish reicht die einfache Implementierung aus:

function shenv; set -gx $argv; end
source ~/.env
JanKanis
quelle
1

Erstellen Sie einfach eine Funktion in $ HOME / .config / fish / functions / env.fish mit folgendem Inhalt:

for f in /etc/profile.d/*.sh
    sh $f
end

hat alle in bash erstellten Variablen im Ordner /etc/profile.d freigegeben

Zum Beispiel: /etc/profile.d/golang.sh

#!/bin/sh
export GOPATH=$HOME/gopath
export GOROOT=$HOME/go
export GOBIN=$HOME/gobin

export PATH=$PATH:$GOROOT/bin:$GOBIN

logge dich einfach bei fish oder bash ein, mache echo $GOPATH $GOROOT $GOBIN $PATHund sieh dir die Magie an :)

Iury Fukuda
quelle