リンク切れシンボリックリンクの扱い

top20200214_symlnk

先日下記のようなスクリプトを書いていました。

import os
import shutil

src='org.txt'
dst='3.txt'

if os.path.isfile(dst):
    os.remove(dst)
shutil.copyfile(src, dst)

とりあえずcheck.pyというファイル名で保存しました。

やってる事はsrcからdstにファイルをコピーするだけです。ただし、コピー先が存在していたら一旦削除してからコピーします。

一見何ともないのですが、このスクリプトを書きのような状況で動かした時に自分が意図していない動作をして戸惑いました。

$ ls -la
(略)
lrwxrwxrwx 1 XXX XXX    6 Feb 12 19:10 3.txt -> broken
-rwxr-xr-x 1 XXX XXX  618 Feb 12 19:39 check.py
-rw-r--r-- 1 XXX XXX    5 Feb 12 19:35 org.txt

3.txtはシンボリックリンクですが、リンク先は存在せず、壊れています。この状態実行すると下記のようになりました。

$ ls -la
(略)
lrwxrwxrwx 1 XXX XXX    6 Feb 12 19:10 3.txt -> broken
-rw-r--r-- 1 XXX XXX    5 Feb 12 19:53 broken
-rwxr-xr-x 1 XXX XXX  618 Feb 12 19:39 check.py
-rw-r--r-- 1 XXX XXX    5 Feb 12 19:35 org.txt

私の予想では3.txtは存在しないのでexistsはパスするが実際コピーしようとするとリンクがいるためエラーになる…という物だったのですが、実行するとリンク先のbrokenというファイル名でコピーされてしまいました。

私の望んだ動作

これはテストだったのですが、最終的にはこういうスクリプトにしたいと考えていました。

  • 壊れた3.txtのシンボリックリンクを削除してからコピー

top20200214_symlnk