Compartir variables de entorno entre bash y fish

13

Las secuencias de comandos bash y fish no son compatibles, pero me gustaría tener un archivo que defina algunas variables de entorno que bash y fish inicializarán.

Mi solución propuesta es definir un ~/.envarchivo que contenga la lista de variables de entorno de esta manera:

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

Entonces podría simplemente buscarlo en bash y hacer un script que lo convierta al formato de pescado y lo haga en pescado.

Estaba pensando que puede haber una solución mejor que esta, así que estoy pidiendo una mejor manera de compartir las variables de entorno entre los peces bash.

Nota: estoy usando OS X.


Aquí hay un .envarchivo de ejemplo que me gustaría que fish y bash manejen usando la sintaxis de ridiculous-fish (supongamos que ~ / bin y ~ / bin2 son directorios vacíos):

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

Respuestas:

17

bash tiene una sintaxis especial para establecer variables de entorno, mientras que fish usa una función incorporada. Sugeriría escribir su archivo .env así:

setenv VAR1 val1
setenv VAR2 val2

y luego definiendo setenvapropiadamente en las respectivas conchas. En bash (por ejemplo, .bashrc):

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

En peces (p. Ej., Config.fish):

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

Tenga en cuenta que PATH requerirá un manejo especial, ya que es una matriz en peces pero una cadena delimitada por dos puntos en bash. Si prefiere escribir setenv PATH "$HOME/bin:$PATH"en .env, puede escribir el setenv de pez de la siguiente manera:

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

Esto manejará mal los elementos en PATH que contienen espacios, dos puntos o nuevas líneas.

La incomodidad en PATH se debe a mezclar cadenas delimitadas por dos puntos con matrices verdaderas. La forma preferida de agregar a PATH en peces es simplemente set PATH $PATH ~/bin.

pez ridículo
fuente
1
¿La PATHsolución para peces funcionará con caminos con espacios? nuevas líneas? otras cosas a tener en cuenta?
Tyilo
[es una función incorporada tanto en bash como en peces, por lo que no es necesario que la RUTA esté configurada correctamente para su uso [. La muestra setenv debería funcionar con todos los caracteres en RUTA, excepto los dos puntos y las nuevas líneas.
ridiculous_fish
Reemplazando trcon /usr/bin/trI y usando el .envarchivo provisto en mi pregunta, recibo muchos errores al comenzar a pescar. No creo que el manejo de la RUTA sea correcto.
Tyilo
Ah, claro, el pez lo separará entre comillas. Actualizaré el comentario.
ridiculous_fish
Yay funciona ahora. No creo que ningún otro caparazón (¿excepto peces?) Permita caminos con dos puntos en RUTA de todos modos.
Tyilo
6

Hay (ahora?) Una manera más fácil, según la respuesta de @ Zanchey aquí

Fish Shell: Cómo configurar múltiples variables de entorno desde un archivo usando exportar

Sin embargo, el resumen es:

Pescado:

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

Golpetazo:

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

con la diferencia de ser $y el uso dexargs

Chris Conover
fuente
Mucho más conveniente y sin ninguna sintaxis especial. Gracias
Panayotis
No funciona para matrices como $ PATH
JanKanis
5

La mayoría de los sistemas Unix usan PAM . El pam_envmódulo lee un archivo muy parecido a tu .env.

En Linux , pam_envlee un archivo de sistema /etc/environmenty un archivo de usuario ~/.pam_environment. En OS X (y otros * BSD, que también usan OpenPAM), parece que pam_envsolo lee el archivo del sistema, por lo que no puede establecer variables por usuario de esta manera, solo para todos los usuarios.

Gilles 'SO- deja de ser malvado'
fuente
1

Ampliando la respuesta de @ ridiculous_fish, con la siguiente función para bash también funciona para matrices que contienen espacios, como $PATHsi tiene espacios en sus caminos. Sin embargo, setenvya está definido como una función en la biblioteca estándar de peces hoy en día, así que cambié el nombre aquí ashenv

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

Ahora en su .envarchivo puede especificar componentes de la matriz como argumentos separados para el setenvcomando:

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

Para la implementación simple de fish @ ridiculous_fish se hará:

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

Simplemente cree una función en $ HOME / .config / fish / functions / env.fish con contenido:

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

compartió todos los vars creados en bash en la carpeta /etc/profile.d

por ejemplo: /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

simplemente inicie sesión en fish o bash, haga echo $GOPATH $GOROOT $GOBIN $PATHy vea la magia :)

Iury Fukuda
fuente