Какие экспортируемые переменные из файла в Bash? [Дубликат]

Swift 4.2:

Следуя решению casademora,

guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError() }

должно быть

guard let context = decoder.userInfo[CodingUserInfoKey.context!] as? NSManagedObjectContext else { fatalError() }.

Это предотвращает ошибки, которые Xcode ложно распознает как проблемы среза массива.

268
задан b4hand 11 September 2015 в 19:41
поделиться

19 ответов

Вы можете использовать свой исходный скрипт для установки переменных, но вам нужно вызвать его следующим образом (с автономной точкой):

. ./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
110
ответ дан b4hand 22 August 2018 в 08:31
поделиться
  • 1
    Хотя чтение файла по строкам и передача каждой строки в export не идеальны, проблему можно также устранить, просто используя перенаправление ввода в цикле: while read line; do ... ; done < ./conf/$1. – chepner 2 September 2014 в 15:00
  • 2
    И если это не файл, используйте < <(commands that generate output) – o11c 31 August 2017 в 00:10
121
ответ дан b4hand 5 November 2018 в 06:01
поделиться
eval $(cat .env | sed 's/^/export /')
16
ответ дан Amit Joki 22 August 2018 в 08:31
поделиться
  • 1
    Использование eval $(cat .env | sed 's/^[^$]/export /') позволяет иметь пустые строки для лучшей читаемости. – Mario Uher 25 July 2015 в 11:09
  • 2
    Я нахожу, что cat .env | sed 's/^[^$]/export /' удаляет начальный символ. То есть для файла A=foo\nB=bar\n я получаю export =foo\nexport =bar\n. Это лучше работает для пропуска пустых строк: cat .env | sed '/^$/! s/^/export /'. – Owen S. 2 March 2017 в 19:26
  • 3
    (Я также хочу отметить, что для игроков в UNIX-кодексе вам не нужно cat в любом случае: eval $(sed 's/^/export /' .env) работает так же хорошо.) – Owen S. 2 March 2017 в 19:28

Я наткнулся на этот поток, когда я пытался повторно использовать 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
  • , и он не будет обрабатывать синтаксис пересылки (голый FOO)
0
ответ дан Bob Zoller 22 August 2018 в 08:31
поделиться

Если вы получаете сообщение об ошибке, потому что одна из ваших переменных содержит значение, которое содержит пробелы, вы можете попытаться сбросить значение IFS (внутреннего разделителя полей) в bash \n, чтобы интерпретировать результат bash cat .env как список параметров для исполняемого файла env.

Пример:

IFS=$'\n'; env $(cat .env) rails c

См. также:

0
ответ дан Community 22 August 2018 в 08:31
поделиться
set -a
. ./env.txt
set +a

Если env.txt имеет значение:

VAR1=1
VAR2=2
VAR3=3
...
39
ответ дан Dan Kowalczyk 22 August 2018 в 08:31
поделиться
  • 1
    Можете ли вы объяснить -a и + a? – Otto 24 June 2018 в 14:03
  • 2
    @Otto -a эквивалентно allexport. Другими словами, каждое присваивание переменной в оболочке export редактируется в среду (для использования несколькими дочерними процессами). Также см. Эту статью gnu.org/software/bash/manual/html_node/The-Set-Builtin.html – Dan Kowalczyk 25 June 2018 в 16:42

-o allexport позволяет экспортировать все следующие определения переменных. +o allexport отключает эту функцию.

set -o allexport
source conf-file
set +o allexport
198
ответ дан fedorqui 22 August 2018 в 08:31
поделиться
  • 1
    Работает как шарм! Даже если в файле .env есть комментарии. Благодаря! – Slava Fomin II 15 November 2016 в 10:10
  • 2
    И в одной строке set -o allexport; source conf-file; set +o allexport – HarlemSquirrel 15 December 2016 в 03:21
  • 3
    Это отличный способ прочитать в файле свойств, когда подключаемый модуль Jenkins EnvInject не работает. Благодаря! – Teresa Peters 31 January 2017 в 03:49
  • 4
    Это работает с POSIX sh или просто bash? – CMCDragonkai 20 July 2017 в 08:51
  • 5
    @CMCDragonkai, для POSIX это будет set -a; . conf-file; set +a. – Charles Duffy 28 February 2018 в 00:21

Параметр 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
}
17
ответ дан gsf 22 August 2018 в 08:31
поделиться
  • 1
    Это выглядит хорошо, но вы выгружаете переменные среды, когда покидаете каталог? – Bastian Venthur 1 August 2017 в 07:37
  • 2
    Я не отключил переменные, и это никогда не было проблемой. Мои приложения, как правило, используют имена переменных, которые являются разными, и если есть перекрытие, я установлю их в этом .env с помощью VAR=. – gsf 2 August 2017 в 14:41

