ln -s和alias有什么区别?

39

我刚找到了一个解决方案,可以解决在安装了MacPorts版本的Python后,Sublime Text 3的subl命令出现的问题。指南说要将软链接ln-s放入/bin中的命令行应用程序中。但那没起作用,所以我只是打开了我的 ~/.profile 然后添加了别名:alias subl="/Applications/path/to/subl"。但这引发了新的问题:别名和软链接之间有什么区别?


3
为避免其他读者像我一样感到困惑,提醒大家注意以下内容。在这个问题和大多数答案中(但不是全部),单词“alias”指的是在Unix、Linux等许多shell中找到的alias命令。例如,请参阅LINFO上的The alias Command。这与OS X和MacOS环境中“alias”的非常不同含义形成对比。例如,请参阅维基百科上的Alias (Mac OS) - tkp
7个回答

36

别名是一种Macintosh Finder概念。在Finder中创建别名时,Finder会跟踪它。当您移动原始文件或文件夹时,别名会跟随它。

符号链接是Unix文件系统的概念。创建符号链接时,它仅指向原始位置。移动原始位置后,符号链接将指向空地址。

当您使用Mac应用程序并使用“打开/保存”对话框时,它会处理别名,因为它使用Finder API,并且Finder处理别名跟踪。

Unix工具无法与Finder API集成,因此无法跟踪别名。但是,它们可以使用底层的Unix API来处理符号链接。您可以在符号链接上使用“ls”,因为它使用的是Unix API。Python也是如此。

在System 7/8/9时代,文件系统无法处理符号链接,就像Windows API使用快捷方式而不是符号链接一样。你需要别名。

但是,Mac OS X是基于Unix的操作系统,因此了解符号链接的概念。现在,Finder将符号链接视为别名(除了符号链接不会在原始位置移动时更新)。别名唯一的理由是与旧的Finder文件系统兼容。


2
Finder别名类似于符号链接,但OP创建的别名是一个shell别名,而不是Finder别名。这只是一种文本替换类型的快捷方式,用于输入文件的完整名称。它不会显示在Finder窗口中,只有在终端窗口中输入时才有效。 - beroe
1
感谢您的详细解释,但@beroe是正确的。我创建的别名仅适用于Shell,并不会在Finder中显示。 - charltoons
6
抱歉,我看到了Mac OS,以为您在问Finder Alias和Unix OS Symbolic link之间的区别。在Unix中,别名是一个shell概念而不是操作系统概念。并非所有的Unix shell都支持别名(例如原始的Bourne shell)。在支持别名的shell中,只有当别名被用作命令并执行命令字符串时才会检测到别名,但没有进行shell替换。如果使用set -xv,则无法看到别名被替换。 - David W.
5
这个回答解答了一个比被问到的问题更有意义的问题 :) - copumpkin
你说“别名的唯一原因是为了与旧的Finder文件系统兼容”。但是,当原始文件被移动时,Finder跟踪别名的能力不是足够好的理由吗? - Giuseppe
如何实现MacOS的别名?这是一个重要的问题。我发现使用模糊的语言,比如“Finder API”,几乎没有什么用处,我们需要具体的实现方式。我读到过关于它们存储inode并进行搜索的信息(但由于权限系统的限制,在Unix上这是不可能的),但我还没有找到详细的资料。 - Lothar

31

尽管在本例中它们可以用于类似的目的,但它们是完全不同的东西。

这个:

alias subl="/Applications/path/to/subl"
创建别名,这样在命令行中键入subl与键入/Applications/path/to/subl等效。
在bash中,通常更喜欢使用函数而不是别名,因为它们更加灵活和强大。
subl() { /Applications/path/to/subl ; }

这两个东西都是特定于 shell 的;它们使 shell 将 sub1 扩展为指定的命令。

ln -s 则在文件系统中创建一个符号链接。符号链接是对另一个文件的引用,对于大多数目的,它可以被视为文件本身。它适用于任何访问它的内容,不仅限于 shell,它会立即对系统上运行的所有进程可见,并持久存在直到它被删除。(符号链接被实现为包含目标文件名称的小型特殊文件。)


Keith,你能提供一下为什么函数比别名更受推崇吗(特别是像这种情况)?例如,这个答案认为相反:http://unix.stackexchange.com/a/30950 谢谢! - cjerdonek
1
@cjerdonek:不,我没有参考。别名并没有什么问题,但是函数更加强大。你可以使用函数实现别名所能做的任何事情。 - Keith Thompson

