TL; DR: как экспортировать набор пар ключ / значение из текстового файла в среду оболочки?
Для справки ниже приведена оригинальная версия вопроса с примерами.
Я пишу скрипт на bash, который анализирует файлы с 3 переменными в определенной папке, это одна из них:
MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"
Этот файл хранится в ./conf/prac1
Мой скрипт minientrega.sh затем анализирует файл, используя этот код:
cat ./conf/$1 | while read line; do
export $line
done
Но когда я выполняю minientrega.sh prac1
в командной строке, он не устанавливает переменные среды
Я также пытался использовать, source ./conf/$1
но та же проблема по-прежнему применяется
Возможно, есть какой-то другой способ сделать это, мне просто нужно использовать переменные окружения файла, который я передаю в качестве аргумента моего скрипта.
bash
variables
environment-variables
hugo19941994
источник
источник
Ответы:
Проблема с вашим подходом заключается
export
в том, чтоwhile
цикл in происходит в вложенной оболочке, и эти переменные не будут доступны в текущей оболочке (родительской оболочке цикла while).Добавьте
export
команду в сам файл:Затем вам нужно найти исходный файл в текущей оболочке, используя:
ИЛИ
источник
export
не является идеальным, проблема также может быть решена просто используя перенаправление ввода на петле:while read line; do ... ; done < ./conf/$1
.< <(commands that generate output)
set -o allexport
export
сломает его для таких вещей, как Java, SystemD или другие инструментыawk '{print "export " $0}' envfile
удобная команда для добавления экспорта в начало каждой строкиЭто может быть полезно:
Причина, по которой я это использую, заключается в том, что я хочу проверить
.env
материал в моей консоли rails.Габриэль нашел хороший способ сохранить переменные локальными. Это решает потенциальную проблему при переходе от проекта к проекту.
Я проверил это с
bash 3.2.51(1)-release
Обновить:
Чтобы игнорировать строки, начинающиеся с
#
, используйте это (благодаря комментарию Пита ):И если вы хотите, чтобы
unset
все переменные, определенные в файле, используйте это:Обновить:
Чтобы также обрабатывать значения с пробелами, используйте:
в системах GNU - или:
на системах BSD.
источник
export $(cat .env)
но я не знаю, как справиться с пробелами.-d
для установки разделителя, так что я пытаюсьenv $(cat .env | xargs -d '\n') rails
, но он все равно ошибки с файлом не найден, если.env
есть пробелы. Есть идеи, почему это не работает?eval $(cat .env) rails
-o allexport
позволяет экспортировать все следующие определения переменных.+o allexport
отключает эту функцию.источник
.env
файле есть комментарии. Спасибо!set -o allexport; source conf-file; set +o allexport
set -a; . conf-file; set +a
.Если
env.txt
это как:Пояснения -a эквивалентны allexport . Другими словами, каждое присвоение переменной в оболочке экспортируется в среду (для использования несколькими дочерними процессами). Дополнительную информацию можно найти во встроенной документации Set :
источник
-a
эквивалентноallexport
. Другими словами, каждое присвоение переменной в оболочкеexport
вводится в среду (для использования несколькими дочерними процессами). Также смотрите эту статью gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlallexport
Вариант упоминается в нескольких других ответов здесь, для которыхset -a
является ярлык. Поиск .env действительно лучше, чем циклический переход по строкам и экспорт, потому что он допускает комментарии, пустые строки и даже переменные окружения, сгенерированные командами. Мой .bashrc включает в себя следующее:источник
VAR=
.источник
eval $(cat .env | sed 's/^[^$]/export /')
позволяет вам иметь пустые строки для лучшей читаемости.cat .env | sed 's/^[^$]/export /'
лишает первоначального персонажа. Т.е. за файлA=foo\nB=bar\n
я получаюexport =foo\nexport =bar\n
. Это работает лучше для пропуска пустых строк:cat .env | sed '/^$/! s/^/export /'
.cat
ни в одном из случаев:eval $(sed 's/^/export /' .env)
работаетЯ нашел самый эффективный способ:
объяснение
Когда у нас есть такой
.env
файл:беги
xargs < .env
получишьkey=val foo=bar
так мы получим
export key=val foo=bar
и это именно то что нам нужно!ограничение
источник
env
производить этот формат.Вот еще одно
sed
решение, которое не запускает eval или не требует ruby:Это добавляет экспорт, сохраняя комментарии в строках, начиная с комментария.
содержание .env
пробный прогон
Я нашел это особенно полезным при создании такого файла для загрузки в файл системного модуля, с
EnvironmentFile
.источник
Я проголосовал за user4040650, потому что он простой и позволяет оставлять комментарии в файле (т.е. строки, начинающиеся с #), что для меня крайне желательно, так как можно добавлять комментарии, объясняющие переменные. Просто переписываю в контексте оригинального вопроса.
Если скрипт вызывается так, как указано:,
minientrega.sh prac1
тогда minientrega.sh может иметь:Следующее было извлечено из комплекта документации :
И это также:
источник
Улучшение ответа Сайласа Павла
экспорт переменных в подоболочку делает их локальными для команды.
(export $(cat .env | xargs) && rails c)
источник
(set -a; source dev.env; set +a; rails c)
чтобы также иметь преимущества поиска (например, скрипт может выполняться).SAVE=$(set +o | grep allexport) && set -o allexport && . .env; eval "$SAVE"
Это сохранит / восстановит ваши исходные параметры, какими бы они ни были.
Использование
set -o allexport
имеет то преимущество, что правильно пропускает комментарии без регулярных выражений.set +o
Сам по себе выводит все ваши текущие параметры в формате, который позже может выполнить bash. Также удобно:set -o
само по себе выводит все ваши текущие параметры в удобном для человека формате.источник
exec env -i bash
очистил существующую среду перед вызовом,eval
если вам нужно сбросить переменные, которые установлены только внутри.env
.Самый короткий путь, который я нашел:
Ваш
.env
файл:Тогда просто
Бонус: поскольку это короткий однострочный текст, он очень полезен в
package.json
файлеисточник
VARIABLE_NAME="A_VALUE"
Simpler:
export
ко всем строкамeval
Все этоeval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')
Другой вариант (вам не нужно запускаться
eval
(спасибо @Jaydeep)):Наконец, если вы хотите сделать свою жизнь ДЕЙСТВИТЕЛЬНО легкой, добавьте это в
~/.bash_profile
:function source_envfile() { export $(cat $1 | sed -e /^$/d -e /^#/d | xargs); }
(УБЕДИТЕСЬ, ЧТО ВЫ ПЕРЕГРУЖАЕТЕ НАСТРОЙКИ BASH !!!
source ~/.bash_profile
или .. просто создайте новую вкладку / окно и проблема решена) Вы называете это так:source_envfile .env
источник
source <( echo $(sed -E -n 's/[^#]+/ &/ p' <(echo "${2}" | tr -d '\r')) );
. Каким-то образом gitlab сохраняет секретную переменную с возвратом каретки Windows, поэтому мне пришлось урезать егоtr -d '\r'
.Вы можете использовать свой оригинальный скрипт для установки переменных, но вам нужно назвать его следующим образом (с отдельной точкой):
Также может быть проблема с
cat | while read
подходом. Я бы порекомендовал использовать подходwhile read line; do .... done < $FILE
.Вот рабочий пример:
источник
test.conf
является файлом сценария. Это делает это лучше. Безопаснее не разрешать скрипты, если они вам действительно не нужны, особенно если кто-то не понимает, что происходит (или забывает).Основываясь на других ответах, вот способ экспортировать только подмножество строк в файле, включая значения с такими пробелами, как
PREFIX_ONE="a word"
:источник
Вот мой вариант:
по сравнению с предыдущими решениями:
.env
не предоставляются вызывающей стороне )set
вариантыset -a
.
вместо того,source
чтобы избежать башизма.env
загрузка не удаласьисточник
set -a && . ./.env && "$@" && echo "your comand here"
Я работаю с docker-compose и
.env
файлами на Mac и хотел импортировать их.env
в мою оболочку bash (для тестирования), и «лучшим» ответом здесь было срабатывание следующей переменной:.env
Решение
Так что я закончил тем, что использовал
eval
и заключил свои env var def в одинарные кавычки.Версия Bash
источник
Мой .env:
Вызов:
Ссылка /unix/79068/how-to-export-variables-that-are-set-all-at-once
источник
У меня есть проблемы с ранее предложенными решениями:
$()
мешают.Вот мое решение, которое все еще довольно ужасно для ИМО - и не решает проблему «экспорта только одному дочернему элементу», решаемую Сайласом (хотя вы, вероятно, можете запустить ее в под-оболочке, чтобы ограничить область действия):
источник
Мои требования были:
export
префиксов (для совместимости с dotenv)Полная рабочая версия составлена из ответов выше:
источник
Во-первых, создайте файл среды, в котором будут все пары ключ-значение сред, как показано ниже, и назовите его как угодно в моем случае, его
env_var.env
Затем создайте скрипт, который будет экспортировать все переменные среды для среды Python, как показано ниже, и назовите его как
export_env.sh
Этот сценарий примет первый аргумент в качестве файла среды, затем экспортирует все переменные среды в этом файле и затем запустит команду после этого.
ПРИМЕНЕНИЕ:
источник
Я наткнулся на эту тему, когда пытался повторно использовать Docker
--env-file
в оболочке. Их формат не совместим с bash, но он прост:name=value
без цитирования, без подстановки. Они также игнорируют пустые строки и#
комментарии.Я не смог получить его с помощью posix-совместимости, но вот тот, который должен работать в bash-подобных оболочках (протестировано в zsh на OSX 10.12.5 и bash на Ubuntu 14.04):
Он не будет обрабатывать три случая в примере из документов, связанных выше:
bash: export: `123qwe=bar': not a valid identifier
bash: export: `org.spring.config=something': not a valid identifier
FOO
)источник
Пробелы в значении
Здесь есть много хороших ответов, но я обнаружил, что им не хватает пробела в значении:
Я нашел 2 решения, которые работают с такими значениями с поддержкой пустых строк и комментариев.
Один основан на SED и @ хавьер-BUZZI ответ :
И один с строкой чтения в цикле на основе ответа @ john1024
Ключевым моментом здесь является использование
declare -x
и размещение строки в двойных кавычках. Я не знаю почему, но когда вы переформатируете код цикла в несколько строк, это не сработает - я не программист bash, я просто сожрал их вместе, это по-прежнему волшебно для меня :)источник
sed
решение, чтобы заставить его работать. Но сначала несколько объяснений:-e
это сокращение--expression
, которое просто говорит,sed
какие операции нужно предпринять.-e /^$/d
удаляет пустые строки из вывода (не из файла).-e /^#/d
удаляет комментарии bash (строки, начинающиеся с #) из вывода.'s/.*/declare -x "&"/g'
заменяет (заменяет) оставшиеся строки наdeclare -x "ENV_VAR="VALUE""
. Когда вы получаете это, по крайней мере для меня, это не сработало. Вместо этого мне пришлось использоватьsource <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env)
, чтобы удалить лишнюю"
обертку.ENV_VAR="lorem ipsum"
, у меня естьENV_VAR=lorem ipsum
, без кавычек в файле .env. Теперь я не уверен, почему, но это, вероятно, было проблематично в других инструментах, которые анализируют этот файл. И вместо этогоlorem ipsum
я закончил со"lorem ipsum"
значением - с кавычками. Спасибо за объяснения :)ENV_VAR="lorem ipsum"
. В моем случае мой провайдер хостинга генерирует этот файл на основе некоторых опций конфигурации, которые я установил, и они вставляют двойные кавычки. Итак, я вынужден обойти это. Спасибо за вашу помощь здесь - сэкономил мне много времени, пытаясь выработать правильныеsed
варианты самостоятельно!попробуй что-нибудь подобное
источник
Как это работает
.env
файл. Все переменные будут экспортированы в текущую среду.declare -x VAR="val"
то, что экспортирует каждую переменную в окружение.особенности
.env
может иметь комментарии.env
может иметь пустые строки.env
не требует специального верхнего или нижнего колонтитула, как в других ответах (set -a
иset +a
).env
не требует иметьexport
для каждого значенияисточник
Если вы получаете сообщение об ошибке, поскольку одна из ваших переменных содержит значение, содержащее пробелы, вы можете попытаться сбросить bash
IFS
(Внутренний разделитель полей),\n
чтобы позволить bash интерпретироватьcat .env
результат как список параметров дляenv
исполняемого файла.Пример:
Смотрите также:
источник
Мой файл .env выглядит так:
Используя способы @henke , экспортируемое значение заканчивается кавычками
"
Но я хочу, чтобы экспортированное значение содержало только:
Чтобы исправить это, я редактирую команду для удаления кавычек:
источник
Этот справляется с пробелами в RHS и пропускает «странные» переменные, такие как определения модуля bash (с «()» в них):
источник