非対話型シェル用の環境変数として配列を保存する

非対話型シェル用の環境変数として配列を保存する

問題を解決できる質問がいくつかありますが、次のことを試してみたいと思います。

この質問では、基本的に配列を環境変数として使用し、文字列を個々の配列要素に格納しようとしています。

a=('Apple Tomato' 'Banana Carrot') bash -c \
'b=($(echo "${a}")); echo -e "${b[0]}\n"; echo "${b[1]}";'

出力

(Apple

Tomato

希望の出力:

リンゴトマト

バナナニンジン

観察する:

また、元の配列の一重引用符で囲まれた配列要素に二重引用符がある場合、引用符は保持されます。たとえば、a=('Apple "Tomato"' 'Banana "Carrot"')

ベストアンサー1

環境変数は、単純な文字列キーと値のペアです。配列は環境変数にはできません。

ただし、配列の値をスクリプトaに渡すことはできます。bash -c

bash -c 'printf "%s\n" "$@"' bash "${a[@]}"

bまたはスクリプトから配列を呼び出す場合:

bash -c 'b=( "$@" ); printf "%s\n" "${b[@]}"' bash "${a[@]}"

どちらの場合も、配列の要素はaスクリプトのコマンドラインを介して渡されます。これはスクリプトの"$@"(in"$1"など"$2")に表示されることを意味しますbash -c

あなたの質問で何が起こっているのか

a=('Apple Tomato' 'Banana Carrot') bash -c '...'

変数をa文字列に設定します(Apple Tomato Banana Carrot)。スクリプトaの環境変数の値は次のとおりですbash -c

$ a=('Apple Tomato' 'Banana Carrot') bash -c 'printf "%s\n" "$a"'
(Apple Tomato Banana Carrot)

もしあなたなら本物データを環境変数に渡す必要がある場合は、区切り文字を決定してから、配列を単一の文字列に平面化します。

例えば:

IFS=:
b="${a[*]}" bash -c 'set -f; IFS=:; a=( $b ); printf "%s\n" "${a[@]}"'

その後、文字列が設定され、その文字列を使用してスクリプト値でApple Tomato:Banana Carrot環境変数が生成されます。bbash -c

その後、スクリプトは再分割され、分割されb:単語を独自の配列aに割り当てます。

set -f引用符なしで分割された単語にファイル名ワイルドカードを呼び出さない場合は、スクリプトで使用する必要があります$b

IFSその後、親シェルから元の値を復元しようとしますbash -c(簡単にするには、古い値を変数に保存できます)。bash -cを使用して、スクリプトでファイル名のグロービングを再度有効にすることもできますset +f

ifs=$IFS; IFS=:
b="${a[*]}" bash -c 'set -f; ifs=$IFS; IFS=:; a=( $b ); IFS=$ifs; unset ifs; set +f; printf "%s\n" "${a[@]}"'
IFS=$ifs; unset ifs

おすすめ記事