Linux如何复制符号链接并保留日期

时间:2014-07-09 15:04:24

标签: linux bash rhel

我有一个包含这种文件的目录:

  0 lrwxrwxrwx  1 utges_m gid36     12 May 17  2011 libedit.so -> libedit.so.2
  0 lrwxrwxrwx  1 utges_m gid36     16 Apr 16  2009 libedit.so.2 -> libedit.so.2.0.9
352 -rw-r--r--  1 utges_m gid36 358958 Mar 10  2010 libedit.so.2.0.9

我想复制文件和符号链接并保留日期。

我开始使用这个命令:

  cp -dp sourceDir/* destinationDir

结果是:

  0 lrwxrwxrwx  1 siri gid33     12 Jul  9 16:38 libedit.so -> libedit.so.2
  0 lrwxrwxrwx  1 siri gid33     16 Jul  9 16:38 libedit.so.2 -> libedit.so.2.0.9
356 -rw-r--r--  1 siri gid33 358958 Mar 10  2010 libedit.so.2.0.9

所以,我写了这个简单的bash脚本:

 cp -dp $OLDDIR/* $NEWDIR

 ls $OLDDIR | while read f; do {
    TS=$(stat -c '%Y' "$OLDDIR/$f")
    DATE=$(date -d "UTC 1970-01-01 $TS secs")
    echo "$f  $DATE"
    touch -d "${DATE}" "$NEWDIR/$f"
 } done;

脚本输出为:

 libedit.so  Tue May 17 21:35:14 CEST 2011
 libedit.so.2  Thu Apr 16 10:30:05 CEST 2009
 libedit.so.2.0.9  Wed Mar 10 16:31:17 CET 2010

但不幸的是结果是:

  0 lrwxrwxrwx  1 siri gid33     12 Jul  9 16:55 libedit.so -> libedit.so.2
  0 lrwxrwxrwx  1 siri gid33     16 Jul  9 16:55 libedit.so.2 -> libedit.so.2.0.9
356 -rw-r--r--  1 siri gid33 358958 Mar 10  2010 libedit.so.2.0.9

我做了什么错了?

我正在使用Red Hat Enterprise Linux ES第4版(Nahant Update 3)

4 个答案:

答案 0 :(得分:1)

您可以改为使用rsync:

rsync -av /folder/ /newfolder/

示例:

mkdir folder; ln -s /etc/hosts /tmp/folder/testfile

rsync -av /tmp/folder/ /tmp/newfolder/
sending incremental file list
created directory /tmp/newfolder
./
testfile -> /etc/hosts

sent 75 bytes  received 18 bytes  186.00 bytes/sec
total size is 10  speedup is 0.11

ls -l /tmp/folder/ 
total 0
lrwxrwxrwx 1 tiago tiago 10 Jul  9 16:44 testfile -> /etc/hosts

ls -l /tmp/newfolder/ 
total 0
lrwxrwxrwx 1 tiago tiago 10 Jul  9 16:44 testfile -> /etc/hosts

答案 1 :(得分:1)

您的系统可能不支持更改符号链接的时间戳,因为cp -dp 应该开始使用。

此外,如果您使用 touch ,则必须添加(GNU touch-h选项以定位链接而不是目标

man touch - 注意括号中的陈述:

-h, --no-dereference
  affect each symbolic link instead of any referenced file
  (useful only on systems that can change the timestamps of a symlink)

请尝试touch -h <someSymlink>; ls -l <someSymlink>查看原则是否有效。

答案 2 :(得分:1)

为什么这么难?你需要的是cp -a。例如在〜/ lib中我有:

lrwxrwxrwx   1 david david    13 May 28 05:59 libetf.so -> libetf.so.1.0
lrwxrwxrwx   1 david david    13 May 28 05:59 libetf.so.1 -> libetf.so.1.0
-rwxr-xr-x   1 david david  8512 May 28 05:59 libetf.so.1.0

复制并保存日期:

$ md lib2

$ cp -a lib/libetf* lib2

$ ls -al lib2
total 28
drwxr-xr-x   2 david david  4096 Jul  9 11:13 .
drwxr-xr-x 110 david david 12288 Jul  9 11:13 ..
lrwxrwxrwx   1 david david    13 May 28 05:59 libetf.so -> libetf.so.1.0
lrwxrwxrwx   1 david david    13 May 28 05:59 libetf.so.1 -> libetf.so.1.0
-rwxr-xr-x   1 david david  8512 May 28 05:59 libetf.so.1.0

答案 3 :(得分:0)

最好只使用UNIX时间戳:

ls $OLDDIR | while read f; do {
    TS=$(stat -c '%Y' "$OLDDIR/$f")
    DATE=$(date -d "@$TS")
    echo "$f  $DATE"
    touch -d "@$TS" "$NEWDIR/$f"
} done;

此外,您可能不需要使用ls

shopt -s dotglob  ## Allows matching filenames beginning with .
for F in "$OLDDIR"/*; do
    TS=$(stat -c '%Y' "$F")
    N=${F##*/}  ## Get base name.
    DATE=$(date -d "@$TS")
    echo "$N  $DATE"
    touch -d "@$TS" "$NEWDIR/$N"
done

明显的注意:stat -c '%Y' "$OLDDIR/$f"产生秒-since-大纪元,因此使用UTC 1970-01-01 ${SECONDS_SINCE_EPOCH} secs作为参考可能是错误的部分。