Совместное использование переменных окружения между рыбой и рыбой

13

Скрипты bash и fish не совместимы, но я хотел бы иметь файл, который определяет некоторые переменные окружения, которые должны инициализироваться как bash, так и fish.

Мое предлагаемое решение - определить ~/.envфайл, который будет содержать список переменных среды, например:

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

Затем я мог бы просто найти его в bash и создать скрипт, который конвертирует его в формат fish и исходники в fish.

Я думал, что может быть лучшее решение, чем это, поэтому я прошу лучшего способа распределения переменных среды между рыбой bash.

Примечание: я использую OS X.


Вот пример .envфайла, который я хотел бы, чтобы и fish, и bash обрабатывали с использованием синтаксиса Смешной рыбы (предположим, ~ / bin и ~ / bin2 - пустые каталоги):

setenv _PATH "$PATH"
setenv PATH "$HOME/bin"
setenv PATH "$PATH:$HOME/bin2"
setenv PATH "$PATH:$_PATH"
Tyilo
источник

Ответы:

17

bash имеет специальный синтаксис для установки переменных окружения, в то время как fish использует встроенную функцию. Я бы предложил написать ваш .env файл так:

setenv VAR1 val1
setenv VAR2 val2

и затем определяя setenvсоответственно в соответствующих оболочках. В bash (например, .bashrc):

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

В рыбе (например, config.fish):

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

Обратите внимание, что PATH потребует особой обработки, так как это массив в fish, а строка в двоеточии, разделенная двоеточиями, в bash. Если вы предпочитаете писать setenv PATH "$HOME/bin:$PATH"в .env, вы можете написать рыбный setenv примерно так:

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

Это будет неправильно обрабатывать элементы в PATH, которые содержат пробелы, двоеточия или символы новой строки.

Неловкость в PATH происходит из-за смешения строк, разделенных двоеточиями, с истинными массивами. Предпочтительным способом добавления к PATH у рыб является простой set PATH $PATH ~/bin.

ridiculous_fish
источник
1
Будет ли PATHисправление для рыбы работать с путями с пробелами? строки? другие вещи, чтобы высматривать?
Tyilo
[это встроенный в bash и fish, поэтому не нужно правильно задавать PATH для использования [. Образец setenv должен работать со всеми символами в PATH, за исключением двоеточий и новых строк.
ridiculous_fish
Заменив trна /usr/bin/trI и используя .envфайл, указанный в моем вопросе, я получаю много ошибок при запуске fish. Я не думаю, что обработка PATH правильная.
Tyilo
Ах, да, рыба будет разделять это в кавычках. Я обновлю комментарий.
ridiculous_fish
Да, это работает сейчас. Я не думаю, что любая другая оболочка (кроме рыбы?) В любом случае разрешает пути с двоеточиями в PATH.
Tyilo
6

Существует (сейчас?) Более простой способ, согласно ответу @ Zanchey здесь

Fish Shell: Как установить несколько переменных среды из файла, используя экспорт

Дайджест:

Рыбы:

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

с той разницей, $что использование иxargs

Крис Коновер
источник
Гораздо удобнее и без какого-либо специального синтаксиса. Спасибо
Panayotis
Не работает для массивов, таких как $ PATH
JanKanis
5

Большинство систем Unix используют PAM . pam_envМодуль считывает файл очень нравится ваш .env.

В Linux , pam_envчитает системный файл /etc/environmentи файл пользователя ~/.pam_environment. В OS X (и других * BSD, которые также используют OpenPAM), кажется, что pam_envчитает только системный файл, поэтому вы не можете установить переменные для пользователя таким образом, только для всех пользователей.

Жиль "ТАК - перестань быть злым"
источник
1

Расширяя ответ @ ridiculous_fish, используя следующую функцию для bash, он также работает для массивов, содержащих пробелы, например, $PATHесли у вас есть пробелы в ваших путях. Однако в setenvнастоящее время она уже определена как функция в стандартной библиотеке fish, поэтому я изменил здесь имя наshenv

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

Теперь в вашем .envфайле вы можете указать компоненты массива в качестве отдельных аргументов setenvкоманды:

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

Для простой реализации fish @ ridiculous_fish:

function shenv; set -gx $argv; end
source ~/.env
JanKanis
источник
1

Просто создайте функцию в $ HOME / .config / fish / functions / env.fish с содержимым:

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

поделился всеми переменными, созданными в bash, в папке /etc/profile.d

например: /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

просто залогиньтесь на fish или bash, сделайте echo $GOPATH $GOROOT $GOBIN $PATHи увидите магию :)

Юрий Фукуда
источник