次のコードを示す指示に従いました。
function testit()
{
local newarray
newarray=($(echo $@))
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
newarray=$(echo $@)
ディレクティブの別の例が気になります。arg1=$(echo ${myarray[*]})
newarray=$@
シンプルで直感的で、もう少し努力するとどんな利点がありますか?
ベストアンサー1
次のいずれも正しく機能しません。
a=($(echo $@))
b=$@
まず拡張$@
そしてワードセパレータとワイルドカードを使用するため、スペースを含む値はそのまま残り、ワイルドカードのように見えるすべての項目が拡張されます。
IFS
2番目は、空白(Bash / ksh)または(Busybox / dash / Zsh;および)"$*"
の最初の文字に関連付けられた配列要素を使用して、配列全体を単一のスカラー値に縮小します。
概念的には、$@
スカラーコンテキストで使用するのも間違っているようです。値のリストに展開するために使用されますが、ここでは値のリストを持つことはできません。配列要素を本当にリンクしたい場合は、s="$*"
明示的に使用することをお勧めします。 (引用符は、一部のシェルでエラーを防ぐのに役立ちます。)
たとえば、
$ touch file1 file2
$ set -- "foo bar" "*"
$ a=($(echo $@))
$ declare -p a
declare -a a=([0]="foo" [1]="bar" [2]="file1" [3]="file2")
そして
$ b=$@
$ declare -p b
declare -- b="foo bar *"
$@
配列のコピーを作成するより良い方法は次のとおりです。
c=("$@")
c=("${myarray[@]}")
両方とも、配列インデックスをゼロから始めるように縮小します(*
前と後のインデックスに注意してください):
$ unset l; l[0]="foo bar"; l[2]="*"
$ c=("${l[@]}")
$ declare -p c
declare -a c=([0]="foo bar" [1]="*")
しかし、これは通常問題ではありません。なぜなら、誤って連続していないインデックスを持つ配列を取得することがないからです。