2

符号链接

我很难理解符号链接。我相信我理解了基本前提,它本质上是一个别名。

但是,假设您让当前工作目录参与符号链接的制作,它是否取决于您在制作它时所处的工作目录?

我正在使用的当前命令是ln -s

示例场景

我在 GitHub 上有一些项目,其中一些是我编写的简单的小脚本,存储在 ~/bin 中。~/bin 在我的 $PATH 环境变量中,以便于调用这些脚本:

$echo $PATH
/Users/me/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin

我刚刚注意到,在我的 git 安装中,它看起来好像/usr/local/git/bin已附加到我的 $PATH 中。暂时,我会假装这没有发生。

例如:(hist是一个简单的脚本,显示我最近使用的命令的统计信息

#/bin/bash
history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10

$hist
     1  115  23%    l
     2  58   11.6%  cd
     3  44   8.8%   ls
     4  29   5.8%   git
     5  14   2.8%   sudo
     6  13   2.6%   locate
     7  12   2.4%   open
     8  11   2.2%   wc
     9  10   2%     dt
    10  9    1.8%   rm

如果我执行此操作:

$cd ~/bin
$pwd
$/Users/me/bin
$ln -s hist ~/Desktop/hist
$ls -la ~/Desktop/
$ls -la | grep hist
lrwxr-xr-x   1 me  staff  4 Sep 15 21:15 hist -> hist
$cd ~/Deskop
$hist

命令词,但与hist -> hist我有关的列表,它没有提供关于真正来源的信息。我不确定我是否可以将文件移动到其他地方并且它仍然可以工作。

所以我最近养成了在制作符号链接时不使用任何扩展标记的习惯。没有更多~的意思。

我什至只需要在开始使用 GitHub 时就开始这样做,并且正在为我.bash_profile.bashrc、 和.bash_history. 每次我对我的.bash_profileto 进行更改,然后cp将它从我的本地存储库更改为~/bin,然后运行source ~/bin/.bash_profile

问题

使用 的正确程序是什么ln -s,或者纯粹是偏好问题,最终结果将始终相同。

好消息是我了解了 -F 标志,ln因此如果我点击作为目标的文件名,我将不再收到错误消息。-F 标志会告诉ln我要覆盖它,从而节省我mv'ing 文件然后运行ln -s命令的时间。

参考

这就是我的 ~/bin 现在的样子,为了简单起见,删除了许多:

$l
total 56
lrwxr-xr-x  1 me  staff   53 Sep 15 20:40 hist -> /Users/me/Documents/me/git-projects/hist/hist
lrwxr-xr-x  1 me  staff   57 Sep 15 20:41 lcaser -> /Users/me/Documents/me/git-projects/lcaser/lcaser
lrwxr-xr-x  1 me  staff   70 Sep 10 05:12 mate -> /Applications/TextMate 1.x.app/Contents/SharedSupport/Support/bin/mate
lrwxr-xr-x  1 me  staff   56 Sep 15 20:42 tart -> /Users/me/Documents/me/git-projects/tart/tart.sh
lrwxr-xr-x  1 me  staff   69 Sep 15 20:44 watchinstall -> /Users/me/Documents/me/git-projects/watchInstall/watchInstall
4

1 回答 1

2

考虑:

ln -s target linkname

复杂性仅在target由相对路径指定时发生。如果是,则路径相对于保存文件的目录linkname。当前的工作目录总是被忽略。

例如,考虑

ln -s hist ~/Desktop/hist

此命令创建一个名为 的hist链接~/Desktop。由于没有为目标提供路径,因此目标被解释为也在目录中~/Desktop。在这种情况下,这意味着链接hist指向自身。

作为另一个例子,考虑

cd /var/tmp
ln -s ../hist ~/Desktop/hist

这将创建一个从~/Desktop/histto的链接,~/hist因为../是相对于保存链接的目录进行解释的,~/Desktop. 我们ln执行命令时所在的目录和我们访问时所在的目录/Desktop/hist都无关紧要。

另一个微妙之处

ln不关心您target在发出命令时使用什么:它可以是任意文本。在尝试访问之前target,不会解释的值。考虑:linkname

$ ln -s "mary had a little lamb" ~/file1
$ ls -alt ~/file1
lrwxrwxrwx 1 user group 22 Sep 15 21:47 /home/user/file1 -> mary had a little lamb
$ cat ~/file1
cat: /home/user/file1: No such file or directory

如果我们愿意,我们可以稍后创建该文件:

$ echo this is a test >~/"mary had a little lamb"
$ cat ~/file1
this is a test

同样,仅在尝试访问链接时才检查目标的存在。

文档

此行为记录在man ln

符号链接可以包含任意文本;如果稍后解决,则相对链接将相对于其父目录进行解释。

于 2014-09-16T04:44:50.800 回答