Compartilhar variáveis ​​de ambiente entre bash e fish

13

Os scripts bash e fish não são compatíveis, mas eu gostaria de ter um arquivo que defina algumas variáveis ​​de ambiente a serem inicializadas pelo bash e pelo fish.

Minha solução proposta é definir um ~/.envarquivo que contenha a lista de variáveis ​​de ambiente como:

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

Eu poderia apenas fonte-lo no bash e criar um script que o converte para o formato de peixes e fontes que em peixes.

Eu estava pensando que poderia haver uma solução melhor do que isso, então estou pedindo uma maneira melhor de compartilhar variáveis ​​de ambiente entre os peixes do bash.

Nota: estou usando o OS X.


Aqui está um .envarquivo de exemplo que eu gostaria que o fish e o bash manipulassem usando a sintaxe ridiculous-fish (suponha que ~ / bin e ~ / bin2 sejam diretórios vazios):

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

Respostas:

16

O bash possui uma sintaxe especial para definir variáveis ​​de ambiente, enquanto o fish usa um builtin. Eu sugeriria escrever seu arquivo .env assim:

setenv VAR1 val1
setenv VAR2 val2

e depois definindo setenvapropriadamente nos respectivos invólucros. No bash (por exemplo, bashrc):

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

Em peixes (por exemplo, config.fish):

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

Observe que PATH exigirá algum tratamento especial, já que é uma matriz em peixes, mas uma sequência delimitada por dois pontos no bash. Se você preferir escrever setenv PATH "$HOME/bin:$PATH"em .env, você pode escrever setenv do peixe da seguinte forma:

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

Isso manipula incorretamente os elementos no PATH que contêm espaços, dois pontos ou novas linhas.

O constrangimento no PATH é devido à mistura de cadeias delimitadas por dois pontos com matrizes verdadeiras. A maneira preferida de acrescentar ao PATH no peixe é simplesmente set PATH $PATH ~/bin.

ridiculous_fish
fonte
1
A PATHcorreção para peixes funcionará com caminhos com: espaços? novas linhas? outras coisas para procurar?
Tyilo
[é integrado ao bash e ao fish, portanto, PATH não precisa ser configurado corretamente para uso [. A amostra setenv deve funcionar com todos os caracteres em PATH, exceto dois pontos e novas linhas.
Ridiculous_fish
Substituindo trpor /usr/bin/trI e usando o .envarquivo fornecido na minha pergunta, recebo muitos erros ao iniciar o fish. Eu não acho que o tratamento PATH está correto.
Tyilo
Ah, certo, o peixe separará o espaço entre aspas. Vou atualizar o comentário.
Ridiculous_fish
Sim, agora funciona. Eu não acho que qualquer outra concha (exceto peixe?) Permita caminhos com dois pontos no PATH de qualquer maneira.
31414 Tyll
6

Existe (agora?) Uma maneira mais fácil, de acordo com a resposta de @ Zanchey aqui

Fish Shell: Como definir várias variáveis ​​de ambiente de um arquivo usando a exportação

O resumo, porém, é:

Peixe:

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

Bater:

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

sendo a diferença $e o uso dexargs

Chris Conover
fonte
Muito mais conveniente e sem nenhuma sintaxe especial. Obrigado
Panayotis
Não funciona para matrizes como $ PATH
JanKanis
5

A maioria dos sistemas Unix usa PAM . O pam_envmódulo lê um arquivo muito parecido com o seu .env.

No Linux , pam_envlê um arquivo do sistema /etc/environmente um arquivo do usuário ~/.pam_environment. No OS X (e em outro * BSD, que também usa o OpenPAM), parece que pam_envapenas lê o arquivo do sistema; portanto, você não pode definir variáveis ​​por usuário dessa maneira, apenas para todos os usuários.

Gilles 'SO- parar de ser mau'
fonte
1

Expandindo a resposta de @ ridiculous_fish, com a seguinte função para bash, também funciona para matrizes que contêm espaços, como $PATHse você tivesse espaços em seus caminhos. No entanto, setenvjá está definido como uma função na biblioteca padrão de peixes atualmente, então mudei o nome aqui parashenv

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

Agora, no seu .envarquivo, você pode especificar os componentes da matriz como argumentos separados para o setenvcomando:

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

Para a implementação simples do fish @ ridiculous_fish, será feito:

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

Basta criar uma função em $ HOME / .config / fish / functions / env.fish com o conteúdo:

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

compartilhou todos os vars criados no bash na pasta /etc/profile.d

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

basta entrar no fish ou bash, fazer echo $GOPATH $GOROOT $GOBIN $PATHe ver a mágica :)

Iury Fukuda
fonte