Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?
@daisuke0115

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

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.ただし、配列に関しては配列格納時にも*を展開しようとするので注意すること。

以上

5
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  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
daisuke0115
インフラエンジニアです。 最近は設計~構築をメインにお仕事しています。Qiitaには主にLinux周りで勉強したことを備忘録がわりに残しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
5
Help us understand the problem. What is going on with this article?