Bagikan variabel lingkungan antara bash dan ikan

13

skrip bash dan fish tidak kompatibel, tetapi saya ingin memiliki file yang mendefinisikan beberapa variabel lingkungan yang akan diinisialisasi oleh bash dan fish.

Solusi yang saya usulkan adalah mendefinisikan ~/.envfile yang akan berisi daftar variabel lingkungan seperti:

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

Saya kemudian bisa hanya sumber di bash dan membuat skrip yang mengubahnya menjadi format ikan dan sumber yang ada di ikan.

Saya berpikir mungkin ada solusi yang lebih baik dari ini, jadi saya meminta cara yang lebih baik untuk berbagi variabel lingkungan antara ikan bash.

Catatan: Saya menggunakan OS X.


Berikut ini contoh .envfile yang ingin saya tangani baik ikan maupun bash menggunakan sintaks konyol-ikan (anggap ~ / bin dan ~ / bin2 adalah direktori kosong):

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

Jawaban:

16

bash memiliki sintaks khusus untuk mengatur variabel lingkungan, sedangkan fish menggunakan builtin. Saya sarankan menulis file .env Anda seperti ini:

setenv VAR1 val1
setenv VAR2 val2

dan kemudian mendefinisikan dengan setenvtepat di masing-masing shell. Dalam bash (misalnya .bashrc):

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

Pada ikan (mis. Ikan config):

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

Perhatikan bahwa PATH akan memerlukan penanganan khusus, karena ini adalah array pada ikan tetapi string yang dibatasi usus di bash. Jika Anda lebih suka menulis setenv PATH "$HOME/bin:$PATH"dalam .env, Anda dapat menulis setenv ikan seperti ini:

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

Ini akan menangani elemen di PATH yang berisi spasi, titik dua, atau baris baru.

Kecanggungan dalam PATH adalah karena mencampur string yang dibatasi usus besar dengan array yang benar. Cara yang lebih disukai untuk menambahkan PATH pada ikan adalah sederhana set PATH $PATH ~/bin.

ridiculous_fish
sumber
1
Akankah PATHperbaikan untuk ikan bekerja dengan jalur dengan: spasi? baris baru? hal-hal lain yang harus diwaspadai?
Tyilo
[adalah builtin pada bash dan fish, jadi PATH tidak perlu diatur dengan benar untuk digunakan [. Sampel setenv harus bekerja dengan semua karakter di PATH kecuali untuk titik dua dan baris baru.
ridiculous_fish
Mengganti trdengan /usr/bin/trsaya dan menggunakan .envfile yang disediakan dalam pertanyaan saya, saya mendapatkan banyak kesalahan saat memulai ikan. Saya tidak berpikir penanganan PATH benar.
Tyilo
Oh, benar, ikan akan memisahkannya di dalam tanda kutip. Saya akan memperbarui komentar.
ridiculous_fish
Yay itu berfungsi sekarang. Saya tidak berpikir ada cangkang lain (kecuali ikan?) Memungkinkan jalur dengan titik dua di PATH.
Tyilo
6

Ada (sekarang?) Cara yang lebih mudah, per jawaban Zanchey di sini

Kerang Ikan: Cara mengatur beberapa variabel lingkungan dari file menggunakan ekspor

Intinya adalah:

Ikan:

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

Pesta:

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

dengan perbedaan menjadi $dan penggunaanxargs

Chris Conover
sumber
Jauh lebih nyaman dan tanpa sintaks khusus. Terima kasih
Panayotis
Tidak berfungsi untuk array seperti $ PATH
JanKanis
5

Sebagian besar sistem Unix menggunakan PAM . The pam_envmodul membaca file yang sangat banyak seperti Anda .env.

Di Linux , pam_envmembaca file sistem /etc/environmentdan file pengguna ~/.pam_environment. Pada OS X (dan * BSD lainnya, yang juga menggunakan OpenPAM), tampaknya pam_envhanya membaca file sistem, jadi Anda tidak dapat mengatur variabel per pengguna dengan cara ini, hanya untuk semua pengguna.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1

Memperluas pada jawaban @ ridiculous_fish, dengan fungsi berikut untuk bash, ia juga berfungsi untuk array yang berisi spasi, seperti $PATHjika Anda memiliki spasi di jalur Anda. Namun setenvsudah didefinisikan sebagai fungsi di perpustakaan standar ikan saat ini jadi saya mengubah nama di sini menjadishenv

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

Sekarang di .envfile Anda, Anda dapat menentukan komponen array sebagai argumen terpisah untuk setenvperintah:

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

Untuk implementasi sederhana dari fish @ ridiculous_fish akan dilakukan:

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

Cukup buat fungsi di $ HOME / .config / fish / functions / env.fish dengan konten:

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

membagikan semua vars yang dibuat dalam bash di folder /etc/profile.d

misalnya: /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

cukup login dengan ikan atau bash, lakukan echo $GOPATH $GOROOT $GOBIN $PATHdan lihat keajaibannya :)

Iury Fukuda
sumber