シェルでワイルドカードをつかって cp するときの落とし穴
問題
例えば $HOME/tmp/conf に以下のファイルがあったとする。
$ ls $HOME/tmp/conf other.dat test1.conf test2.conf
このうち、 test1.conf と test2.conf をカレントディレクトリにコピーしたい場合に、以下のコマンドを打つことがある。
cp $HOME/conf/*.conf .
でも、このコマンドはちょっと危険。 うっかり、最後のドットをつけ忘れて…
cp $HOME/conf/*.conf
としちゃうと惨事がおこる。 なぜでしょう?
答え
$ cat $HOME/tmp/conf/test2.conf This is "test1.conf"
test2.conf が test1.conf の内容で上書きされてしまってる。 ちなみに、ディレクトリに .conf ファイルが3つ以上存在する場合は、こうはならない。
$ touch $HOME/tmp/conf/test3.conf $ cp $HOME/tmp/conf/*.conf cp: target `/home/machu/tmp/conf/test3.conf' is not a directory
まぁ、考えれば当たり前で、
$ cp $HOME/tmp/conf/*.conf
はシェルによって、
$ cp $HOME/tmp/conf/test1.conf $HOME/tmp/conf/test2.conf
と展開されて cp コマンドへ渡される。 なので、 test1.conf の内容が test2.conf にコピーされるという訳。
対策
打ち間違いを防ぐのは無理なので、 -i オプションを alias で付けておけばいい。
$ alias cp='cp -i' mv='mv -i' rm='rm -i'
まぁ、この問題に限らず基本的なことだけど、なぜか root だけ設定されていなかったりすることもあるんだよね。