У меня есть проблемы с ранее предложенными решениями:

  • Решение anubhava делает очень удобными для написания дружественные конфигурационные файлы bash, а также - вы можете не захотеть всегда экспортировать свою конфигурацию.

    / g0]

  • Решение @Silas Paul ломается, когда у вас есть переменные, у которых есть пробелы или другие символы, которые хорошо работают в цитированных значениях, но $() создает беспорядок.

Здесь это мое решение, которое по-прежнему довольно ужасно ИМО - и не решает проблему «экспортировать только одному ребенку», заданную Сайласом (хотя, возможно, вы можете запустить ее в под-оболочке, чтобы ограничить область):

source .conf-file
export $(cut -d= -f1 < .conf-file)
1
ответ дан Guss 22 August 2018 в 08:31
поделиться

Это может быть полезно:

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/(.*)=.*/\1/' | xargs)

Обновление:

Чтобы также обрабатывать значения с пробелами, используйте:

export $(grep -v '^#' .env | xargs -d '\n')

в системах GNU или:

export $(grep -v '^#' .env | xargs -0)

в системах BSD.

454
ответ дан Iulian Onofrei 22 August 2018 в 08:31
поделиться
  • 1
    Спасибо, мне нравится, что это не требует добавления чего-либо к файлу - позволяет совместимость с форматом Foreman (Procfile) .env. – natevw 7 January 2014 в 00:00
  • 2
    Я придумал решение: env $ (cat .env | xargs) рельсы – gabrielf 9 May 2014 в 13:02
  • 3
    исключить комментарии: export $(cat .env | grep -v ^# | xargs) – Pete 12 June 2014 в 18:47
  • 4
    @BenjaminWheeler GNU linux имеет -d для установки разделителя, поэтому я пытаюсь env $(cat .env | xargs -d '\n') rails, но все еще ошибки с файлом не найдены, если .env имеет пробелы. Любая идея, почему это не работает? – Bailey Parker 17 April 2015 в 06:08
  • 5
    Вот более короткая вариация eval $(cat .env) rails – manalang 26 April 2016 в 15:57

Белые пробелы в значении

Здесь много замечательных ответов, но я нашел, что им не хватает поддержки пробела в значении:

DATABASE_CLIENT_HOST=host db-name db-user 0.0.0.0/0 md5

Я нашел 2 решения, которые работают с такими значениями с поддержкой пустых строк и комментариев.

Один на основе sed и @ javier-buzzi answer :

source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x "&"/g' .env)

И один с линией чтения в цикле на основе @ john1024 answer

while read -r line; do declare -x "$line"; done < <(egrep -v "(^#|^\s|^$)" .env)

Ключ здесь заключается в использовании declare -x и вводе строки в двойные кавычки. Я не знаю, почему, но когда вы переформатируете код цикла на несколько строк, это не сработает - я не программист bash, я просто сожрал их, это все еще волшебство для меня:)

1
ответ дан Janusz Skonieczny 22 August 2018 в 08:31
поделиться
  • 1
    Мне пришлось изменить решение 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), чтобы удалить дополнительную обертку ". – jcasner 10 April 2018 в 20:49
  • 2
    Я не использую ENV_VAR="lorem ipsum", у меня есть ENV_VAR=lorem ipsum, без кавычек в файле .env. Теперь я не уверен, почему, но это, вероятно, было проблематично в других инструментах, которые анализируют этот файл. И вместо lorem ipsum я закончил с "lorem ipsum" значением - с кавычками. Thx для объяснений :) – Janusz Skonieczny 11 April 2018 в 06:51
  • 3
    Если бы это был мой выбор, я бы не использовал ENV_VAR="lorem ipsum". В моем случае мой хостинг-провайдер создает этот файл на основе некоторых параметров конфигурации, которые я установил, и они вставляют двойные кавычки. Поэтому я вынужден работать над этим. Спасибо за вашу помощь здесь - сэкономил много времени, пытаясь самостоятельно выработать правильные опции sed! – jcasner 13 April 2018 в 13:53

Упрощение:

  1. захватить содержимое файла
  2. удалить все пустые строки (просто вы можете отделить некоторые вещи)
  3. удалить все комментарии (просто добавьте некоторые ...)
  4. добавьте export ко всем строкам
  5. 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 $1 | sed -e /^$/d -e /^#/d | xargs); }

(УБЕДИТЕСЬ, ЧТО ВЫ ПЕРЕПУСКАЕТЕ ВАШЕ НАСТРОЙКИ БЕСПРОВОДА !!! source ~/.bash_profile или .. просто сделайте новая вкладка / окно и проблема решена) вы называете это следующим образом: source_envfile .env

