红联Linux门户
Linux帮助

处女贴,关于cp命令的一些疑问 续更新

发布时间:2010-01-17 20:02:36来源:红联作者:yanyongkg
[i=s] 本帖最后由 yanyongkg 于 2010-1-18 10:34 编辑 [/i]

又一次拜读鸟哥的大作,关于cp命令的一些疑问
1) 书中是这样说的cp -s:做连结档,同ln用法
以下是我做实验(centos5.4 'uname -a'=2.6.18-164.el5):
[yan@localhost tmp]$ pwd
/home/yan/tmp
[yan@localhost tmp]$ ll
-rw-rw-r-- 1 yan yan 21 01-17 18:39 aaa #aaa是个文本文件
drwxrwxr-x 2 yan yan 4096 01-17 18:59 test #一个目录

当前目录建立链接的情况
[yan@localhost tmp]$ cp -s aaa bbb
[yan@localhost tmp]$ ll
lrwxrwxrwx 1 yan yan 3 01-17 19:02 bbb -> aaa #没问题,OK

非当前目录建立链接的情况
[yan@localhost tmp]$ cp -s aaa test/bbb2
cp: “test/bbb2”:只能于当前目录中创建相对的符号链接 #提示只能当前目录建立
[yan@localhost tmp]$ cp -s ~/tmp/aaa test/bbb2
[yan@localhost tmp]$ ll test
lrwxrwxrwx 1 yan yan 17 01-17 19:08 bbb2 -> /home/yan/tmp/aaa
这里看出来cp -s做链接档,源文件必须用绝对路径?不是提示所说的只能于当前目录建立符号链接
/home/yan/tmp/aaa,叫绝对路径
~/tmp/aaa,这个也绝对路径?或许全路径?

换ln -s试试,在当前目录建立链接的情况:
当前目录建立链接
ln -s aaa bbb跟cp -s aaa bbb一样,这个没问题

非当前目录建立链接
先用相对路径看看
[yan@localhost tmp]$ ln -s aaa test/bbb3 #没问题,貌似可以了,只所以说貌似,接着往后看你就明白了
再用绝对路径看看
[yan@localhost tmp]$ ln -s ~/tmp/aaa test/bbb4
[yan@localhost tmp]$ ll test
lrwxrwxrwx 1 yan yan 3 01-17 19:13 bbb3 -> aaa
lrwxrwxrwx 1 yan yan 17 01-17 19:40 bbb4 -> /home/yan/tmp/aaa
可以看出链接文件bbb3指向当前目录下的aaa文件,当前目录也就是bbb3所在的目录,这肯定就不对了aaa文件就不在这个目录下,不信可以cat bbb3一下
[yan@localhost test]$ cat bbb3
cat: bbb3: 没有那个文件或目录
[yan@localhost test]$ cat bbb4
hello,Linux
justaaaa

小结:ln -s或cp -s往非当前目录做链接文件时,源文件必须用绝对路径,不然就算做上了链接文件,链接文件指向的路径也不对
上面说得不太明白,换成下列说法更容易理解
做链接符号文件时,源文件和链接文件不在同一目录的时候,源文件路径必须用绝对路径,链接文件绝对路径或相对路径都可以
源文件和链接文件在同一目录的情况下就没所谓了,源文件和链接文件使用相对路径或绝对路径都可以

ps:这里是讲的软链接,还有硬链接,ln -d,我的centos环境直接ln默认-d参数就是有的,刚开始我ln aaa bbb,我还以为也是复制了个aaa为bbb呢,网上搜了下才知道,这个给个地址大家有兴趣可以看看
http://hi.baidu.com/zhongbin104/blog/item/374bc7550e49c75c564e00a8.html

未完待续,还有2)没写,这个疑问就比较大了,要吃晚饭了,呵呵

2)cp -u
鸟哥书中如是说:cp -u 如果来源档比较新,或者没有目的档,才会执行copy动作,可用于备份的动作当中
鸟哥还给了个例子并加了注释说明:
cp -u /home/.bashrc /root/.bashrc #先检查/home/.bashrc是否与/root/.bashrc不同,如不同则copy一份,如果相同则不进行任何动作

用心在看的话肯定会想到这个问题,来源档和目的档比较的是文件内容有不同呢还是文档修改时间不同呢?
于是我做了下面一系列测试:
[yan@localhost tmp]$ ll
总计 8
-rw-rw-r-- 1 yan yan 12 01-17 23:13 aaa #最后修改时间为23:13
-rw-rw-r-- 1 yan yan 24 01-17 23:14 bb #最后修改时间为23:14
[yan@localhost tmp]$ cat aaa
hello,Linux
[yan@localhost tmp]$ cat bb
hello,Linux
just a test #aaa和bb文件内容不同
[yan@localhost tmp]$ cp -u aaa bb
[yan@localhost tmp]$ cat bb
hello,Linux
just a test #虽然源文档和目的档内容不同,但没有进行copy动作,说明它们比较的不是文件内容
#源文档aaa没有目的档bb最后修改时间新,故没有进行copy动作,是这个原因吗,后面接着验证
过了一会儿了,修改下aaa文件
[yan@localhost tmp]$ll
-rw-rw-r-- 1 yan yan 16 01-17 23:18 aaa
-rw-rw-r-- 1 yan yan 24 01-17 23:14 bb #这里时间还是原来的23:14
[yan@localhost tmp]$ cat aaa
hello,Linux
hey
[yan@localhost tmp]$ cat bb
hello,Linux
just a test
[yan@localhost tmp]$ cp -u aaa bb
[yan@localhost tmp]$ ll
总计 8
-rw-rw-r-- 1 yan yan 16 01-17 23:18 aaa
-rw-rw-r-- 1 yan yan 16 01-17 23:18 bb #这里最后修改时间已经变成23:18了,貌似进行copy动作了,下面cat下看看
[yan@localhost tmp]$ cat bb
hello,Linux
hey #看明白了吧?

