Help us understand the problem. What is going on with this article?

シェルにおけるワイルドカードの挙動についての整理

More than 1 year has passed since last update.

はじめに

シェルの変数と配列で”*”(アスタリスク)を格納する際の挙動が異なるようなので整理してみました。
環境は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.ただし、配列に関しては配列格納時にも*を展開しようとするので注意すること。

以上

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away