LoginSignup
23
14

More than 5 years have passed since last update.

cpコマンドでディレクトリを再帰的にコピーする時に気持ちが伝わらなすぎるのでcpコマンドでの失敗を記録してみた

Posted at

BSDのcpコマンドでディレクトリごと同じ名前で再帰的にコピーしたい

  • 環境 : macOS Mojave バージョン10.14.2
例えばこんなディレクトリ構成
$ find .
.
./chovin
./pon
./pon/su
./pon/su/ke
./pon/su/ke/tarou.txt
./pon/su/symbolicklink

# シンボリックリンクも入っています
$ ls -lR
total 0
drwxr-xr-x  2 mana  staff   64 12 27 16:06 chovin
drwxr-xr-x  4 mana  staff  128 12 27 16:19 pon

./chovin:

./pon:
total 0
drwxr-xr-x  4 mana  staff  128 12 27 16:20 su

./pon/su:
total 0
drwxr-xr-x  3 mana  staff  96 12 27 14:47 ke
lrwxr-xr-x  1 mana  staff  32 12 27 16:20 symbolicklink -> /Users/mana/Downloads/pon/su/ke/

./pon/su/ke:
total 0
-rw-r--r--  1 mana  staff  0 12 27 14:47 tarou.txt

正解

$ cp -R pon chovin
$ find .
.
./chovin
./chovin/pon
./chovin/pon/su
./chovin/pon/su/ke
./chovin/pon/su/ke/tarou.txt
./chovin/pon/su/symbolicklink
./pon
./pon/su
./pon/su/ke
./pon/su/ke/tarou.txt
./pon/su/symbolicklink

cp: pon is a directory (not copied).

オプションなしでディレクトリは指定してはだめです。

$ cp pon chovin/
cp: pon is a directory (not copied).

cp: ./pon and pon are identical (not copied).

同じ場所に同じ名前はだめです。

$ cp -r pon .
cp: ./pon and pon are identical (not copied).

オプションの -r を使うのは超オススメできないので -R を使うとシンボリックリンクもコピーできる

# -rでも使える
$ cp -r pon chovin

# コピーできたように見えるけどシンボリックリンクがおかしい気がする
$ find .
.
./chovin
./chovin/pon
./chovin/pon/su
./chovin/pon/su/ke
./chovin/pon/su/ke/tarou.txt
./chovin/pon/su/symbolicklink
./chovin/pon/su/symbolicklink/tarou.txt
./pon
./pon/su
./pon/su/ke
./pon/su/ke/tarou.txt
./pon/su/symbolicklink

# シンボリックリンクは残念なことに実態をコピーしてきてシンボリックリンクじゃなくなる
$ ls -lR

# <省略>

./chovin/pon/su:
total 0
drwxr-xr-x  3 mana  staff  96 12 27 16:27 ke
drwxr-xr-x  3 mana  staff  96 12 27 16:27 symbolicklink

./chovin/pon/su/ke:
total 0
-rw-r--r--  1 mana  staff  0 12 27 16:27 tarou.txt

./chovin/pon/su/symbolicklink:
total 0
-rw-r--r--  1 mana  staff  0 12 27 16:27 tarou.txt

# <省略>

./pon/su:
total 0
drwxr-xr-x  3 mana  staff  96 12 27 14:47 ke
lrwxr-xr-x  1 mana  staff  32 12 27 16:20 symbolicklink -> /Users/mana/Downloads/pon/su/ke/

# <省略>

manに「cp -rは使うな」と書いてあった話 - 西尾泰和のはてなダイアリー
Mac で cp を使うときの注意 - tkuchikiの日記

COMPATIBILITY(互換性)
 Historic versions of the cp utility had a -r option.  This implementation(実装) supports that option;
 however, its use is strongly discouraged(勧められない), as it does not correctly copy special files, symbolic
 links, or fifo`s.
DESCRIPTION
-R    If source_file designates(指定する) a directory, cp copies the directory and the entire subtree con-
      nected at that point.  If the source_file ends in a /, the contents of the directory are
      copied rather than the directory itself.  This option also causes symbolic links to be
      copied, rather than indirected(間接的な) through, and for cp to create special files rather than
      copying them as normal files.  Created directories have the same mode as the corresponding
      source directory, unmodified by the process` umask.

      In -R mode, cp will continue copying even if errors are detected.

      Note that cp copies hard-linked files as separate files.  If you need to preserve hard
      links, consider using tar(1), cpio(1), or pax(1) instead.

コピーされた階層が思ったのと違う! / の有無で構成は変わります

「両方につける」「コピー元だけにつける」とサブディレクトリがサブディレクトリとしてコピーされる

$ cp -R pon/ chovin/
$ find .
.
./chovin
./chovin/su
./chovin/su/ke
./chovin/su/ke/tarou.txt
./chovin/su/symbolicklink
./pon
./pon/su
./pon/su/ke
./pon/su/ke/tarou.txt
./pon/su/symbolicklink
$ rm -rf chovin/*

$ cp -R pon/ chovin
$ find .
.
./chovin
./chovin/su
./chovin/su/ke
./chovin/su/ke/tarou.txt
./chovin/su/symbolicklink
./pon
./pon/su
./pon/su/ke
./pon/su/ke/tarou.txt
./pon/su/symbolicklink

「両方につけない」「コピー先だけにつける」とディレクトリがサブディレクトリとしてコピーされる

$ cp -R pon chovin
$ find .
.
./chovin
./chovin/pon
./chovin/pon/su
./chovin/pon/su/ke
./chovin/pon/su/ke/tarou.txt
./chovin/pon/su/symbolicklink
./pon
./pon/su
./pon/su/ke
./pon/su/ke/tarou.txt
./pon/su/symbolicklink
$ rm -rf chovin/*

$ cp -R pon chovin/
$ find .
.
./chovin
./chovin/pon
./chovin/pon/su
./chovin/pon/su/ke
./chovin/pon/su/ke/tarou.txt
./chovin/pon/su/symbolicklink
./pon
./pon/su
./pon/su/ke
./pon/su/ke/tarou.txt
./pon/su/symbolicklink

cp: cannot overwrite directory chovin/pon/su/symbolicklink with non-directory pon/su/symbolicklink

シンボリックリンクは上書きできません、とはいえ他のものはコピーできています。

$ cp -R pon chovin
cp: cannot overwrite directory chovin/pon/su/symbolicklink with non-directory pon/su/symbolicklink

# コピー元のファイルを追加します。
$ echo -n > pon/tyan.txt
$ find pon
pon
pon/tyan.txt
pon/su
pon/su/ke
pon/su/ke/tarou.txt
pon/su/symbolicklink

# 警告は出てもちゃんとコピーできています。
$ cp -R pon chovin
cp: cannot overwrite directory chovin/pon/su/symbolicklink with non-directory pon/su/symbolicklink
$ find chovin
chovin
chovin/pon
chovin/pon/tyan.txt
chovin/pon/su
chovin/pon/su/ke
chovin/pon/su/ke/tarou.txt
chovin/pon/su/symbolicklink
23
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
14