UNIXのワイルドカードがワイルド

Back To The Future: Unix Wildcards Gone Wild

面白かったので.また気をつけようと思ったので.

ワイルドな実例

例えば,以下のようなファイルとディレクトリがあるとする.

$ ls -al
total 0
drwxr-xr-x  9 taichi  staff  306  8 18 22:31 .
drwxr-xr-x  6 taichi  staff  204  8 18 22:27 ..
drwxr-xr-x  2 taichi  staff   68  8 18 22:26 DIR1
drwxr-xr-x  2 taichi  staff   68  8 18 22:26 DIR2
drwxr-xr-x  2 taichi  staff   68  8 18 22:26 DIR3
-rw-r--r--  1 taichi  staff    0  8 18 22:26 file1
-rw-r--r--  1 taichi  staff    0  8 18 22:26 file2
-rw-r--r--  1 taichi  staff    0  8 18 22:26 file3
-rw-r--r--  1 taichi  staff    0  8 18 22:30 -rf

ここで,以下のようにワイルドカードでファイル指定しファイル削除を実行する.

$ rm *

オプションを指定していないので,ディレクトリは消えないはずが,ディレクトリまで消えてしまう.

$ ls -al
total 0
-rw-r--r--  1 taichi  staff    0  8 18 22:30 -rf
drwxr-xr-x  3 taichi  staff  102  8 18 22:32 .
drwxr-xr-x  4 taichi  staff  136  8 18 22:32 ..

これは-rfというファイルが原因.ワイルドカードが展開されると,rmはそれをオプションとして認識してしまい,ディレクトリも消してしまう.すごい野性的.

どう避けるのか

そもそも-で始まるファイル名が存在することがおかしいし,センスを疑うが,ありえないとは言い切れない.

まず,--を使う方法.--を使うとオプションの終了位置を明示的に指定でき,それ以後-で始まるファイルが現れてもそれをファイルとして扱うようになる.

$ rm -- *

でも,すべてのコマンドをこれで実行するわけにはいかないし,いつか忘れる.また全てのコマンドが--をサポートしているわけではない.

良さげなのは,./を使う方法.というか,ワイルドカードで始まるファイル指定をしない.

$ rm ./*

まとめ

軽い話題のつもりが良い教訓になった.

ワイルドカードを使ったファイルglobはシェルスクリプトではよく使う(例えばforでループするときなど).ワイルドカードで始まるファイル指定をしないように気をつけること.

さらに学ぶには

以下の素敵な記事に目を通すのが良さそう.

Filenames and Pathnames in Shell (bash, dash, ash, ksh, and so on): How to do it Correctly