web-dev-qa-db-ja.com

キー/ペア値のファイルから環境変数を設定する

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を使ってみましたが、同じ問題がまだ当てはまります

これを行うには他の方法があるかもしれません、私は私のスクリプトの引数として渡すファイルの環境変数を使用する必要があります。

341
hugo19941994

あなたのアプローチでの問題は、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
137
anubhava

これは役に立つかもしれません:

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システムでは。

619
Silas Paul

-o allexportは、以下のすべての変数定義をエクスポートできるようにします。 +o allexportはこの機能を無効にします。

set -o allexport
source conf-file
set +o allexport
277
user4040650
set -a
. ./env.txt
set +a

env.txtが次のようなものであれば:

VAR1=1
VAR2=2
VAR3=3
...
70
Dan Kowalczyk

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
}
25
gsf
eval $(cat .env | sed 's/^/export /')
21
selvan

これは、evalを実行したりRubyを必要としない、他のsedソリューションです。

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

これはエクスポートを追加し、コメントで始まる行にコメントを残します。

.envの内容

A=1
#B=2

サンプルラン

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

systemdユニットファイル、EnvironmentFile にロードするためのそのようなファイルを構築するとき、私はこれが特に役に立つとわかりました。

20
tutuDajuju

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

これにより、元のオプションを保存/復元できます。

set -o allexportを使用すると、正規表現なしでコメントを適切にスキップできるという利点があります。

set +oはそれ自体で現在のすべてのオプションをbashが後で実行できる形式で出力します。 set -oだけでなく、現在のすべてのオプションを人間に優しい形式で出力します。

12
jwfearn

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属性が与えられ、後続のコマンドの環境へのエクスポート用にマークされます。

そしてこれも:

「 - 」ではなく「+」を使用すると、これらのオプションは無効になります。オプションはシェルの起動時にも使用できます。現在のオプションセットは$ - にあります。

12
Nagev

Silas Paulの答えを改善する

サブシェルで変数をエクスポートすると、それらはコマンドに対してローカルになります。

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

10
Jaydeep

もっと簡単:

  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); }

(あなたがあなたのBASH設定を再ロードすることを確認してください!!! source ~/.bash_profileまたは..新しいタブ/ウィンドウを作成し、問題を解決してください)あなたはそれを次のように呼びます:source_envfile .env

9
Javier Buzzi

他の答えに基づいて、これはPREFIX_ONE="a Word"のようなスペースを含む値を含むファイル内の行のサブセットのみをエクスポートする方法です。

set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
5
Victor Roetman

元のスクリプトを使用して変数を設定できますが、次のように呼び出す必要があります(スタンドアロンドットを使用)。

. ./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
5
Extrapolator

私の要求は、

  • export接頭辞のない単純な.envファイル
  • 引用符で囲まれた値をサポートします。TEXT = "alpha bravo charlie"
  • #と空行で始まるコメントのサポート
  • mac/BSDとlinux/GNUの両方に共通

上記の回答からコンパイルされたフルバージョン

  set -o allexport
  eval $(grep -v '^#' .env | sed 's/^/export /')
  set +o allexport
1
Alex

私が見つけた最短の方法:

あなたの.envファイル:

VARIABLE_NAME="A_VALUE"

それからちょうど

. ./.env && echo ${VARIABLE_NAME}

おまけ:これは短いワンライナーなので、package.jsonファイルでとても役に立ちます

  "scripts": {
    "echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
  }
1
Flavien Volken

値の空白

ここにはたくさんの素晴らしい答えがありますが、私はそれらがすべて値の余白のサポートを欠いているのを見つけました:

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

私は以前に提案された解決策に問題があります:

  • @ anubhavaのソリューションは、bashにやさしい設定ファイルの作成を非常に煩わしく非常に高速にします。また、常に設定をエクスポートしたくない場合もあります。
  • 引用符で囲まれた値でうまく機能するスペースや他の文字を含む変数があると@Silas Paulの解決法は破綻しますが、$()は失敗します。

これは私の解決策です、それはまだかなりひどいIMOです - そしてSilasによって対処された「一人の子供だけにエクスポートする」問題を解決しません(ただし、範囲を制限するためにサブシェルでそれを実行することができます)。

source .conf-file
export $(cut -d= -f1 < .conf-file)
1
Guss

変数の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.
0
Nick Grealy

シェルでDockerの--env-filesを再利用しようとしたときに、このスレッドに出くわしました。 それらのフォーマット は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)を処理しません
0
Bob Zoller

まず、以下のような環境のすべてのキーと値のペアを持つ環境ファイルを作成し、私の場合は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
0
anand tripathi

私の。

#!/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

0
Tudor Ilisoi