为 Cygwin 启用本机 NTFS 符号链接
Posted
技术标签:
【中文标题】为 Cygwin 启用本机 NTFS 符号链接【英文标题】:Enable native NTFS symbolic links for Cygwin 【发布时间】:2013-09-10 08:10:34 【问题描述】:最近的 NTFS 和 Windows 实现了符号链接:
从 NTFS 3.0 (Windows 2000) 开始,NTFS junction point 可以用作目录符号链接,使用linkd
或 junction
工具。
NTFS symbolic link 也可以用作符号链接(用于文件和目录),因为 Windows Vista 使用 mklink
工具。
但在 Cygwin 1.7(安装在 Windows 7 上)上,ln -s
会创建一个文本文件。
在 Cygwin 上:
$ ln -s -v target mylink
`mylink' -> `target'
在 MinGW(或您最喜欢的编辑器)上:
$ cat mylink
!<symlink>ÿþt a r g e t
是否可以告诉 Cygwing 使用NTFS junction point 或NTFS symbolic link?
其他问题:MinGW 是否提供此功能?
【问题讨论】:
【参考方案1】:⸻⸻⸻ 简答 ⸻⸻⸻
定义环境变量:
CYGWIN=winsymlinks:nativestrict
正如mwm 所指出的,您可能还必须以管理员身份运行bash。
⸻⸻⸻ 长答案 ⸻⸻⸻
默认 Cygwin 符号链接只是常规文件
默认情况下Cygwin 创建文本文件作为 Windows 符号链接缺陷的解决方法。 这些文件并不是真正的symlinks。 几乎所有 Windows 程序都不将这些文件视为符号链接。
本机符号链接在最新的 Windows 版本中可用
最近的 NTFS 和 Windows 实现了符号链接:
NTFS junction point 可用作目录符号链接 从 NTFS 3.0 (Windows 2000) 开始使用linkd
或 junction
工具。
NTFS symbolic link 也可以用作符号链接
(对于文件和目录)从 Windows Vista 开始使用 mklink
工具。
Cygwin 可以创建原生NTFS symlinks
Cygwin documentation 的简化摘录:
符号链接
[...]
Cygwin 可能以多种不同方式创建符号链接:
默认符号链接是包含魔法 cookie 的普通文件 后跟链接指向的路径。 [...]
快捷方式的符号链接是 Windows
.lnk
[...] 创建的 如果环境变量 CYGWIN [...] 设置为包含 字符串winsymlinks
或winsymlinks:lnk
。 [...]本机 Windows 符号链接仅在 Windows Vista/2008 及更高版本上创建, 并且仅在支持重解析点的文件系统上。 由于它们奇怪的限制和行为,它们只被创建 如果用户明确要求创建它们。 这是通过设置环境变量 CYGWIN 包含字符串
winsymlinks:native
或winsymlinks:nativestrict
。 [...]在 NFS 文件系统上,Cygwin 总是创建真正的 NFS 符号链接。
配置 Cygwin
Cygwin User's Guide 表示变量CYGWIN
和选项winsymlinks
:
[...] [...] [...] [...]
CYGWIN
环境变量用于配置许多全局设置 [...]。 它包含下面列出的选项,以空白字符分隔。 [...]
winsymlinks:lnk,native,nativestrict
- 如果设置为winsymlinks
或winsymlinks:lnk
,Cygwin 会创建符号链接 作为带有特殊标题和 R/O 属性集的 Windows 快捷方式。如果设置为
winsymlinks:native
或winsymlinks:nativestrict
, Cygwin 在文件系统上创建符号链接作为本机 Windows 符号链接 和支持它们的操作系统版本。如果已知操作系统不支持 本机符号链接(Windows XP、Windows Server 2003)、警告消息 每个会话生成一次。
winsymlinks:native
和winsymlinks:nativestrict
是这样的:如果文件系统支持本机 符号链接和 Cygwin 出于某种原因无法创建本机符号链接, 它将回退到创建 Cygwin 默认符号链接winsymlinks:native
,而winsymlinks:nativestrict
symlink(2)
系统调用将立即失败。
CYGWIN=winsymlinks:native
总是创建一个链接,但在目标不存在时使用 Cygwin 回退
在 Cygwin 上:
$ export CYGWIN="winsymlinks:native"
$ ln -s -v target mylink
`mylink' -> `target'
$ echo content > target
在 MinGW 上:
$ cat mylink
content
同时使用 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'
由于 nativestrict
要求目标在创建符号链接之前存在,因此某些命令/脚本在创建链接时可能会失败。
注意:只有管理员才能创建本地 NT 符号链接 所以在 Windows UAC 下,Cygwin 终端仿真器 (mintty) 应该以提升的权限运行 (右键单击快捷方式并选择以管理员身份运行 或设置 mintty 快捷方式属性,高级 → 以管理员身份运行)。
特别感谢 Guria 和 Spooky 的贡献。
【讨论】:
我刚刚对这个内容丰富的答案投了赞成票。我还添加了一个建议的编辑,即启用了 UAC 的用户应该以提升的权限运行 mintty,以便能够创建本机 NT 符号链接。 export CYGWIN="winsymlinks:nativestrict" 在 Windows 8 中为我工作 对于 MSYS2,在/msys2_shell.bat
中取消注释 set MSYS=winsymlinks:nativestrict
。
这在我的系统上不起作用。唯一的方法是通过cmd /c ...
关于nativestrict
含义的信息不准确。引用Cygwin User Guide: winsymlinks:native 和 winsymlinks:nativestrict 之间的区别是:如果文件系统支持本机符号链接并且 Cygwin 由于某种原因无法创建本机符号链接,它将回退到创建 Cygwin 默认符号链接winsymlinks:native,而使用 winsymlinks:nativestrict 时,symlink(2) 系统调用将立即失败。 我个人使用的是nativestrict
,到目前为止没有任何失败。【参考方案2】:
公认的答案是正确的,两个小注解。
如果您只关心自己在命令行上创建的符号链接,请安装 cygutils-extra
软件包,它包含一个 winln
命令,其语法与 ln
相同,但会创建本机 Windows 链接。创建一个别名:alias ln=winln
(仅适用于交互式 shell),或者甚至将 ln
文件替换为 winln
(也适用于 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
附:起初我使用CYGWIN=winsymlinks:nativestrict
,但后来我发现在这种模式下,如果target
不存在,ln -s target link
会失败。相比之下,native
将创建一个 Cygwin(非本地)符号链接 link
指向不存在的 target
- 这与 UNIX 系统上的 ln
的行为相匹配。在极少数情况下,nativestrict
可能会破坏某些程序或脚本,例如 Gentoo run-crons
脚本使用锁定文件,它是指向正在运行进程的 PID 的符号链接。在nativestrict
模式下,脚本停止工作,因为它无法再创建锁定文件。注意:run-crons
是 Gentoo Linux 上的一个 crontab 帮助脚本,增加了对cron.hourly,daily,weekly,monthly/
dirs 的支持,它与 Cygwin 配合得很好。
【讨论】:
虽然这确实有效(首先我们需要editrights -u $USER -a SeCreateSymbolicLinkPrivilege
),但这种符号链接与mklink
创建的符号链接并不完全相同。基本上 CMD 的 mklink
不尊重该权限设置,而 CMD 的 mklink
正确地将文件类型设置为“.symlink”,而 winln
不这样做。效果基本上是,当由 Windows Explorer 和 Cygwin 的 ls
呈现时,符号链接实际上看起来像符号链接,当使用 mklink
时,他们知道它是 Windows 符号链接。
您是在谈论 winln 还是 tar 使用 CYGWIN=winsymlinks:nativestrict
创建的符号链接。我并没有真正使用 winln,所以无法发表评论,但在后一种情况下,由 Cygwin 创建的符号链接看起来像 Explorer 等中的符号链接。
我说的是winln
。刚才试了一下。 CYGWIN=winsymlinks:nativestrict
以前对我完全不起作用。
好的,我刚刚试过mklink fzf-mklink fzf
、winln -s fzf fzf-winln
、ln -s fzf fzf-ln
(设置了winsymlinks:nativestrict)。创建的所有三个链接都显示为.symlink
,在资源管理器中键入并指向同一个文件 fzf。我能看到的唯一区别是 mklink 创建的链接归 BUILTIN\Administrators
所有,而 Cygwin 创建的两个链接都归 Alpha\root
(当前用户)所有。 CYGWIN=winsymlinks:nativestrict
现在是否适合您?如果不是,您如何定义该变量?【参考方案3】:
因为@olibre 的回答对我不起作用。我刚刚创建了一个 shell 函数。
: '
mklink - Create NTFS (Windows) links that is usable by Windows and Cygwin
Usage: mklink [/D | /H | /J] <link-path> <target-path>
Options:
/D Directory Symbolic Link
/H Hardlink
/J Directory Junction (you should prefer /D)
With no options, it creates a NTFS file symlink.
'
mklink ()
if [ "$#" -ge "3" ]; then
cmd /c mklink "$1" "$(cygpath --windows --absolute "$2")" "$(cygpath --windows --absolute "$3")"
else
cmd /c mklink "$(cygpath --windows --absolute "$1")" "$(cygpath --windows --absolute "$2")"
fi
请注意,您需要管理员权限(对于 Cygwin)才能正常运行上述内容。
请注意,我不知道符号链接到绝对路径与使用 CMD 的 mklink
符号链接到相对路径之间是否有任何区别。在 Linux 上,如果您决定移动符号链接或移动目标文件,或同时移动两者,这两种行为会有所不同。
【讨论】:
不错的选择 :-) 请提供您已在其上测试过您的脚本以帮助其他 SO 读者的 Windows 版本(可能还有 Cygwin/MinGW)。谢谢;-)cygutils-extra
包包含一个winln
命令,该命令提供类似ln
的语法来创建Windows 本地链接。
啊,这个工具很棒。它甚至建议:editrights -a SeCreateSymbolicLinkPrivilege -a $YOUR_USER
.
但实际上应该是editrights -u $USER -a SeCreateSymbolicLinkPrivilege
。
由于我是管理员,所以没有向我建议。【参考方案4】:
我想最简单的方法是
从本地组策略编辑器授予 SeCreateSymbolicLinkPrivilege(gpedit.msc,默认在路径上,非家庭版本)
在路径(批处理或 bash)上创建名为 ln
的脚本,实现
类似于上述的shell函数
利润
【讨论】:
【参考方案5】:您可能正在寻找一种方法来使用 MSYS 到达目录树中的另一个目的地。有一种方法。您应该创建一个包含以下行的 shell 脚本(“*.sh”文件):
cd "/drive_letter/SubCatalogue/SubFolder/..."
【讨论】:
您好 FreeCodeRide。感谢您的想法,但我不确定是否理解。请举个例子。例如,您可以创建一个目标文件,然后创建一个链接到该目标文件的文件……干杯;)以上是关于为 Cygwin 启用本机 NTFS 符号链接的主要内容,如果未能解决你的问题,请参考以下文章