将符号链接复制为文件

上面我有两个 smylinks cron_allowcron_deny,让我们将它们作为普通文件而不是符号链接复制到 /tmp/dst_files

# cp -LRv /tmp/src_files/* /tmp/dst_files/
`/tmp/src_files/a' -> `/tmp/dst_files/a'
`/tmp/src_files/b' -> `/tmp/dst_files/b'
`/tmp/src_files/c' -> `/tmp/dst_files/c'
`/tmp/src_files/cron_allow' -> `/tmp/dst_files/cron_allow'
`/tmp/src_files/cron_deny' -> `/tmp/dst_files/cron_deny'

验证符号链接

# ll /tmp/dst_files/
total 8
-rw-r--r-- 1 root root  0 Sep 11 18:03 a
-rw-r--r-- 1 root root  0 Sep 11 18:03 b
-rw-r--r-- 1 root root  0 Sep 11 18:03 c
-rw-r--r-- 1 root root 28 Sep 11 18:03 cron_allow
-rw-r--r-- 1 root root 15 Sep 11 18:03 cron_deny

如我们所见,两个符号链接都转换为普通文件。
让我们将这些内容与原始文件进行匹配

# sdiff cron_allow /tmp/cron.allow
root                                                         root
jack                                                       jack
cherry                                                         cherry
rahul                                                        rahul

手册页说明:

‘-L’ ,‘--dereference’ - 从符号链接复制时遵循符号链接。 使用此选项,cp 无法创建符号链接。 例如,源树中的符号链接(到常规文件)将被复制到目标树中的常规文件。

将符号链接复制为符号链接(不是文件)

# cp -Prv /tmp/src_files/* /tmp/dst_files/
`/tmp/src_files/a' -> `/tmp/dst_files/a'
`/tmp/src_files/b' -> `/tmp/dst_files/b'
`/tmp/src_files/c' -> `/tmp/dst_files/c'
`/tmp/src_files/cron_allow' -> `/tmp/dst_files/cron_allow'
`/tmp/src_files/cron_deny' -> `/tmp/dst_files/cron_deny'

验证符号链接

# ll /tmp/dst_files/
total 0
-rw-r--r-- 1 root root  0 Sep 11 18:06 a
-rw-r--r-- 1 root root  0 Sep 11 18:06 b
-rw-r--r-- 1 root root  0 Sep 11 18:06 c
lrwxrwxrwx 1 root root 13 Sep 11 18:06 cron_allow -> ../cron.allow
lrwxrwxrwx 1 root root 12 Sep 11 18:06 cron_deny -> ../cron.deny

这也可以通过一些更多的参数来实现,如下所示

# cp -dv /tmp/src_files/* /tmp/dst_files/
`/tmp/src_files/a' -> `/tmp/dst_files/a'
`/tmp/src_files/b' -> `/tmp/dst_files/b'
`/tmp/src_files/c' -> `/tmp/dst_files/c'
`/tmp/src_files/cron_allow' -> `/tmp/dst_files/cron_allow'
`/tmp/src_files/cron_deny' -> `/tmp/dst_files/cron_deny'

复制与源目录具有相同权限和所有权的符号链接

通常,如果我们复制文件,目标位置的权限将更改为用于复制文件的用户(将该用户视为目标位置的新所有者)

让我们更改源目录中文件之一的权限和所有者

# ls -l
total 0
-rwxrwxrwx 1 oamsys root  0 Sep 11 17:53 a
-rwxrwxrwx 1 oamsys root  0 Sep 11 17:53 b
-rw-r--r-- 1 root   root  0 Sep 11 17:53 c
lrwxrwxrwx 1 root   root 13 Sep 11 17:53 cron_allow -> ../cron.allow
lrwxrwxrwx 1 root   root 12 Sep 11 17:53 cron_deny -> ../cron.deny

复制后

# cp -dv /tmp/src_files/* /tmp/dst_files/
`/tmp/src_files/a' -> `/tmp/dst_files/a'
`/tmp/src_files/b' -> `/tmp/dst_files/b'
`/tmp/src_files/c' -> `/tmp/dst_files/c'
`/tmp/src_files/cron_allow' -> `/tmp/dst_files/cron_allow'
`/tmp/src_files/cron_deny' -> `/tmp/dst_files/cron_deny'

检查确认

# ll /tmp/dst_files/
total 0
-rwxr-xr-x 1 root root  0 Sep 11 18:12 a
-rwxr-xr-x 1 root root  0 Sep 11 18:12 b
-rw-r--r-- 1 root root  0 Sep 11 18:12 c
lrwxrwxrwx 1 root root 13 Sep 11 18:12 cron_allow -> ../cron.allow
lrwxrwxrwx 1 root root 12 Sep 11 18:12 cron_deny -> ../cron.deny

