distutils.dir_util.copy_tree() 在 src 目录中包含损坏的符号链接时中止

distutils.dir_util.copy_tree() aborted on broken symlinks contained in src dir

我正在尝试使用 distutils.dir_util.copy_tree() 将整个目录树复制到新位置。但是,调用中止,因为源目录中有一些损坏的符号链接:

[ERROR] * src = 'src_dir/some_broken_symlink'
[ERROR] * dst = 'dst_dir/the_file_pointed_to_by_the_symlink'
[ERROR] * preserve_mode = 1, preserve_times = 1, update = 0, link = None, verbose = 1
[ERROR] * dry_run = 0
[ERROR] * 
[ERROR] *     def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0,
[ERROR] *                   link=None, verbose=1, dry_run=0):
[ERROR] *         """Copy a file 'src' to 'dst'.  If 'dst' is a directory, then 'src' is
[ERROR] *         copied there with the same name; otherwise, it must be a filename.  (If
[ERROR] *         the file exists, it will be ruthlessly clobbered.)  If 'preserve_mode'
[ERROR] *         is true (the default), the file's mode (type and permission bits, or
[ERROR] *         whatever is analogous on the current platform) is copied.  If
[ERROR] *         'preserve_times' is true (the default), the last-modified and
[ERROR] *         last-access times are copied as well.  If 'update' is true, 'src' will
[ERROR] *         only be copied if 'dst' does not exist, or if 'dst' does exist but is
[ERROR] *         older than 'src'.
[ERROR] *     
[ERROR] *         'link' allows you to make hard links (os.link) or symbolic links
[ERROR] *         (os.symlink) instead of copying: set it to "hard" or "sym"; if it is
[ERROR] *         None (the default), files are copied.  Don't set 'link' on systems that
[ERROR] *         don't support it: 'copy_file()' doesn't check if hard or symbolic
[ERROR] *         linking is available. If hardlink fails, falls back to
[ERROR] *         _copy_file_contents().
[ERROR] *     
[ERROR] *         Under Mac OS, uses the native file copy function in macostools; on
[ERROR] *         other systems, uses '_copy_file_contents()' to copy file contents.
[ERROR] *     
[ERROR] *         Return a tuple (dest_name, copied): 'dest_name' is the actual name of
[ERROR] *         the output file, and 'copied' is true if the file was copied (or would
[ERROR] *         have been copied, if 'dry_run' true).
[ERROR] *         """
[ERROR] *         # XXX if the destination file already exists, we clobber it if
[ERROR] *         # copying, but blow up if linking.  Hmmm.  And I don't know what
[ERROR] *         # macostools.copyfile() does.  Should definitely be consistent, and
[ERROR] *         # should probably blow up if destination exists and we would be
[ERROR] *         # changing it (ie. it's not already a hard/soft link to src OR
[ERROR] *         # (not update) and (src newer than dst).
[ERROR] *     
[ERROR] *         from distutils.dep_util import newer
[ERROR] *         from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE
[ERROR] *     
[ERROR] *         if not os.path.isfile(src):
[ERROR] *             raise DistutilsFileError(
[ERROR] * >                 "can't copy '%s': doesn't exist or not a regular file" % src)
[ERROR] * E           distutils.errors.DistutilsFileError: can't copy 'src_dir/some_broken_symlink': doesn't exist or not a regular file
[ERROR] * 
[ERROR] * /usr/software/pkgs/Python-3.7.1/lib/python3.7/distutils/file_util.py:105: DistutilsFileError

我不知道是否有办法让 distutils.dir_util.copy_tree() 忽略这些错误并表现得像 shell 命令 cp -r,这样它就不会在中断时中止来自源目录的符号链接?

该部分的代码是:

from distutils.dir_util import copy_tree
copy_tree(src_dir, dst_dir)

preserve_symlinks=1 已修复。

原始代码(不适用于 src_dir 中损坏的符号链接):

from distutils.dir_util import copy_tree
copy_tree(src_dir, dst_dir)

新代码(使用 src_dir 中损坏的符号链接):

from distutils.dir_util import copy_tree
copy_tree(src_dir, dst_dir, preserve_symlinks=1)