配列を環境変数として使用できません

配列を環境変数として使用できません

なぜスクリプトでenv配列変数が利用できないのかわかりません。
私の中で~/.bashrcなければ~/.profile

export HELLO="ee"
export HELLOO=(aaa bbbb ccc)

シェルから:

> echo $HELLO
ee
> echo $HELLOO
aaa
> echo ${HELLOO[@]}
aaa bbbb ccc

スクリプトから:

#!/usr/bin/env bash
echo $HELLO
echo $HELLOO
echo ${HELLOO[@]}
---
# Return 
ee

なぜ?

答え1

bash環境変数はキーと値の文字列のペアのみであるため、配列は環境変数にすることはできません。

デフォルトでは、パス配列である変数を使用してシェルが実行する操作を実行できます$PATH。配列を配列値にない特定の文字で区切られた文字列に変換します。

$ arr=( aa bb cc "some string" )
$ arr=$( printf '%s:' "${arr[@]}" )
$ printf '%s\n' "$arr"
aa:bb:cc:some string:

またはもう少しきれいな、

arr=( aa bb cc "some string" )
arr=$( IFS=:; printf '%s' "${arr[*]}" )
export arr

の拡張は、の最初の文字で区切られた配列要素になり、${arr[*]}ここではに設定されます。これにより、文字列の要素は次のようになります。arrIFS:分離(いいえ分離)by :、これは末尾の空の要素(存在する場合)を区別できないことを意味します。


環境変数を使用してスクリプトに値を渡すもう1つの方法は、(明らかに?)コマンドライン引数を使用することです。

arr=( aa bb cc )

./some_script "${arr[@]}"

その後、スクリプトは位置引数$1などを使用するか、次を使用して渡された引数に1つずつアクセスします。$2$3$@

printf 'First I got "%s"\n' "$1"
printf 'Then  I got "%s"\n' "$2"
printf 'Lastly there was "%s"\n' "$3"

for opt in "$@"; do
    printf 'I have "%s"\n' "$opt"
done

答え2

配列は bash によって異なります。環境変数は名前と値のペアです。

読む環境変数の指定、そのいくつかは次のとおりです。

環境変数の値は文字列です。 C言語プログラムの場合、プロセスの開始時に環境と呼ばれる文字列配列を提供する必要があります。外部変数は配列を指します。環境、として定義される:

extern char **environ;

この文字列は次の形式です。名前=値;名前"="文字を含めることはできません。

答え3

現在のアレイ輸出状況2021年10月

配列のエクスポートはまだ完全に実装されていません。コマンドを使用してソースコードを複製できますgit clone https://git.savannah.gnu.org/git/bash.git ~/bash-src。 Bashソースコード~/bash-src/config-top.hのコメント付き154行を見てください。

/* Define to 1 if you want to be able to export indexed arrays to processes
   using the foo=([0]=one [1]=two) and so on */
/* #define ARRAY_EXPORT 1 */

また、429行のコードセクションでは、次のように~/bash-src/variables.c言います。

#if defined (ARRAY_VARS)
#  if ARRAY_EXPORT
      /* Array variables may not yet be exported. */
      if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
    {
      string_length = 1;
      temp_string = extract_array_assignment_list (string, &string_length);
      temp_var = assign_array_from_string (name, temp_string, 0);
      FREE (temp_string);
      VSETATTR (temp_var, (att_exported | att_imported));
      array_needs_making = 1;
    }
      else
#  endif /* ARRAY_EXPORT */
#endif

したがって、既定では、この問題にはより多くの作業が必要です。

解決策

同時に、BASH_ENV環境スクリプトを指す変数をエクスポートできます。私はそれを置き、/etc/bash.environmentそこにシステム全体の配列を宣言しました。~/.bashrcこれを含めることができ、export BASH_ENV="~/.bash.environment"現在のユーザーが実行しているすべてのbashプロセスはこのファイルを受け取ります。

@them が後述するように、~/.bashrc対話型シェルと非対話型シェルの両方に適用するには、対応する構成が必要です。

[ -r "~/.bash.environment" ] \
&& source "~/.bash.environment" \
&& export BASH_ENV="~/.bash.environment"

最後に、環境は次のようになります。

# ~/.bash.environment
export HELLO="ee"
export HELLOO=(aaa bbbb ccc)

非永続的な回避策

配列配信のための迅速で汚れた非永続的な解決策は次のとおりです。プロセス置換によって生成された名前付きパイプを環境変数<()に割り当てます。BASH_ENV

BASH_ENV=<(declare -p HELLO HELLOO) your_script.sh

最高の願い

関連情報