因此,考虑到我的 umask 值,例如:0022,文件权限已更新为 755,所有权已更改为“root”,因为文件是使用“root”用户复制的。

那么我如何保留这些权限以及符号链接

# cp -dav /tmp/src_files/* /tmp/dst_files/
`/tmp/src_files/a' -> `/tmp/dst_files/a'
`/tmp/src_files/b' -> `/tmp/dst_files/b'
`/tmp/src_files/c' -> `/tmp/dst_files/c'
`/tmp/src_files/cron_allow' -> `/tmp/dst_files/cron_allow'
`/tmp/src_files/cron_deny' -> `/tmp/dst_files/cron_deny'

检查确认

# ll /tmp/dst_files/
total 0
-rwxrwxrwx 1 oamsys root  0 Sep 11 17:53 a
-rwxrwxrwx 1 oamsys root  0 Sep 11 17:53 b
-rw-r--r-- 1 root   root  0 Sep 11 17:53 c
lrwxrwxrwx 1 root   root 13 Sep 11 17:53 cron_allow -> ../cron.allow
lrwxrwxrwx 1 root   root 12 Sep 11 17:53 cron_deny -> ../cron.deny

现在一切看起来没问题。

从“手册”页面

-a, --archive
              和 -dR --preserve=all 相同
如何在 Linux 中复制文件时保留符号链接

不同目录之间复制符号链接的场景可以有很多,

我创建了几个示例文件和符号链接来演示。下面的操作在SuSE Linux Enterprise Server 11 SP 3 中演示。

# mkdir /tmp/src_file
# cd /tmp/src_files
# ls -l
total 0
-rw-r--r-- 1 root root  0 Sep 11 17:53 a
-rw-r--r-- 1 root root  0 Sep 11 17:53 b
-rw-r--r-- 1 root root  0 Sep 11 17:53 c
lrwxrwxrwx 1 root root 13 Sep 11 17:53 cron_allow -> ../cron.allow
lrwxrwxrwx 1 root root 12 Sep 11 17:53 cron_deny -> ../cron.deny

使用相对路径复制符号链接

这里有一个大问题,对我来说,符号链接的复制工作正常,因为我们将符号链接复制到同一父目录中,并且目标文件始终可以通过符号链接访问。

其他例子:

# ll
total 0
-rwxrwxrwx 1 oamsys root  0 Sep 11 17:53 a
-rwxrwxrwx 1 oamsys root  0 Sep 11 17:53 b
-rw-r--r-- 1 root   root  0 Sep 11 17:53 c
lrwxrwxrwx 1 root   root 13 Sep 11 17:53 cron_allow -> ../cron.allow
lrwxrwxrwx 1 root   root 12 Sep 11 17:53 cron_deny -> ../cron.deny

这里上面的符号链接 cron_allow 指向/tmp/cron.allow,但我将这些文件复制到一个完全不同的位置,其中相对路径 . ./cron.allow无法访问。

# cp -Prv /tmp/src_files/* /tmp/test/new_dst/
`/tmp/src_files/a' -> `/tmp/test/new_dst/a'
`/tmp/src_files/b' -> `/tmp/test/new_dst/b'
`/tmp/src_files/c' -> `/tmp/test/new_dst/c'
`/tmp/src_files/cron_allow' -> `/tmp/test/new_dst/cron_allow'
`/tmp/src_files/cron_deny' -> `/tmp/test/new_dst/cron_deny'

检查确认

# ll /tmp/test/new_dst/
total 0
-rwxr-xr-x 1 root root  0 Sep 11 18:19 a
-rwxr-xr-x 1 root root  0 Sep 11 18:19 b
-rw-r--r-- 1 root root  0 Sep 11 18:19 c
lrwxrwxrwx 1 root root 13 Sep 11 18:19 cron_allow -> ../cron.allow
lrwxrwxrwx 1 root root 12 Sep 11 18:19 cron_deny -> ../cron.deny
# cd /tmp/test/new_dst/
# less cron_allow
cron_allow: No such file or directory

所以../cron.allow是不可访问的。
为避免此类情况,始终建议使用目标文件的完整路径作为符号链接。

我使用下面脚本来解决这些问题

#!/bin/sh
src="/tmp/src_files"
dst="/tmp/test/new_dst"
#clean destination
if [ -d $dst ]; then
   echo "Cleaning target directory $dst"
   rm -f $dst/*
fi
#copy files
for i in `ls $src`; do
   path=""
   if [  -L $i ]; then
      path=`readlink -f $i`
      ln -s $path $dst/$i
   else
      cp -vP $i $dst
   fi
done
# Listing target directory files
ls -al $dst
日期:2020-06-02 22:17:03 来源:oir作者:oir