Partager les variables d'environnement entre bash et fish

13

les scripts bash et fish ne sont pas compatibles, mais j'aimerais avoir un fichier qui définit certaines variables d'environnement à initialiser à la fois par bash et fish.

Ma solution proposée consiste à définir un ~/.envfichier qui contiendrait la liste des variables d'environnement comme ceci:

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

Je pourrais alors simplement le source en bash et faire un script qui le convertit au format poisson et les sources que dans poisson.

Je pensais qu'il pourrait y avoir une meilleure solution que cela, alors je demande une meilleure façon de partager les variables d'environnement entre les poissons bash.

Remarque: j'utilise OS X.


Voici un exemple de .envfichier que je voudrais que fish et bash manipulent en utilisant la syntaxe de ridiculous-fish (supposons que ~ / bin et ~ / bin2 sont des répertoires vides):

setenv _PATH "$PATH"
setenv PATH "$HOME/bin"
setenv PATH "$PATH:$HOME/bin2"
setenv PATH "$PATH:$_PATH"
Tyilo
la source

Réponses:

17

bash a une syntaxe spéciale pour définir les variables d'environnement, tandis que fish utilise une fonction intégrée. Je suggère d'écrire votre fichier .env comme ceci:

setenv VAR1 val1
setenv VAR2 val2

puis définir de setenvmanière appropriée dans les coques respectives. En bash (par exemple .bashrc):

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

Dans le poisson (par exemple, poisson config.):

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

Notez que PATH nécessitera une manipulation spéciale, car il s'agit d'un tableau dans fish mais d'une chaîne délimitée par deux points dans bash. Si vous préférez écrire setenv PATH "$HOME/bin:$PATH"en .env, vous pouvez écrire le setenv de fish comme ceci:

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

Cela entraînera une mauvaise gestion des éléments dans PATH qui contiennent des espaces, des deux-points ou des retours à la ligne.

La maladresse dans PATH est due au mélange de chaînes délimitées par deux points avec de vrais tableaux. La façon préférée d'ajouter à PATH dans les poissons est tout simplement set PATH $PATH ~/bin.

ridicule_fish
la source
1
La PATHsolution pour les poissons fonctionnera-t-elle avec des chemins avec: des espaces? nouvelles lignes? d'autres choses à surveiller?
Tyilo
[est intégré à la fois à bash et à fish, donc PATH ne devrait pas avoir besoin d'être configuré correctement pour être utilisé [. L'exemple setenv doit fonctionner avec tous les caractères dans PATH à l'exception des deux-points et des retours à la ligne.
ridiculous_fish
Remplacer trpar /usr/bin/trI et utiliser le .envfichier fourni dans ma question, je reçois beaucoup d'erreurs lors du démarrage du poisson. Je ne pense pas que la gestion de PATH soit correcte.
Tyilo
Oh, c'est vrai, le poisson le séparera dans des guillemets. Je mettrai à jour le commentaire.
ridiculous_fish
Ouais ça marche maintenant. Je ne pense pas qu'un autre shell (à l'exception du poisson?) Autorise les chemins avec deux points dans PATH de toute façon.
Tyilo
6

Il y a (maintenant?) Un moyen plus simple, selon la réponse de @ Zanchey ici

Fish Shell: comment définir plusieurs variables d'environnement à partir d'un fichier à l'aide de l'exportation

Le résumé est cependant:

Poisson:

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

Frapper:

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

avec la différence étant $et l'utilisation dexargs

Chris Conover
la source
Beaucoup plus pratique et sans syntaxe particulière. Merci
Panayotis
Ne fonctionne pas pour les tableaux tels que $ PATH
JanKanis
5

La plupart des systèmes Unix utilisent PAM . Le pam_envmodule lit un fichier très semblable au vôtre .env.

Sous Linux , pam_envlit un fichier système /etc/environmentet un fichier utilisateur ~/.pam_environment. Sur OS X (et autres * BSD, qui utilisent également OpenPAM), il semble que pam_envseul le fichier système soit lu, vous ne pouvez donc pas définir des variables par utilisateur de cette façon, uniquement pour tous les utilisateurs.

Gilles 'SO- arrête d'être méchant'
la source
1

En développant la réponse de @ ridiculous_fish, avec la fonction suivante pour bash, cela fonctionne également pour les tableaux qui contiennent des espaces, comme $PATHsi vous avez des espaces dans vos chemins. Cependant, setenvest déjà défini comme une fonction dans la bibliothèque standard de poissons de nos jours, j'ai donc changé le nom ici enshenv

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

Maintenant, dans votre .envfichier, vous pouvez spécifier les composants du tableau en tant qu'arguments séparés de la setenvcommande:

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

Pour la mise en œuvre simple de fish @ ridiculous_fish:

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

Créez simplement une fonction dans $ HOME / .config / fish / functions / env.fish avec le contenu:

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

partagé tous les vars créés dans bash dans le dossier /etc/profile.d

par exemple: /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

connectez-vous simplement sur fish ou bash, faites echo $GOPATH $GOROOT $GOBIN $PATHet voyez la magie :)

Iury Fukuda
la source