bash配列が奇妙に動作する

bash配列が奇妙に動作する

/ tmpの下に2つのフォルダがあります。

ターミナルから出発:

ls -d /tmp/firefox-*

/tmp/firefox-sy2vakcj.default-esr-charlie-cache
/tmp/firefox-sy2vakcj.default-esr-charlie-profile

または

compgen -G /tmp/firefox-*

/tmp/firefox-sy2vakcj.default-esr-charlie-cache
/tmp/firefox-sy2vakcj.default-esr-charlie-profile

出力を配列に保存することもできます。

arr=( $(ls -d /tmp/firefox-*) )
echo $arr
tmp/firefox-sy2vakcj.default-esr-charlie-cache  /tmp/firefox-sy2vakcj.default-esr-charlie-profile
 
echo $arr[1] 
tmp/firefox-sy2vakcj.default-esr-charlie-cache

echo $arr[2]
/tmp/firefox-sy2vakcj.default-esr-charlie-profile

今まではそんなに良くなった。

しかし、スクリプトで同じことをしようとすると、次のようになります。

    ...
    ... 
    arr=( "$(ls -d /tmp/firefox-*)" ) ||( echo "directory doesn't exist" && exit 1)
    #arr=( "$(compgen -G /tmp/firefox-*)" ) ||( echo "directory doesn't exist" && exit 1)
    echo "this is a test for arr[1]: $arr[1]"
    echo "this is a test for arr[2]: $arr[2]"
    ...
 

私は出力を取得します:

スクリプトから:

ls -d出力は次のとおりです。

+ arr=("$(ls -d /tmp/firefox-*)")
++ ls -d '/tmp/firefox-*'
ls: cannot access '/tmp/firefox-*': No such file or directory
+ echo 'directory doesn'\''t exist'
directory doesn't exist

の場合、compgen -G出力は次のようになります。

this is a test for arr[1]: /tmp/firefox-sy2vakcj.default-esr-charlie-cache
/tmp/firefox-sy2vakcj.default-esr-charlie-profile[1]
this is a test for arr[2]: /tmp/firefox-sy2vakcj.default-esr-charlie-cache
/tmp/firefox-sy2vakcj.default-esr-charlie-profile[2]

私の質問:

1.コマンドのサブシェルでglobが拡張されないのはなぜですか ls -d

2.の場合、compgen -G値は配列にどのように格納されますか?出力は、配列内の各項目がディレクトリ項目を格納し、2番目のディレクトリ項目を独自のインデックス配列として保存するように見えますか?

三。これら2つのコマンドのターミナル出力はスクリプトとは異なりますか、それとも何か抜けましたか?

答え1

  1. ls -dコマンドのサブシェルでglobが拡張されないのはなぜですか?

閉じたワイルドカードを使用した可能性がありますset -f。展示する:

$ touch firefox-1 firefox-2
$ arr=( firefox-* ); declare -p arr
declare -a arr=([0]="firefox-1" [1]="firefox-2")
$ set -f
$ arr=( firefox-* ); declare -p arr
declare -a arr=([0]="firefox-*")
  1. compgen -Gを使用すると、値は配列にどのように格納されますか?出力は、配列内の各項目がディレクトリ項目を格納し、2番目のディレクトリ項目を独自のインデックス配列として保存するように見えますか?

これにより、arr=( "$(compgen -G /tmp/firefox-*)" )二重引用符で compgen 出力が次のように保存されます。単一要素配列から。この場合は、以下をお読みください。出力ライン数mapfileプロセスの置き換えに使用するために配列に入れます。

$ mapfile -t arr < <(compgen -G ./firefox-*)
$ declare -p arr
declare -a arr=([0]="./firefox-1" [1]="./firefox-2")
  1. これら2つのコマンドのターミナル出力はスクリプトとは異なりますか、それとも何か抜けましたか?

対話型シェルがzshのようです。さらに、中括弧を必要とする配列要素のパラメータ拡張構文がありません(3.5.3 シェルパラメータの拡張)、bash配列は0からインデックス付けされます。

echo "${arr[0]}"

関連情報