8
ответ дан Javier Buzzi 22 August 2018 в 08:31
поделиться
  • 1
    Мне пришлось читать .env текст из секретной переменной gitlab для конвейера: на основе вашего решения эта команда работала для меня: source <( echo $(sed -E -n 's/[^#]+/ &/ p' <(echo "${2}" | tr -d '\r')) );. Как-то gitlab сохраняет секретную переменную с возвратом каретки окон, поэтому мне пришлось обрезать это с помощью tr -d '\r'. – metanerd 24 November 2017 в 12:21

Улучшение ответа Сайласа Павла

, экспортирующего переменные на подоболочке, делает их локальными для команды.

(export $(cat .env | xargs) && rails c)

9
ответ дан Jaydeep 22 August 2018 в 08:31
поделиться

SAVE=$(set +o) && set -o allexport && . .env; eval "$SAVE"

Это сохранит / восстановит ваши исходные параметры, какими бы они ни были.

Использование set -o allexport имеет преимущество правильного пропуска комментариев без регулярного выражения.

set +o сам выводит все ваши текущие параметры в формате, который позже может выполнить bash. Также удобно: set -o сам по себе выводит все ваши текущие параметры в удобном для пользователя формате.

12
ответ дан jwfearn 22 August 2018 в 08:31
поделиться
  • 1
    Я бы, вероятно, exec env -i bash очистил существующую среду до вызова eval, если вам нужно отключить переменные, которые установлены только в .env. – b4hand 11 September 2015 в 19:46

Если вы хотите загрузить ваш .env-файл в исполняемый процесс внутри кода Visual Studio, вы можете добавить ссылку на ваш .ENV-файл в свой launch.json, используя свойство envFile:

"configurations": [
    {
        "name": "Launch server.js with .env",
        "type": "node",
        "request": "launch",
        "envFile": "${workspaceRoot}/.env",
        ...
    }
]
0
ответ дан maxpaj 22 August 2018 в 08:31
поделиться

У меня есть ответ на user4040650, потому что он прост и позволяет комментарии в файле (то есть строки, начинающиеся с #), что очень желательно для меня, поскольку комментарии, объясняющие переменные, могут быть добавлены. Просто переписывание в контексте исходного вопроса.

Если скрипт вызван как указано: minientrega.sh prac1, то minientrega.sh может иметь:

set -a # export all variables created next
source $1
set +a # stop exporting

# test that it works
echo "Ficheros: $MINIENTREGA_FICHEROS"

Выбрано следующее: из документации set :

Этот встроенный интерфейс настолько сложный, что он заслуживает своего собственного раздела. set позволяет изменять значения параметров оболочки и устанавливать позиционные параметры или отображать имена и значения переменных оболочки.

set [--abefhkmnptuvxBCEHPT] [-o option-name] [argument ... ] set [+ abefhkmnptuvxBCEHPT] [+ o option-name] [argument ...]

Если параметры и аргументы не заданы, набор отображает имена и значения всех переменных и функций оболочки, отсортированных в соответствии с текущими locale, в формате, который может быть повторно использован как вход для установки или сброса переменных, заданных в текущий момент. Переменные только для чтения не могут быть сброшены. В режиме POSIX перечислены только переменные оболочки.

Когда заданы параметры, они устанавливают или отменяет атрибуты оболочки. Параметры, если они указаны, имеют следующие значения:

-а Каждая переменная или функция, которая создана или изменена, получает атрибут экспорта и помечен для экспорта в среду последующих команд.

И это также:

Использование '+', а не '-' заставляет эти параметры отключать. Эти опции также могут использоваться при вызове оболочки. Текущий набор параметров можно найти в $ -.

8
ответ дан Nagev 22 August 2018 в 08:31
поделиться

My .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-переменные-что-являются-зор-все-в-один раз

-3
ответ дан Tudor Ilisoi 22 August 2018 в 08:31
поделиться

Вот еще одно решение sed, которое не запускает eval или требует ruby:

source <(sed -E -n 's/[^#]+/export &/ p' ~/.env)

Это добавляет экспорт, сохраняя комментарии к строкам, начинающимся с комментария.

.env contents

A=1
#B=2

sample run

$ sed -E -n 's/[^#]+/export &/ p' ~/.env
export A=1
#export B=2

Я нашел это особенно полезным при построении такого файла для загрузки в единичный файл system с EnvironmentFile .

17
ответ дан tutuDajuju 22 August 2018 в 08:31
поделиться

Основываясь на других ответах, вы можете экспортировать только подмножество строк в файле, включая значения с пробелами типа PREFIX_ONE="a word":

set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
5
ответ дан Victor Roetman 22 August 2018 в 08:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: