#はじめに
シェルの変数と配列で”*
”(アスタリスク)を格納する際の挙動が異なるようなので整理してみました。
環境はCentOS7.5を使用しています。
#基本
まずアスタリスクをそのままechoした場合、
*
は特殊文字として解釈され、直下のファイル名が展開されます。
※挙動が判りやすいようにset -xオプション付きで実行。
[root@hostname]# echo *
+ echo test.txt test1.txt
test.txt test1.txt
次に"
(ダブルコーテーション)や\
(バックスラッシュ)で特殊文字として解釈されないようにした場合。
[root@hostname]# echo "*"
+ echo '*'
*
[root@hostname]# echo \*
+ echo '*'
*
どちらもecho '*'
と解釈されます。
#変数に格納する場合
変数i
に*
を格納する場合ですが、"
(ダブルコーテーション)で囲った場合は、先ほどと同様に'*'
と解釈されますが、変数名に(バックスラッシュ)を付けると変数自体を解釈しなくなります。
[root@hostname]# i=*
+ i='*'
[root@hostname]# echo $i
+ echo test.txt test1.txt
test.txt test1.txt
[root@hostname]# echo "$i"
+ echo '*'
*
[root@hostname]# echo \$i
+ echo '$i'
$i
ここまでは想定通りの動き。
#配列に格納する場合
配列に格納した場合は変数に格納した場合と異なり、配列に格納する時点で*
が展開されてしまいます。
その為、"
(ダブルコーテーション)で囲っても展開後のファイル名しか表示されません。
[root@hostname]# i=(*) #内部的に標準出力されてから配列に格納されている?
+ i=(*)
[root@hostname]# echo ${i[@]}
+ echo test.txt test1.txt
test.txt test1.txt
[root@hostname]# echo "${i[@]}" #ダブルコーテーションで囲っても展開後の名前が表示される
+ echo test.txt test1.txt
test.txt test1.txt
[root@hostname]# echo \${i[@]}
+ echo '${i[@]}'
${i[@]}
これは変数とは異なり、配列格納時に*
が展開されてしまう為に発生するようです。
→内部的に標準出力で展開されたものを配列に格納している?
対策として、配列格納時に”*”
とすると下記のようにきちんと*
のまま格納されます。
[root@hostname]# i=("*")
+ i=("*")
[root@hostname]# echo $i
+ echo test.txt test1.txt
test.txt test1.txt
[root@hostname]# echo "$i"
+ echo '*'
*
応用編 アスタリスクに文字列を足した場合
*
に文字列を足した場合は、ディレクトリ直下に該当するファイルがあるか無いかで結果が変わってくるので注意が必要です。
[root@hostname]# i=*
+ i='*'
[root@hostname]# echo tes$i #該当するファイルがあると展開される
+ echo test.txt test1.txt
test.txt test1.txt
[root@hostname]# echo e$i #該当するファイルが無いとそのまま表示される
+ echo 'e*'
e*
[root@hostname]# i=(e*) #配列を格納する場合も該当するファイルが無いとそのまま格納される
+ i=(e*)
[root@hostname]# echo ${i[@]}
+ echo 'e*'
e*
#まとめ
1.*
は標準出力されるタイミングでカレントディレクトリに該当するファイルがあると勝手に展開されてしまう。
2.展開されないようにするには”(ダブルコーテーション)で囲うのが確実。
3.ただし、配列に関しては配列格納時にも*
を展開しようとするので注意すること。
以上