例えば、以下のようなスクリプトを書いてテストしてみる。cp コマンドの前後でディレクトリの内容がどう変わったかチェックする。
$ cat test.sh rm -fr src/ dst/ mkdir -p src/ mkdir -p src/fuga for (( i=0 ; i<3 ; i++ )) do SRC=`printf "src/%03d.txt" $i` touch $SRC SRC=`printf "src/hoge/%03d" $i` mkdir -p $SRC for (( j=0 ; j<3 ; j++ )) do SRC=`printf "src/hoge/%03d/%03d.txt" $i $j` touch $SRC done done mkdir -p dst/ for (( i=0 ; i<2 ; i++ )) do DST=`printf "dst/%03d.txt" $i` touch $DST DST=`printf "dst/hoge/%03d" $i` mkdir -p $DST for (( j=0 ; j<2 ; j++ )) do DST=`printf "dst/hoge/%03d/%03d.txt" $i $j` touch $DST done done ls -Rli cp -ia src/* dst #mv -f src/* dst ls -Rli exit;
このスクリプトを走らせると以下のような結果が得られる。src 以下のディレクトリとファイルが dst 以下にマージされていることがわかる。このような作業をしたい要望は (僕の場合) 結構頻繁にある。それは、ポータブルメモリで文書ツリーを持ち歩いて、その内容を編集後、再度コピー元にマージする場合だ。
$ sh test.sh .: total 12 36210484 drwxr-xr-x 3 hoge hoge 4096 2010-06-05 09:36 dst 36210478 drwxr-xr-x 4 hoge hoge 4096 2010-06-05 09:36 src 18972715 -rw-r--r-- 1 hoge hoge 566 2010-06-05 09:36 test.sh ./dst: total 4 19054768 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19054769 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 36210485 drwxr-xr-x 4 hoge hoge 4096 2010-06-05 09:36 hoge ./dst/hoge: total 8 36210486 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 000 36210487 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 001 ./dst/hoge/000: total 0 19087531 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19087532 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt ./dst/hoge/001: total 0 19103774 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19103775 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt ./src: total 8 18956416 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 18956417 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 18956418 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt 36210479 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 fuga 36210480 drwxr-xr-x 5 hoge hoge 4096 2010-06-05 09:36 hoge ./src/fuga: total 0 ./src/hoge: total 12 36210481 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 000 36210482 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 001 36210483 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 002 ./src/hoge/000: total 0 19005474 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19005475 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19005476 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt ./src/hoge/001: total 0 19021931 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19021932 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19021933 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt ./src/hoge/002: total 0 19038217 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19038218 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19038219 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt cp: overwrite `dst/000.txt'? y cp: overwrite `dst/001.txt'? y cp: overwrite `dst/hoge/000/001.txt'? y cp: overwrite `dst/hoge/000/000.txt'? y cp: overwrite `dst/hoge/001/001.txt'? y cp: overwrite `dst/hoge/001/000.txt'? y .: total 12 36210484 drwxr-xr-x 4 hoge hoge 4096 2010-06-05 09:36 dst 36210478 drwxr-xr-x 4 hoge hoge 4096 2010-06-05 09:36 src 18972715 -rw-r--r-- 1 hoge hoge 566 2010-06-05 09:36 test.sh ./dst: total 8 19054768 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19054769 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19054770 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt 36210488 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 fuga 36210485 drwxr-xr-x 5 hoge hoge 4096 2010-06-05 09:36 hoge ./dst/fuga: total 0 ./dst/hoge: total 12 36210486 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 000 36210487 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 001 36210489 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 002 ./dst/hoge/000: total 0 19087531 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19087532 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19087533 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt ./dst/hoge/001: total 0 19103774 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19103775 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19103776 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt ./dst/hoge/002: total 0 19136568 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19136566 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19136567 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt ./src: total 8 18956416 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 18956417 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 18956418 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt 36210479 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 fuga 36210480 drwxr-xr-x 5 hoge hoge 4096 2010-06-05 09:36 hoge ./src/fuga: total 0 ./src/hoge: total 12 36210481 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 000 36210482 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 001 36210483 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 09:36 002 ./src/hoge/000: total 0 19005474 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19005475 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19005476 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt ./src/hoge/001: total 0 19021931 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19021932 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19021933 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt ./src/hoge/002: total 0 19038217 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 000.txt 19038218 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 001.txt 19038219 -rw-r--r-- 1 hoge hoge 0 2010-06-05 09:36 002.txt
コピー先に同じパスが無かったファイルやディレクトリについては、コピー元と内容が同じで新しい inode 番号が割り振られた別のファイルが出来ている。コピー先に同じパスが有ったファイルやディレクトリについては、コピー元と内容が同じでコピー先と同じ inode 番号のファイルに内容を上書きされている。
cp 前 inode | cp 後 inode | パス |
---|---|---|
36210484 | 36210484 | ./dst/ |
36210478 | 36210478 | ./src/ |
18972715 | 18972715 | ./test.sh |
19054768 | 19054768 | ./dst/000.txt |
19054769 | 19054769 | ./dst/001.txt |
- | 19054770 | ./dst/002.txt |
- | 36210488 | ./dst/fuga/ |
36210485 | 36210485 | ./dst/hoge/ |
36210486 | 36210486 | ./dst/hoge/000/ |
36210487 | 36210487 | ./dst/hoge/001/ |
- | 36210489 | ./dst/hoge/002/ |
19087531 | 19087531 | ./dst/hoge/000/000.txt |
19087532 | 19087532 | ./dst/hoge/000/001.txt |
- | 19087533 | ./dst/hoge/000/002.txt |
19103774 | 19103774 | ./dst/hoge/001/000.txt |
19103775 | 19103775 | ./dst/hoge/001/001.txt |
- | 19103776 | ./dst/hoge/001/002.txt |
- | 19136568 | ./dst/hoge/002/000.txt |
- | 19136566 | ./dst/hoge/002/001.txt |
- | 19136567 | ./dst/hoge/002/002.txt |
18956416 | 18956416 | ./src/000.txt |
18956417 | 18956417 | ./src/001.txt |
18956418 | 18956418 | ./src/002.txt |
36210479 | 36210479 | ./src/fuga/ |
36210480 | 36210480 | ./src/hoge/ |
36210481 | 36210481 | ./src/hoge/000/ |
36210482 | 36210482 | ./src/hoge/001/ |
36210483 | 36210483 | ./src/hoge/002/ |
19005474 | 19005474 | ./src/hoge/000/000.txt |
19005475 | 19005475 | ./src/hoge/000/001.txt |
19005476 | 19005476 | ./src/hoge/000/002.txt |
19021931 | 19021931 | ./src/hoge/001/000.txt |
19021932 | 19021932 | ./src/hoge/001/001.txt |
19021933 | 19021933 | ./src/hoge/001/002.txt |
19038217 | 19038217 | ./src/hoge/002/000.txt |
19038218 | 19038218 | ./src/hoge/002/001.txt |
19038219 | 19038219 | ./src/hoge/002/002.txt |
ファイルをコピーするのではなく、移動したい場合もあるだろう。cp と同じことを mv でやろうとした場合、以下のように書き換えてみる。"mv: cannot move `src/hoge' to `dst/hoge': Directory not empty" と怒られる。重要な示唆は、mv の場合 inode が変更されない、cp の場合 inode は変更されるという点だ。つまり、移動先に移動元と同じ名前のファイルやディテクトリがあったとき、mv の場合は移動元の inode に紐付けられたファイルやディレクトリのパスを移動先に変更する、cp の場合は移動元の inode に紐付けられたファイルやディレクトリと同じ内容のファイルやディレクトリを移動先に新規作成 (新しい inode が割り振られる) する。ファイルやディレクトリの相対パスが同じになる場合、mv では移動先のファイルをどう扱うかわからないので、エラーを出す。移動先のファイルを削除する場合は、-f を使えばいいが、ファイルの入っているディレクトリに対しては効果なし。そんなわけで、cp を使って inode は違うけど、内容は同じファイルやディレクトリを作って、その後に移動元を削除するほうがわかりやすい(と思う)。
$ sh test.sh .: total 12 36210484 drwxr-xr-x 3 hoge hoge 4096 2010-06-05 10:09 dst 36210478 drwxr-xr-x 4 hoge hoge 4096 2010-06-05 10:09 src 18972715 -rw-r--r-- 1 hoge hoge 566 2010-06-05 10:09 test.sh ./dst: total 4 19054768 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19054769 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 36210485 drwxr-xr-x 4 hoge hoge 4096 2010-06-05 10:09 hoge ./dst/hoge: total 8 36210486 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 000 36210487 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 001 ./dst/hoge/000: total 0 19087531 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19087532 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt ./dst/hoge/001: total 0 19103774 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19103775 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt ./src: total 8 18956416 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 18956417 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 18956418 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 002.txt 36210479 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 fuga 36210480 drwxr-xr-x 5 hoge hoge 4096 2010-06-05 10:09 hoge ./src/fuga: total 0 ./src/hoge: total 12 36210481 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 000 36210482 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 001 36210483 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 002 ./src/hoge/000: total 0 19005474 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19005475 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 19005476 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 002.txt ./src/hoge/001: total 0 19021931 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19021932 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 19021933 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 002.txt ./src/hoge/002: total 0 19038217 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19038218 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 19038219 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 002.txt mv: overwrite `dst/000.txt'? y mv: overwrite `dst/001.txt'? y mv: overwrite `dst/hoge'? y mv: cannot move `src/hoge' to `dst/hoge': Directory not empty .: total 12 36210484 drwxr-xr-x 4 hoge hoge 4096 2010-06-05 10:09 dst 36210478 drwxr-xr-x 3 hoge hoge 4096 2010-06-05 10:09 src 18972715 -rw-r--r-- 1 hoge hoge 566 2010-06-05 10:09 test.sh ./dst: total 8 18956416 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 18956417 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 18956418 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 002.txt 36210479 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 fuga 36210485 drwxr-xr-x 4 hoge hoge 4096 2010-06-05 10:09 hoge ./dst/fuga: total 0 ./dst/hoge: total 8 36210486 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 000 36210487 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 001 ./dst/hoge/000: total 0 19087531 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19087532 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt ./dst/hoge/001: total 0 19103774 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19103775 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt ./src: total 4 36210480 drwxr-xr-x 5 hoge hoge 4096 2010-06-05 10:09 hoge ./src/hoge: total 12 36210481 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 000 36210482 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 001 36210483 drwxr-xr-x 2 hoge hoge 4096 2010-06-05 10:09 002 ./src/hoge/000: total 0 19005474 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19005475 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 19005476 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 002.txt ./src/hoge/001: total 0 19021931 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19021932 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 19021933 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 002.txt ./src/hoge/002: total 0 19038217 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 000.txt 19038218 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 001.txt 19038219 -rw-r--r-- 1 hoge hoge 0 2010-06-05 10:09 002.txt
移動先に同じパスが無かったファイルやディレクトリについては、移動元と内容が同じで同じ inode 番号が割り振られた同じファイルが移動先に移動された。移動先に同じパスが有ったファイルやディレクトリについても、移動元と内容が同じで移動元と同じ inode 番号のファイルが移動されてきている。
cp 前 inode | cp 後 inode | パス |
---|---|---|
36210484 | 36210484 | ./dst/ |
36210478 | 36210478 | ./src/ |
18972715 | 18972715 | ./test.sh |
19054768 | 18956416 | ./dst/000.txt |
19054769 | 18956417 | ./dst/001.txt |
- | 18956418 | ./dst/002.txt |
- | 36210479 | ./dst/fuga/ |
36210485 | 36210485 | ./dst/hoge/ |
36210486 | 36210486 | ./dst/hoge/000/ |
36210487 | 36210487 | ./dst/hoge/001/ |
19087531 | 19087531 | ./dst/hoge/000/000.txt |
19087532 | 19087532 | ./dst/hoge/000/001.txt |
19103774 | 19103774 | ./dst/hoge/001/000.txt |
19103775 | 19103775 | ./dst/hoge/001/001.txt |
18956416 | - | ./src/000.txt |
18956417 | - | ./src/001.txt |
18956418 | - | ./src/002.txt |
36210479 | - | ./src/fuga/ |
36210480 | 36210480 | ./src/hoge/ |
36210481 | 36210481 | ./src/hoge/000/ |
36210482 | 36210482 | ./src/hoge/001/ |
36210483 | 36210483 | ./src/hoge/002/ |
19005474 | 19005474 | ./src/hoge/000/000.txt |
19005475 | 19005475 | ./src/hoge/000/001.txt |
19005476 | 19005476 | ./src/hoge/000/002.txt |
19021931 | 19021931 | ./src/hoge/001/000.txt |
19021932 | 19021932 | ./src/hoge/001/001.txt |
19021933 | 19021933 | ./src/hoge/001/002.txt |
19038217 | 19038217 | ./src/hoge/002/000.txt |
19038218 | 19038218 | ./src/hoge/002/001.txt |
19038219 | 19038219 | ./src/hoge/002/002.txt |