cp コマンドでシンボリックをコピーする

  • 27
    いいね
  • 1
    コメント
この記事は最終更新日から1年以上が経過しています。

今まで勘違いしていたので覚え直しと、ちょっとぐぬぬ…ってなったのでメモ。

cp コマンドでシンボリックリンクそのものをコピーしようとした場合、名前を維持して実体化されてしまいシンボリックリンクとしてコピーできない(これは普通だけどね…)。

$ ls /path/to/symlink
/path/to/symlink => substance
$ cp /path/to/symlink .
$ ls symlink
symlink # 中身は substance になる

例えばダイナミックライブラリ群をコピーする際、cp libname*.dylib dest なんてやると全部実体化して容量が無駄になる。

gcp には -d オプションがあるのでそれを使えばシンボリックリンクのままコピーできるけど BSD の cp にはそれが無い。シンボリックリンクとしてそのままコピーする場合は -R オプション。

$ cp -R /path/to/symlink .
$ ls
symlink => substance

あれ?-R オプションってディレクトリ用じゃないの?と思ってディレクトリのシンボリックリンクをコピーしてみたらシンボリックリンクのままコピーされてしまう。

$ ls /path/to/dir1
/path/to/dir1 => dir2
$ cp -R /path/to/dir1 .
$ ls dir1
dir1 => dir2

ディレクトリへのシンボリックリンクの場合は -H オプションを追加する。-H オプションはコマンドライン上のシンボリックリンクを辿る。(ditto コマンドはデフォルトでこの動作になる)。

$ cp -RH /path/to/dir1 .
$ ls dir1
dir1

-H に似たようなので -L があるけど、-L は全てのシンボリックリンクを辿るのでディレクトリ以下のシンボリックリンクも全て実体化する。例えば fontconfig の conf.d 内のファイルはほとんどが ../conf.avail へのシンボリックリンクになっているのでそれを全部実体化してコピーしたい場合は -H オプションを使う。

話変わって ln コマンドになるけど、既にあるディレクトリへのシンボリックリンクを上書きしようとしてもそのディレクトリの中に落ちてしまい正しく上書きができない。

$ ln -s A Current
$ ln -fs B Current # A/B が作成されてしまう

ln コマンドの場合は -h でシンボリックリンクを辿らないようにできる。

$ ln -fhs B Current
$ ls Current
Current => B