Next: , Previous: Random sources, Up: Common options   [Contents][Index]


2.8 出力先ディレクトリ

通常、cp, install, ln, mv といったコマンドは、最後のオペランドがディレクトリやディレクトリへのシンボリックリンクの場合、 それを特別扱いする。たとえば、‘cp source dest’ は、dest がディレクトリならば、‘cp source dest/source’ と同じことである。 時には、そうした動作が、ユーザが求めている動作とは違うこともある。 そこで、こうしたコマンドは、よりきめ細かな制御ができるように、 以下のオプションをサポートしている。

-T
--no-target-directory

最後のオペランドが、ディレクトリやディレクトリへのシンボリックリンクであっても、 それを特別扱いしない。このオプションは、共有領域で作業する複数のプログラムが、 競合状態にならないようにしてくれる。 たとえば、‘mv /tmp/source /tmp/dest’ というコマンドが正常終了しても、 /tmp/source/tmp/dest にリネームされたという保証はない。 もし、何かほかのプロセスが /tmp/dest をディレクトリとして作成していたら、 /tmp/dest/source という名前のファイルになってしまうかもしれないのだ。 それに対して、mv -T /tmp/source /tmp/dest が正常終了した場合は、 /tmp/source は間違いなく /tmp/dest にリネームされている。

反対に、最後のオペランドをディレクトリとして扱わせたい、 それができない場合は、エラーメッセージを出したい、ということもある。 そういうときは、--target-directory (-t) オプションを使用すればよい。 (訳注: ターゲット・ディレクトリをコマンドラインの最後に置く代わりに、 --target-directory オプションの引数にするということである。)

-t directory
--target-directory=directory

directory を、出力されるファイルすべてのディレクトリ部分として使用する。

ほとんどのプログラムで、コマンドラインの扱いは次のようになっている。 オプションや、一定数の (0 個のこともある) 位置の固定した引数の処理が終われば、 引数リストにはもう何も残っていないか、残っているとすれば、 それはすべて同じように処理されることになる項目 (通常はファイル) のリストのはずある。 xargs プログラムは、こうした約束ごとに沿ってうまく動くように作られている。

mv ファミリーのコマンドが変わっているのは、引数の数が不定であり、 しかも最後の引数を特別扱いするという点である (すなわちターゲット・ディレクトリとして扱う)。 そのため、ある種の作業の実行は、一筋縄ではいかない。 たとえば、「すべてのファイルをここから ../d/ に移動する」がそうだ。 何故なら、mv * ../d/ では、引数を入れておくための領域を使い切ってしまうかもしれないし、 そうかと言って、ls | xargs ... には、実行対象コマンド (訳注: ここでは、mv) を起動するたびに最後の引数を特別に指定するためのすっきりした方法がないからである。 (あるシェル・コマンドを駆使すれば、やることができるが、それでは、人間の労力と脳力を過当に要求することになる。)

--target-directory (-t) オプションを使用すると、 cp, mv, ln, install といったプログラムを xargs と一緒に使うとき、たいへん都合がよい。 たとえば、カレントディレクトリから、同じディレクトリ階層にある d ディレクトリへファイルを移動するには、こんなふうにすればよい。

ls | xargs mv -t ../d --

しかし、これでは、ファイル名の先頭に ‘.’ の付くファイルが移動しない。 GNU find プログラムを使用しているなら、 次のコマンドでそうしたファイルも移動させることができる。

find . -mindepth 1 -maxdepth 1 \
  | xargs mv -t ../d

とは言え、上記のどちらの方法も、カレントディレクトリにファイルが一つもない場合や、 空白などの特殊文字を名前に含むファイルがある場合には、うまく行かない。 次の例はそうした制限を一掃しているが、GNU find と GNU xargs の両方が必要である。

find . -mindepth 1 -maxdepth 1 -print0 \
  | xargs --null --no-run-if-empty \
      mv -t ../d

--target-directory (-t) オプションと --no-target-directory (-T) オプションを一緒に使うことはできない。