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
を使ってみましたが、同じ問題がまだ当てはまります
これを行うには他の方法があるかもしれません、私は私のスクリプトの引数として渡すファイルの環境変数を使用する必要があります。
あなたのアプローチでの問題は、export
ループのwhile
がサブシェルで起こっているということです、そして、それらの変数は現在のシェル(whileループの親シェル)では利用できません。
ファイル自体にexport
コマンドを追加します。
export MINIENTREGA_FECHALIMITE="2011-03-31"
export MINIENTREGA_FICHEROS="informe.txt programa.c"
export MINIENTREGA_DESTINO="./destino/entrega-prac1"
それから、あなたは現在のシェルのファイルにソースを入れる必要があります:
. ./conf/prac1
OR
source ./conf/prac1
これは役に立つかもしれません:
export $(cat .env | xargs) && Rails c
これを使用する理由は、Railsコンソールで.env
のものをテストしたい場合です。
gabrielf は変数をローカルに保つ良い方法を思いついた。これはプロジェクトからプロジェクトへと進むときの潜在的な問題を解決します。
env $(cat .env | xargs) Rails
私はこれをbash 3.2.51(1)-release
でテストしました
更新:
#
で始まる行を無視するには、これを使用します( Peteのコメント のおかげで):
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システムでは。
-o allexport
は、以下のすべての変数定義をエクスポートできるようにします。 +o allexport
はこの機能を無効にします。
set -o allexport
source conf-file
set +o allexport
set -a
. ./env.txt
set +a
env.txt
が次のようなものであれば:
VAR1=1
VAR2=2
VAR3=3
...
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
}
eval $(cat .env | sed 's/^/export /')
これは、evalを実行したりRubyを必要としない、他のsed
ソリューションです。
source <(sed -E -n 's/[^#]+/export &/ p' ~/.env)
これはエクスポートを追加し、コメントで始まる行にコメントを残します。
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の答えは単純で、ファイル内のコメント(つまり#で始まる行)も許可されているので、私は支持しました。これは変数を説明するコメントを追加できるので非常に望ましいです。元の質問の文脈で書き直すだけです。
スクリプトが示されているように呼び出されると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オプション名] [引数…] set [+ abefhkmnptuvxBCEHPT] [+ oオプション名] [引数…]
オプションも引数も指定されていない場合、setは現在のロケールに従ってソートされたすべてのシェル変数と関数の名前と値を、現在設定されている変数の設定またはリセットの入力として再利用できる形式で表示します。読み取り専用変数はリセットできません。 POSIXモードでは、シェル変数のみがリストされます。
オプションが与えられると、それらはシェル属性を設定または設定解除します。オプションが指定されている場合は、以下の意味があります。
-a作成または変更された各変数または関数にはexport属性が与えられ、後続のコマンドの環境へのエクスポート用にマークされます。
そしてこれも:
「 - 」ではなく「+」を使用すると、これらのオプションは無効になります。オプションはシェルの起動時にも使用できます。現在のオプションセットは$ - にあります。
Silas Paulの答えを改善する
サブシェルで変数をエクスポートすると、それらはコマンドに対してローカルになります。
(export $(cat .env | xargs) && Rails c)
もっと簡単:
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 $1 | sed -e /^$/d -e /^#/d | xargs); }
(あなたがあなたのBASH設定を再ロードすることを確認してください!!! source ~/.bash_profile
または..新しいタブ/ウィンドウを作成し、問題を解決してください)あなたはそれを次のように呼びます:source_envfile .env
他の答えに基づいて、これはPREFIX_ONE="a Word"
のようなスペースを含む値を含むファイル内の行のサブセットのみをエクスポートする方法です。
set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
元のスクリプトを使用して変数を設定できますが、次のように呼び出す必要があります(スタンドアロンドットを使用)。
. ./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
私の要求は、
export
接頭辞のない単純な.envファイル上記の回答からコンパイルされたフルバージョン
set -o allexport
eval $(grep -v '^#' .env | sed 's/^/export /')
set +o allexport
私が見つけた最短の方法:
あなたの.env
ファイル:
VARIABLE_NAME="A_VALUE"
それからちょうど
. ./.env && echo ${VARIABLE_NAME}
おまけ:これは短いワンライナーなので、package.json
ファイルでとても役に立ちます
"scripts": {
"echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
}
ここにはたくさんの素晴らしい答えがありますが、私はそれらがすべて値の余白のサポートを欠いているのを見つけました:
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プログラマではありません。これらを一緒に手に入れただけです。
私は以前に提案された解決策に問題があります:
$()
は失敗します。これは私の解決策です、それはまだかなりひどいIMOです - そしてSilasによって対処された「一人の子供だけにエクスポートする」問題を解決しません(ただし、範囲を制限するためにサブシェルでそれを実行することができます)。
source .conf-file
export $(cut -d= -f1 < .conf-file)
変数の1つに空白を含む値が含まれているためにエラーが発生した場合は、bashのIFS
実行可能ファイルのリストとして\n
の結果を解釈するためにbashのenv
(Internal Field Separator)をcat .env
にリセットします。
例:
IFS=$'\n'; env $(cat .env) Rails c
また見なさい:
私はMac上でdocker-composeファイルと.env
ファイルを操作していて、.env
を私のbashシェルにインポートしたい(テストのため)ことを望みました。
.env
NODE_ARGS=--expose-gc --max_old_space_size=2048
そのため、私はeval
を使用し、env var defを一重引用符で囲みました。
eval $(grep -v -e '^#' .env | xargs -I {} echo export \'{}\')
バッシュバージョン
$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-Apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.
シェルでDockerの--env-file
sを再利用しようとしたときに、このスレッドに出くわしました。 それらのフォーマット はbash互換ではありませんが、単純です:name=value
、引用符、置換はありません。空白行や#
コメントも無視されます。
POSIX互換にすることはできませんでしたが、bash風のシェル(OSX 10.12.5のzshおよびUbuntu 14.04のbashでテスト済み)で動作するはずのものがあります。
while read -r l; do export "$(sed 's/=.*$//' <<<$l)"="$(sed -E 's/^[^=]+=//' <<<$l)"; done < <(grep -E -v '^\s*(#|$)' your-env-file)
はしない 上のリンクのドキュメントの例では、3つのケースを処理しません。
bash: export: `123qwe=bar': not a valid identifier
bash: export: `org.spring.config=something': not a valid identifier
FOO
)を処理しませんまず、以下のような環境のすべてのキーと値のペアを持つ環境ファイルを作成し、私の場合はenv_var.env
のように好きな名前を付けます。
MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"
それから、以下のようにpython環境用のすべての環境変数をエクスポートするスクリプトを作成し、export_env.sh
のように名前を付けます。
#!/usr/bin/env bash
ENV_FILE="$1"
CMD=${@:2}
set -o allexport
source $ENV_FILE
set +o allexport
$CMD
このスクリプトは最初の引数を環境ファイルとして取り、そのファイル内のすべての環境変数をエクスポートしてからコマンドを実行します。
使用法:
./export_env.sh env_var.env python app.py
私の。
#!/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