7

这确实是一个超级问题

在这场辩论中,有三个别名的级别

  1. 文件系统:ln -s "目标文件或目录" "别名" - 所有使用文件系统的程序(bash、Finder、应用程序)都可以看到它
  2. Shell 别名:(bash/sh/zsh 等)-(问题的一部分)- 仅由 shell 命令行使用
  3. MacOS Finder:"创建别名" - Finder 和大多数应用程序中的文件对话框都知道它

一些不同的用例:

  • 希望 shell 脚本(bash)以符号方式导航您的文件系统-然后使用ln -s...。当您安装java时,它将自己使用此技术。例如尝试说which java并查看 java 的位置。然后使用ls -a /usr/bin/java查看其真正的位置。
  • 想要在 Finder 中进行快速链接,以便您可以导航到位于不同目录中的常见内容- > 使用Finder 创建别名
  • 想要使用 bash 快捷方式启动 Sublime 编辑器,则使用Shell 别名。我有别名ll=ls -l - 它以每行一个项目的方式列出目录。我几乎不能在没有它的情况下使用bash :-) 请注意,这些替换仅在命令行替换中发生在bash中,因此在 shell 脚本中不太有用。

个人而言,我经常使用ln -s ..

我也经常使用Finder 创建别名。它很容易,链接会随着物品的移动而改变位置。但是它无法从bash中工作-因此,当我需要开始编写脚本时,我有时将这些链接更改为**ln -s ...*


2
ln -s创建一个符号链接,几乎就像是文件系统上的一个文件。

别名(alias)是shell特定的东西。

因此,基本上符号链接是更好的解决方案,因为它可以适用于所有内容。比如,如果你想让文件管理器使用特定程序打开文本文件,你可以指向符号链接,它就能够起作用了。


1

别名仅存在于shell(Bash、Sh、Zsh等)的上下文中,但在其他应用程序中找不到,而ln -s创建一个虚拟文件(即链接),指向一个现有的真实文件,它可以像新命令一样呈现自己,并且大多数调用其他二进制文件的应用程序都能识别它。别名类似于函数和变量,只是它们更像命令模板。创建函数实际上更值得推荐。


1
我认为你在上面的别名命令中可能缺少了一些内容 - 它应该采用alias mumble="substitution" 的形式,这将导致您键入的任何以mumble开头的命令被替换为substitution。所以如果你在配置文件中输入的是alias subl="/Applications/path//to/subl",那么每当你在命令开头键入subl时,它都会被完整路径替换。 ln通过在文件系统中从一个东西到另一个东西创建引用来工作。
你提供的链接表明ln无法与MacPorts提供的Python版本一起使用。

1

编辑:另一个评论让我意识到我提到的别名是特定于Mac的“finder”别名,而这里讨论的别名是bash“shell”别名。我的错误。

符号链接或软链接指向文件系统上的位置:路径。如果位于该路径的文件或文件夹被移动或重命名,则软链接现在将指向无用的内容。

别名可以包含对路径或文件ID的引用,也可以两者都有,具体取决于实现方式。至少在Mac OS X上,默认值为两者都有,但路径优先于文件ID。也就是说,只要别名所引用的路径存在某些内容,您的别名就会指向该路径,就像符号链接一样。但是,如果别名所引用的路径上不存在任何内容,则它将指向原始文件ID。

例如:

假设您创建了一个文件,然后通过指定文件路径为其创建了一个别名。现在,别名包含文件的文件ID以及文件的路径。默认情况下,别名将按照文件的路径跟随您到达该文件。

如果您现在将文件移动到其他位置,则别名将通过引用文件的文件ID跟随它。但是,如果您将新文件分配给与旧文件相同的文件路径,则别名现在将指向新文件,因为它更青睐于路径而不是文件ID。
参考资料:http://forums.macworld.com/index.php?/topic/142842-aliases-vs-symbolic-links/

你的文件ID是指inode号码吗?还是这是与文件一起存储的其他内容?不幸的是,糟糕的Unix文件API迫使大多数程序使用原子重命名来保存,而不是原子内容交换(破坏了inode)。如果它不是inode的话,我们如何知道它能够在文件编辑后保持存在?很遗憾,你提供的链接已经无效了。 - Lothar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接