我想得比较极端,比较的最后修改时间这里只精确到分,它是要精确到秒吗?
[yan@localhost tmp]$ ll
总计 8
-rw-rw-r-- 1 yan yan 6 01-17 23:36 aaa #先改的aaa
-rw-rw-r-- 1 yan yan 12 01-17 23:36 bb #后改的bb bb的最后修改时间比aaa新
[yan@localhost tmp]$ cat aaa
hello
[yan@localhost tmp]$ cat bb
hello,Linux
[yan@localhost tmp]$ cp -u bb aaa
[yan@localhost tmp]$ ll
总计 8
-rw-rw-r-- 1 yan yan 12 01-17 23:40 aaa
-rw-rw-r-- 1 yan yan 12 01-17 23:36 bb
[yan@localhost tmp]$ cat aaa
hello,Linux #还真精确到妙了!

由于早格掉了XP,所以不好发截图,鸟哥对于cp -u有点没说明白,直接给马虎过去了,虽然鸟哥比较权威,我还是要挑战,不要拍我,对于鸟哥我没有不敬之意
处女贴写的比较长,谢谢大家能读完
文章评论

共有 8 条评论

  1. yanyongkg 于 2010-01-18 15:05:50发表:

    醍醐灌顶啊,太感谢了!谢谢acrofox!
    源文件可以使用相对路径,不是相对于当前工作目录,而是相对于目的文件所在目录而言所写的相对路径
    8楼关于用绝对路径或相对路径各自的特点,说得很详细明白,我就不重复了

    呵呵,我验证了下如下:
    [yan@localhost tmp]$ pwd
    /home/yan/tmp
    [yan@localhost tmp]$ ls
    aaa test
    [yan@localhost tmp]$ ln -s ../../aaa test/test1/zzz #目的档是在/home/yan/tmp/test/test1目录下,源文件是在/home/yan/tmp目录,源文件相对于目的档的路径就是../../aaa
    [yan@localhost tmp]$ cd test/test1
    [yan@localhost test1]$ ll
    总计 0
    lrwxrwxrwx 1 yan yan 9 01-18 14:50 zzz -> ../../aaa
    [yan@localhost test1]$ cat zzz
    hello,Linux
    asdfafsadfafag

  2. acrofox 于 2010-01-18 12:47:34发表:

    先说简短的, cp -u 是那么回事。
    再说长的。
    我那个例子中没有省略,就是原样输入就可以了。
    这么说吧,如果你 cd /usr/local/bin,那么这时你打开 ../Adobe/Reader8/bin/acroread 就等同于打开 /usr/local/Adobe/Reader8/bin/acroread,因为那个 ../ 把你带到了上一层目录 /usr/local。
    不难理解,如果你在 /usr/local/bin 目录下执行 ln 命令,那么可以用:[code]ln -s ../Adobe/Reader8/bin/acroread .[/code]但是如果当前目录在 /usr/local 下,还想在 /usr/local/bin 下建立符号链接,该怎么办呢?
    常常有人想当然地执行[code]ln -s Adobe/Reader8/bin/acroread bin[/code]结果却得到一个 broken symbolic link。
    其实这时你只要把源改为相对于 /usr/local/bin 目录的相对路径,也就是说当当前目录在 /usr/local/bin 下时应该采用的相对路径,就没有问题了。所以正确的命令是:[code]ln -s ../Adobe/Reader8/bin/acroread bin[/code]源使用绝对路径当然也可以,但效果是有差别的。
    使用绝对路径的好处是,你可以把符号链接移到别的地方,链接仍然有效。
    使用相对路径的好处是,你可以把符号链接及其所指向的目标一所处的目录结构一起移到别的地方,符号链接仍然有效。
    再拿上面的例子来说,如果使用绝对路径建立 acroread 的符号链接,那么如果把 /usr/local 这个分区(假设单独分区了)挂载到了 /software 目录上,那么符号符号链接已经失效了,因为 /usr/local/Adobe/Reader8/bin/acroread 已经变成 /software/Adobe/Reader8/bin/acroread 了。但是如果使用我给的那种相对路径,那么符号链接仍然有效。因为当 /usr/local/bin/acroread 变成了 /software/bin/acroread 时,站在它所处的目录中看,../Adobe/Reader8/bin/acroread 正好是 /software/Adobe/Reader8/bin/acroread。

    如果你用的系统是 Debian/Ubuntu,那么 /usr/bin 下一定有很多文件是采用相对路径的符号链接(其它系统也可能有,但我不了解)。不管当前目录在哪,你用 file 命令查看一个符号链接时,表示目标的字符串都是不变的。比如我的系统中 /usr/bin/xulrunner-1.9 总是指向 ../lib/xulrunner-1.9.0.17/xulrunner。当你在 /home/tom 下时,../lib/xulrunner-1.9.0.17/xulrunner 这个文件是不存在的,但这并不影响你使用 /usr/bin/xulrunner-1.9,因为系统知道那就是 /usr/bin/../lib/xulrunner-1.9.0.17/xulrunner,即 /usr/lib/xulrunner-1.9.0.17/xulrunner。

    钻点牛角尖很好,能把问题弄明白。

  3. yanyongkg 于 2010-01-18 10:29:04发表:

    [i=s] 本帖最后由 yanyongkg 于 2010-1-18 10:35 编辑 [/i]

    acrofox,这么早啊,明白你说的意思了
    是我表述得欠佳,我红字部分说的
    小结:ln -s或cp -s往非当前目录做链接文件时,源文件必须用绝对路径,不然就算做上了链接文件,链接文件指向的路径也不对
    往当前目录做链接,源文件肯定在当前目录撒,我指的往非当前目录做链接符号文件时,意思指的是源文件和链接文件不在同一目录
    我应该这样说吧,做链接符号文件时,源文件和链接文件不在同一目录的时候,源文件路径必须用绝对路径,链接文件绝对路径或相对路径都可以
    源文件和链接文件在同一目录的情况下就没所谓了,源文件和链接文件使用相对路径或绝对路径都可以

    1楼已更新
    ln -s ../Adobe/Reader8/bin/acroread /usr/local/bin
    你这里的../Adobe/Reader8/bin/acroread 这个路径我有点疑问 .. 上层目录 你的点点指的上层目录还是偷了个懒略写了啊,汗
    PS:我是不是有点钻牛角尖了啊,还有cp -u我理解的是对的吗?

  4. vdnuiv 于 2010-01-18 07:51:38发表:

    支持

  5. acrofox 于 2010-01-18 06:48:33发表:

    这个我不用试了,肯定是不行的,我上面已经说明:符号链接使用相对路径一定要“相对于”符号链接所在的目录。所以即使是在 /usr/local/Adobe/Reader8/bin 下执行,也应该使用我给的命令:[code]ln -s ../Adobe/Reader8/bin/acroread /usr/local/bin[/code]本来上面的回复我是写“都应该执行下面的命令”的,但怕有人挑错说最后一个参数(/usr/local/bin)可以改,所以就把“应该”改成“可以”了。那么我再说明一下,上面的例子中,只要源和目的没变,那么不管是在哪个目录下执行,ln 命令的源参数都应该是我写的那样(除非改用绝对路径)。
    PS:虽然我说太长,看着晕乎乎的,但并不是没仔细看,否则我不会抓住你使用了错误的相对路径那个关键。

  6. yanyongkg 于 2010-01-17 21:46:05发表:

    谢谢3楼的朋友关注我的处女贴,如果你能再仔细看看我的处女贴你可能会明白我说的是什么我会更高兴,你说的ln -s /usr/local/Adobe/Reader8/bin/acroread /usr/local/bin,是可以在任务目录下执行,你cd到/usr/local/Adobe/Reader8/bin目录下执行ln -s acroread /usr/local/bin试试看,或者cd到/usr/local/Adobe下执行ln -s Reader8/bin/acroread /usr/local/bin,执行完后,ll /usr/local/bin/acroread,你看看链接是指向哪儿了。这样你cd到/usr/local/bin目录下执行一下这个链接符号的文件./acroread或者直接执行/usr/local/bin/acroread也一样,你看看它能执行得了不

  7. acrofox 于 2010-01-17 21:11:08发表:

    太长,看着有点晕乎乎的,就针对红色字附近的内容回复一下吧。

    1. ~/tmp/aaa 确实是绝对路径,因为 shell 会把 ~ 扩展为 $HOME,而 $HOME 是以 / 开头的,也就是说,应用程序(cp)看到的参数是以 / 开头的了。如果不把 ~ 解释成 $HOME,则是相对路径,但那时 ~ 只代表当前目录下一个子目录。

    2. 符号链接可以使用相对路径,只是这个相对路径一定要是“相对”符号链接所在的目录。例如,如果 acroread 8 安装在 /usr/local 下,acroread 的运行文件为 /usr/local/Adobe/Reader8/bin/acroread,如果想在 /usr/local/bin 下建一个同名的符号链接,那么不管当前目录在哪,都可以执行下面的命令:[code]ln -s ../Adobe/Reader8/bin/acroread /usr/local/bin[/code]

  8. openbian 于 2010-01-17 20:52:07发表:

    给顶个