为Cygwin启用本机NTFS符号链接

oli*_*bre 49 symlink cygwin ntfs mingw ln

最近的NTFS和Windows实现了符号链接:

  • NTFS连接点可以用作目录符号链接,因为NTFS 3.0(Windows 2000)使用linkdjunction工具.
  • 自Windows Vista使用mklink工具以来,NTFS符号链接也可用作符号链接(用于文件和目录).

但是在Cygwin 1.7(安装在Windows 7上)上,ln -s创建了一个文本文件.

在Cygwin上:

$ ln -s -v target mylink
`mylink' -> `target'
Run Code Online (Sandbox Code Playgroud)

在MinGW(或你最喜欢的编辑):

$ cat mylink
!<symlink>ÿþt a r g e t 
Run Code Online (Sandbox Code Playgroud)

是否有可能告诉Cygwing使用NTFS交接点NTFS符号链接

其他问题:MinGW上有这个吗?

oli*_*bre 79

⸻⸻⸻简答题⸻⸻⸻

定义环境变量:

CYGWIN=winsymlinks:nativestrict
Run Code Online (Sandbox Code Playgroud)

正如mwm所指出的,您可能还必须以管理员身份运行.

⸻⸻⸻答案很长⸻⸻⸻

默认的Cygwin符号链接只是常规文件

默认情况下,Cygwin创建文本文件作为Windows symlink缺陷的解决方法.这些文件不是真正的符号链接.几乎所有Windows程序都不会将这些文件视为符号链接.

最新的Windows版本提供了本机符号链接

最近的NTFS和Windows实现了符号链接:

  • NTFS连接点可以用作目录符号链接,因为NTFS 3.0(Windows 2000)使用linkdjunction工具.
  • 自Windows Vista使用mklink工具以来,NTFS符号链接也可用作符号链接(用于文件和目录).

Cygwin可以创建本机NTFS符号链接

Cygwin文档的简化摘录:

符号链接

[...]

Cygwin可能以多种不同的方式创建符号链接:

  • 默认符号链接是纯文件,包含魔术cookie,后跟链接指向的路径.[...]

  • .lnk如果环境变量CYGWIN [...]设置为包含字符串winsymlinks或,则快捷方式符号链接是Windows [...]创建的winsymlinks:lnk.[...]

  • 原生Windows符号链接仅在Windows Vista/2008及更高版本上创建,并且仅在支持重新分析点的文件系统上创建.由于其奇怪的限制和行为,只有在用户明确要求创建它们时才会创建它们.这是通过将环境变量CYGWIN设置为包含字符串winsymlinks:native或来完成的winsymlinks:nativestrict.[...]

  • 在NFS文件系统上,Cygwin总是创建真正的NFS符号链接.

配置Cygwin

Cygwin用户指南介绍变量CYGWIN和选项winsymlinks:

CYGWIN环境变量用于配置许多全局设置[...].它包含下面列出的选项,以空白字符分隔.[...]

  • [...]
  • [...]
  • [...]
  • [...]
  • winsymlinks:{lnk,native,nativestrict}- 如果设置为just winsymlinkswinsymlinks:lnk,Cygwin将符号链接创建为具有特殊headerand和R/O属性集的Windows快捷方式.

    如果设置为winsymlinks:nativewinsymlinks:nativestrict,Cygwin会在文件系统和支持它们的操作系统版本上创建符号链接作为本机Windows符号链接.如果已知操作系统不支持本机符号链接(Windows XP,Windows Server 2003),则每个会话将生成一条警告消息.

    之间的区别winsymlinks:nativewinsymlinks:nativestrict是这样的:如果文件系统支持本地符号链接和Cygwin无法创建某种原因本地符号链接,它会回落到与创建Cygwin的默认符号连接 winsymlinks:native,同时与winsymlinks:nativestrictsymlink(2)系统调用将立即失败.

CYGWIN=winsymlinks:native
始终创建一个链接,但在目标不存在时使用Cygwin后退

在Cygwin上:

$ export CYGWIN="winsymlinks:native"
$ ln -s -v target mylink
`mylink' -> `target'
$ echo content > target
Run Code Online (Sandbox Code Playgroud)

