tkuchikiの日記

新ブログ https://blog.tkuchiki.net

Mac で cp を使うときの注意

MacでFinderからドラッグ&ドロップしてディレクトリを上書きしようとすると置き換えられてしまう。
そこで、

cp -rf src dest


のように実行したところ、
まったく上書きされていない。。。

Macのマニュアルを見てみると、

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.

     The -v and -n options are non-standard and their use in scripts is not


BSDの日本語マニュアル(On-line Manual of "cp")も載せておくと、

互換性
     従来版の cp には -r オプションがありました。本実装でもこのオプションはサ
     ポートされていますが、特殊ファイル・シンボリックリンク・FIFO などを正しく
     コピーできないため、これを使用することは奨められません。

     -v および -n は標準ではありませんし、スクリプト中での使用はお勧めしません。


とのこと。
BSDの英語マニュアル(Man Page for cp (freebsd Section 1) - The UNIX and Linux Forums)を見てみたら、若干文章が違うけれど、とりあえず気にしないでおく。
正しく使う場合は、"-R" を使えばOKのようだ。

あと、同僚に教えていただいたのだが、
"-a" でも再帰的にコピーできるようだ。
ずっと "-a" はユーザとグループを維持したままコピーだと思っていた。。。

確かにマニュアルと見ると、

GNU

      -a, --archive
              same as -dR --preserve=all

       -d     same as --no-dereference --preserve=links

       -P, --no-dereference
              never follow symbolic links in SOURCE

       -p     same as --preserve=mode,ownership,timestamps

       --preserve[=ATTR_LIST]
              preserve the specified attributes (default:  mode,own-
              ership,timestamps), if possible additional attributes:
              context, links, xattr, all

       --no-preserve=ATTR_LIST
              don’t preserve the specified attributes

       -R, -r, --recursive
              copy directories recursively

BSD

     -a    Same as -pPR options. Preserves structure and attributes of files
           but not directory structure.

     -P    If the -R option is specified, no symbolic links are followed.  This
           is the default.

     -p    Cause cp to preserve the following attributes of each source file in
           the copy: modification time, access time, file flags, file mode,
           user ID, and group ID, as allowed by permissions.  Access Control
           Lists (ACLs) and Extended Attributes (EAs), including resource
           forks, will also be preserved.

           If the user ID and group ID cannot be preserved, no error message is
           displayed and the exit value is not altered.

           If the source file has its set-user-ID bit on and the user ID cannot
           be preserved, the set-user-ID bit is not preserved in the copy's
           permissions.  If the source file has its set-group-ID bit on and the
           group ID cannot be preserved, the set-group-ID bit is not preserved
           in the copy's permissions.  If the source file has both its set-
           user-ID and set-group-ID bits on, and either the user ID or group ID
           cannot be preserved, neither the set-user-ID nor set-group-ID bits
           are preserved in the copy's permissions.

     -R    If source_file designates a directory, cp copies the directory and
           the entire subtree connected 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.


再帰的にコピーしたい場合、ユーザとグループを維持したままでよければ "-a" 、
維持したくなければ "-R" を使えば概ねOK。

ここまで書いていて思ったが、シンボリックリンクとかで問題が出ることはわかったが、
ファイルが全く上書きされなかった理由にはなっていない気がする。。。
階層が深すぎるとだめなのか?
ただ、今回のように全く上書きされなかったのはかなり特殊なケースだと思われる(これ以外で同様のケースに遭遇したことがない)。

色々探してみたら、こちらの記事の方がよくまとめられている(manに「cp -rは使うな」と書いてあった話 - 西尾泰和のはてなダイアリー)