尽管很尴尬,但可以在MSYSGIT中创建符号链接。
首先,我们需要确保我们在Windows上。这是检查以下内容的示例函数:
windows() { [[ -n "$WINDIR" ]]; }
现在,我们不能做cmd /C
,因为MSYSGIT会对此参数进行断言并将其转换为C:
。另外,请不要尝试使用/K
,它只有在没有K:
驱动器的情况下才有效。
因此,虽然它将替换程序参数上的该值,但不会在heredocs上使用。我们可以利用此优势:
if windows; then
cmd <<< "mklink /D \"${link%/}\" \"${target%/}\"" > /dev/null
else
ln -s "$target" "$link"
fi
另外:请注意,我/D
之所以加入,是因为我仅对目录符号链接感兴趣;Windows具有这种区别。付出大量的努力,您可以编写一个ln() { ... }
包装Windows API并用作完整的嵌入式解决方案的函数,但这只是作为练习供读者使用。
编辑:作为感谢您接受的答案,这是一个更全面的功能。
# We still need this.
windows() { [[ -n "$WINDIR" ]]; }
# Cross-platform symlink function. With one parameter, it will check
# whether the parameter is a symlink. With two parameters, it will create
# a symlink to a file or directory, with syntax: link $linkname $target
link() {
if [[ -z "$2" ]]; then
# Link-checking mode.
if windows; then
fsutil reparsepoint query "$1" > /dev/null
else
[[ -h "$1" ]]
fi
else
# Link-creation mode.
if windows; then
# Windows needs to be told if it's a directory or not. Infer that.
# Also: note that we convert `/` to `\`. In this case it's necessary.
if [[ -d "$2" ]]; then
cmd <<< "mklink /D \"$1\" \"${2//\//\\}\"" > /dev/null
else
cmd <<< "mklink \"$1\" \"${2//\//\\}\"" > /dev/null
fi
else
# You know what? I think ln's parameters are backwards.
ln -s "$2" "$1"
fi
fi
}
另请注意以下几点:
- 我只是写了这篇文章,并在Win7和Ubuntu上进行了简要测试,如果您来自2015年并使用Windows 9,请先尝试一下。
- NTFS具有重新解析点和结合点。我选择重新解析点是因为它实际上是一个符号链接,并且适用于文件或目录,但是结合点将具有作为XP中可用解决方案的优势,除了它仅适用于目录。
- 某些文件系统(尤其是FAT文件系统)不支持符号链接。现代Windows版本不再支持从它们启动,但是Windows和Linux可以安装它们。
奖励功能:删除链接。
# Remove a link, cross-platform.
rmlink() {
if windows; then
# Again, Windows needs to be told if it's a file or directory.
if [[ -d "$1" ]]; then
rmdir "$1";
else
rm "$1"
fi
else
rm "$1"
fi
}
ln
并没有真正倒退,因为它支持多个参数,您只需列出一堆文件和一个目录作为目标即可使用:)此外,按常规顺序,它类似于cp
并且mv
不易混淆。