在MinGW上:

$ cat mylink
content
Run Code Online (Sandbox Code Playgroud)

将符号链接创建为虚拟文件时,使用Windows和Cygwin程序的人可能会遇到问题(当目标丢失时,Cygwin回退)...

CYGWIN=winsymlinks:nativestrict
始终使用本机Windows符号链接但在目标不存在时失败

在Cygwin上:

$ export CYGWIN="winsymlinks:nativestrict"
$ rm -f  a b
$ ln -sv a b
ln: failed to create symbolic link `b': No such file or directory
$ touch    b
$ ln -sv a b
ln: failed to create symbolic link `b': File exists
$ rm b
$ touch a
$ ln -sv a b
`b' -> `a'
Run Code Online (Sandbox Code Playgroud)

因为nativestrict在创建符号链接之前需要目标存在,所以在创建链接时某些命令/脚本可能会失败.

注意:只有管​​理员才能创建本机NT符号链接,因此在Windows UAC下,应使用提升的权限运行Cygwin终端模拟器(mintty)(右键单击快捷方式并选择以管理员身份运行 或设置mintty快捷方式属性,高级→以管理员身份运行).

特别感谢GuriaSpooky的贡献.

  • 我刚刚赞成这个非常有用的答案.我还添加了一个建议的编辑,启用UAC的用户应该使用提升的权限运行mintty,以便能够创建本机NT符号链接. (2认同)
  • 对于MSYS2,取消注释/msys2_shell.bat中的set MSYS = winsymlinks:nativestrict。 (2认同)
  • 关于“nativestrict”含义的信息不准确。引用 [Cygwin 用户指南](https://cygwin.com/cygwin-ug-net/using-cygwinenv.html):*winsymlinks:native 和 winsymlinks:nativestrict 之间的区别是:如果文件系统支持本地符号链接并且由于某种原因,Cygwin 无法创建本地符号链接,它将回退到使用 winsymlinks:native 创建 Cygwin 默认符号链接,而使用 winsymlinks:nativestrict symlink(2) 系统调用将立即失败。* 我个人使用 `nativestrict`并且到目前为止没有任何失败。 (2认同)

Gen*_*sky 7

接受的答案是对的,两个小方注释.

如果您只关心自己在命令行上创建的符号链接,安装cygutils-extra包,它包含一个winln命令,该命令具有相同的语法ln,但创建本机Windows链接.创建一个别名:( alias ln=winln仅适用于交互式shell),或者甚至lnwinln(在shell脚本中工作)替换文件- 但是下次coreutils更新包时可能会被覆盖.

我已经发现当我已经安装了Cygwin时可以使用本机符号链接,并且我自己也添加了一些符号链接.所以在我设置CYGWIN=winsymlinks:native为系统环境变量之后,我想将所有现有的非本地链接转换为本机链接.这就是我做的.

以防万一,先备份整个Cygwin目录.

找到所有符号链接并将列表保存到/links文件: cd /; find . -regextype egrep -regex './(dev|proc|mnt|cygdrive)' -prune -o -type l -print >links

回顾links.tar使用所有链接创建存档:tar c --files-from=links >links.tar

解压缩tar归档:tar x --files-from=links <links.tar 由于现在启用了本机符号链接,因此tar将使用本机符号链接覆盖旧的Cygwin符号链接.

清理: rm -f links links.tar

PS起初我用过CYGWIN=winsymlinks:nativestrict,但后来发现在这种模式下,ln -s target link如果target不存在则失败.相比之下,native将创建一个link指向不存在的Cygwin(非本机)符号链接target- 这与lnUNIX系统上的行为相匹配.在极少数情况下,nativestrict可以破坏某些程序或脚本,例如Gentoo run-crons脚本使用一个锁定文件,这是一个指向正在运行的进程的PID的符号链接.在nativestrict模式下,脚本停止工作,因为它无法再创建锁定文件.注意:run-crons是Gentoo Linux上的crontab帮助程序脚本,添加了对cron.{hourly,daily,weekly,monthly}/dirs的支持,它与Cygwin非常兼容.