argument list toooooooooooooooooooooooooooooooooooo long
仕事で超大量のファイルをコピーする事が多いのだが、何も考えずに作業すると
[root@sv file]# cp -R * /path/to/
bash: /bin/cp: Argument list too long
となるのがありがち。
同様に、rmとかでもなる。
rm 20080101*
rm 20080102*
…
などと順番にやるのはいかにもダサい。
理屈を書くと、これはシェルで*が展開されて
cp -R dir1 dir2 dir3 ... dir9999 /path/to
というコマンドを処理しようとしたが、引数が長すぎるよアホ、と言われている。
引数の限度は案外短いのだ。
- -
こういうときにはxargsを使う。
ls * |xargs rm
とかすると、
rm dir dir dir dir dir dir dir dir dir ... dir dir dir
と「怒られない範囲で、できるだけ長くした状態で」実行してくれるという便利なコマンドである。
xargsは標準入力からファイル名(Path)を受け取り、引数に数珠つなぎする。
勿論ファイルリストや、findから渡してもちゃんと動く。
- -
ただ、上のrmではわかりやすいが、コレをcpでやろうとすると
ls * |xargs cp /path/to
などとやったら
cp /path/to dir dir dir ... ndir
となってしまって、うまくうごかない、というかndir に全部つっこまれてしまい、悲惨な結果となる。
勿論xargsだってバカじゃないので、
ls * | xargs -i cp {} /path/to
と、-iオプション付きで実行すれば、差し込む場所を指定できる。
- -
ただ、これしばしば忘れるんだよなー、ということで
ls * |xargs cp --target-directory=/path/to
というバージョンを覚えておく事をお勧めしたい。*1
そんだけの話。
*1:これで、前方の引数でコピー先が指定できる