Задать переменные среды из файла
Я пишу скрипт в bash, который анализирует файлы с 3 переменными в определенной папке, это один из них:
MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"
этот файл хранится в ./ conf / prac1
мой скрипт minientrega.sh затем анализирует файл с помощью этого кода:
cat ./conf/ | while read line; do
export $line
done
но когда я выполнить minientrega.sh prac1
в командной строке он не устанавливает переменные среды
Я также попытался с помощью source ./conf/
но та же проблема по-прежнему применяется
может есть какой другой способ сделать это, мне просто нужно использовать переменные среды файла, который я передаю в качестве аргумента моего скрипта.
19 ответов
проблема с вашим подходом является export
на while
цикл происходит в суб-оболочке, и эта переменная не будет доступна в текущей оболочке (родительская оболочка цикла while).
добавить в самом файле:
export MINIENTREGA_FECHALIMITE="2011-03-31"
export MINIENTREGA_FICHEROS="informe.txt programa.c"
export MINIENTREGA_DESTINO="./destino/entrega-prac1"
тогда вам нужно источник в файле в текущей оболочке, используя:
. ./conf/prac1
или
source ./conf/prac1
это может быть полезно:
export $(cat .env | xargs) && rails c
причина, почему я использую это, если я хочу проверить .env
материал в моей консоли rails.
gabrielf придумал хороший способ сохранить переменные локальными. Это решает потенциальную проблему при переходе от проекта к проекту.
env $(cat .env | xargs) rails
я протестировал это с bash 3.2.51(1)-release
обновление:
игнорировать строки, начинающиеся с #
используйте этот (спасибо Пит):
export $(grep -v '^#' .env | xargs)
и если вы хотите unset
все переменные, определенные в файле, используйте этот:
unset $(grep -v '^#' .env | sed -E 's/(.*)=.*//' | xargs)
обновление:
чтобы также обрабатывать значения с пробелами, используйте:
export $(grep -v '^#' .env | xargs -d '\n')
в системах GNU или:
export $(grep -v '^#' .env | xargs -0)
на системах BSD.
-o allexport
позволяет экспортировать все следующие определения переменных. +o allexport
отключает эту функцию.
set -o allexport
source conf-file
set +o allexport
на allexport
опция упоминается в нескольких других ответах здесь, для которых set -a
- это ярлык. Источник .env действительно лучше, чем цикл по строкам и экспорт, потому что он допускает комментарии, пустые строки и даже переменные среды, генерируемые командами. Мой. bashrc и включает в себя следующее:
# .env loading in the shell
dotenv () {
set -a
[ -f .env ] && . .env
set +a
}
# Run dotenv on login
dotenv
# Run dotenv on every new directory
cd () {
builtin cd $@
dotenv
}
вот еще sed
решение, которое не запускает eval или не требует ruby:
source <(sed -E -n 's/[^#]+/export &/ p' ~/.env)
это добавляет экспорт, сохраняя комментарии к строкам, начинающимся с комментария.
.env contents
A=1
#B=2
образца
$ sed -E -n 's/[^#]+/export &/ p' ~/.env
export A=1
#export B=2
я нашел это особенно полезно при создании такого файла для загрузки в файл блока systemd, с EnvironmentFile
.
SAVE=$(set +o) && set -o allexport && . .env; eval "$SAVE"
Это позволит сохранить/восстановить исходные параметры, какими бы они ни были.
используя set -o allexport
имеет преимущество правильного пропуска комментариев без регулярного выражения.
set +o
сам по себе выводит все ваши текущие параметры в формате, который bash может позже выполнить. Также удобно:set -o
сам по себе, выводит все ваши текущие параметры в удобном для человека формате.
Я ввел ответ user4040650, потому что он прост, и он позволяет комментарии в файле (т. е. строки, начинающиеся с#), что очень желательно для меня, так как комментарии, объясняющие переменные, могут быть добавлены. Просто переписываю в контексте первоначального вопроса.
Если скрипт callled как указано: minientrega.sh prac1
, тогда minientrega.sh мог бы:
set -a # export all variables created next
source
set +a # stop exporting
# test that it works
echo "Ficheros: $MINIENTREGA_FICHEROS"
следующее было извлечено из набор документации:
эта постройка настолько сложна, что заслуживает собственного раздела. набор позволяет изменять значения параметров оболочки и устанавливать позиционные параметры или отображение имен и значений оболочки переменная.
set [--abefhkmnptuvxBCEHPT] [- o option-name] [аргумент ...] set [+abefhkmnptuvxBCEHPT] [+o option-name] [аргумент ...]
Если параметры или аргументы не указаны, set отображает имена и значения всех оболочек переменные и функции, отсортированный по текущей локали, в формат, который может быть использован в качестве входного для установки или сброса в настоящее время-набор переменных. Переменные только для чтения не могут быть сброшены. В POSIX mode, перечислены только переменные оболочки.
когда параметры предоставляются, они устанавливают или отключают атрибуты оболочки. Параметры, если они указаны, имеют следующие значения:
- каждой переменной или функции, которая создается или изменяется, присваивается атрибут export и помечается для экспорта в окружающая среда последующие команды.
а также:
использование ‘ + 'вместо' - ' приводит к отключению этих параметров. Этот опции также могут использоваться при вызове оболочки. Текущий набор из вариантов можно найти в$ -.
улучшение ответа Сайласа Павла
экспорт переменных в подрешетке делает их локальными для команды.
(export $(cat .env | xargs) && rails c)
проще:
- захватить содержимое файла
- удалите все пустые строки (просто incase вы отделили некоторые вещи)
- удалить любые комментарии (просто incase вы добавили некоторые...)
- добавить
export
ко всем строкам -
eval
все
eval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')
другой вариант (вам не придется бегать eval
(спасибо @Jaydeep)):
export $(cat .env | sed -e /^$/d -e /^#/d | xargs)
наконец, если вы хотите сделать свою жизнь очень простой, добавьте это в свой ~/.bash_profile
:
function source_envfile() { export $(cat | sed -e /^$/d -e /^#/d | xargs); }
(УБЕДИТЕСЬ, ЧТО ВЫ ПЕРЕЗАГРУЗИТЕ НАСТРОЙКИ BASH!!! source ~/.bash_profile
или.. просто сделать новую вкладку/Окно и проблема решена) вы называете это так: source_envfile .env
вы можете использовать свой оригинальный скрипт для установки переменных, но вам нужно вызвать его следующим образом (с автономной точкой):
. ./minientrega.sh
также может возникнуть проблема с cat | while read
подход. Я бы рекомендовал использовать подход while read line; do .... done < $FILE
.
вот пример:
> cat test.conf
VARIABLE_TMP1=some_value
> cat run_test.sh
#/bin/bash
while read line; do export "$line";
done < test.conf
echo "done"
> . ./run_test.sh
done
> echo $VARIABLE_TMP1
some_value
основываясь на других ответах, вот способ экспортировать только подмножество строк в файл, включая значения с пробелами, такими как PREFIX_ONE="a word"
:
set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
у меня есть проблемы с ранее предложенными решениями:
- решение@anubhava делает написание файлов конфигурации bash friendly очень раздражающим очень быстро, а также - вы можете не всегда экспортировать свою конфигурацию.
- @Silas Paul решение ломается, когда у вас есть переменные, которые имеют пробелы или другие символы, которые хорошо работают в кавычках значений, но
$()
делает беспорядок.
вот мое решение, которое все еще довольно ужасно IMO-и не решает проблему "экспорт только в один ребенок", рассмотренную Сайласом (хотя вы, вероятно, можете запустить ее в под-оболочке, чтобы ограничить область):
source .conf-file
export $(cut -d= -f1 < .conf-file)
пробелы в значении
здесь есть много отличных ответов, но я нашел, что им всем не хватает поддержки белого пространства в значении:
DATABASE_CLIENT_HOST=host db-name db-user 0.0.0.0/0 md5
Я нашел 2 решения, которые работают с такими значениями с поддержкой пустых строк и комментариев.
один на основе sed и @javier-buzzi ответ:
source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x "&"/g' .env)
и один с прочитанной строкой в цикле на основе @john1024 ответ
while read -r line; do declare -x "$line"; done < <(egrep -v "(^#|^\s|^$)" .env)
ключ заключается в использовании declare -x
и ввод строки в двойные кавычки. Я не знаю, почему, но когда вы переформатируете код цикла на несколько строк, он не будет работать - я не программист bash, я просто сожрал их, это все еще магия для меня:)
если вы получаете ошибку, потому что одна из ваших переменных содержит значение, содержащее пробелы, вы можете попытаться сбросить bash IFS
(внутренний разделитель полей) в \n
пусть Баш интерпретирует cat .env
результат в виде списка параметров для env
исполняемый файл.
пример:
IFS=$'\n'; env $(cat .env) rails c
посмотреть также:
Если вы хотите загрузить ваш .env-файл в запущенный процесс внутри кода Visual Studio можно добавить ссылку на свой .env файл в вашем launch.json
С помощью envFile
свойства:
"configurations": [
{
"name": "Launch server.js with .env",
"type": "node",
"request": "launch",
"envFile": "${workspaceRoot}/.env",
...
}
]
я наткнулся на эту тему, когда пытался повторно использовать Docker --env-file
s в оболочке. формат не совместим с bash, но это просто:name=value
, не цитирую, нет замены. Они также игнорируют пустые строки и #
комментарии.
Я не мог получить совместимость с posix, но вот тот, который должен работать в bash-подобных оболочках (протестирован в zsh на OSX 10.12.5 и bash на Ubuntu 14.04):
while read -r l; do export "$(sed 's/=.*$//' <<<$l)"="$(sed -E 's/^[^=]+=//' <<<$l)"; done < <(grep -E -v '^\s*(#|$)' your-env-file)
это не будет ручка три случая в примере из документов, связанных выше:
bash: export: `123qwe=bar': not a valid identifier
bash: export: `org.spring.config=something': not a valid identifier
- и он не будет обрабатывать синтаксис passthrough (голый
FOO
)
мой .env:
#!/bin/bash
set -a # export all variables
#comments as usual, this is a bash script
USER=foo
PASS=bar
set +a #stop exporting variables
вызов:
source .env; echo $USER; echo $PASS
ссылка https://unix.stackexchange.com/questions/79068/how-to-export-variables-that-are-set-all-at-once