コマンドの環境変数を動的に設定するには?

コマンドの環境変数を動的に設定するには?

私は純粋なbashで一種のミニマリストテンプレートエンジンを使用したいと思いますenvsubst

user@host:~$ env -i FOO=foo BAR="bar baz" envsubst '$FOO,$BAR' \
  <<< 'Hello "$FOO" and "$BAR"!'
Hello "foo" and "bar baz"!

上記はうまくいきますが、静的変数のみを含みます。

ここで、連想配列のように環境変数が動的に提供されるとしましょう。

declare -A MY_ENV=([FOO]=foo [BAR]="bar baz")

配列キーと値のペアの解析は、空白のない環境値に対してのみ機能します(バグ):

env -i \
  $(for k in "${!MY_ENV[@]}"; do printf "%s=%s " $k "${MY_ENV[$k]}"; done) \ 
  envsubst #...

環境値を引用符で囲もうとすると(noteで '%s' 置き換え)、エラーが発生します。%s

env -i \
  $(for k in "${!MY_ENV[@]}"; do printf "%s='%s' " $k "${MY_ENV[$k]}"; done) \ 
  envsubst #...

出力set -x原因:set -x示された引数がenv巨大な文字列になりました

+ env -i 'FOO='\''foo'\''' 'BAR='\''bar' 'baz'\''' envsubst #...
env: ‘baz'’: No such file or directory

私は脱出クラスを間違いなく逃しました(再び…)。最後の例が正しく動作するように、どのように書き換えることができますか?

ベストアンサー1

これは[バッシュFAQ/050]"key=value"- 各ペアが正しく参照されるように配列を使用する必要があります。

vars=()
for k in "${!MY_ENV[@]}"; do
    vars+=( "$k=${MY_ENV[$k]}" )
done
env -i "${vars[@]}" envsubst '$FOO,$BAR' <<< 'Hello "$FOO" and "$BAR"!'
Hello "foo" and "bar baz"!

追加の引用符文字は挿入しません。


拡張されたため、変数名をハードコードする必要はありません。

keys=( "${!MY_ENV[@]}" )
printf -v varnames ',%s' "${keys[@]/#/'$'}"

env -i "${vars[@]}" envsubst "${varnames#,}" <<< 'Hello "$FOO" and "$BAR"!'

# or without the `varnames` temp var
env -i "${vars[@]}" envsubst "$(IFS=,; echo "${keys[*]/#/'$'}")" <<< 'Hello "$FOO" and "$BAR"!'

おすすめ記事