我知道 Vista 之后的 Windows 提供了mklink
shell 命令。我想从 Msys 终端使用它。有什么想法吗?
当我mklink
在 msys 终端上输入时,它输出sh: mklink: command not found
。Msys 只提供了一个虚假的ln
实用程序,它看起来与 实际上相同cp
。
我尝试编写一个 shell 脚本来打开 Windows shell 并mklink
在其中运行,但是当我的 shell 脚本尝试执行时cmd /C <instructions>
,msys 会将 Windows shell 带到当前终端的前台并将其留在那里,而不运行指令。
答案1
Windows 10 现在支持符号链接,无需以管理员身份运行,只要您在 Windows 设置中打开开发人员模式。
一旦完成后,您就可以使用主目录中的文件ln
中一行来正常工作!.bashrc
export MSYS=winsymlinks:nativestrict
(我无法弄清楚 Git Bash 安装中等效的 .ini 文件在哪里。但在那里设置环境变量可能也有效。)
Josh Kelley 的这篇非常有用的文章中有更多详细信息: https://www.joshkel.com/2018/01/18/symlinks-in-windows/
答案2
cmd //c mklink
直接在 MSYS bash 命令行上使用就可以了。
$ cmd //c mklink
Creates a symbolic link.
MKLINK [[/D] | [/H] | [/J]] Link Target
/D Creates a directory symbolic link. Default is a file
symbolic link.
/H Creates a hard link instead of a symbolic link.
/J Creates a Directory Junction.
Link specifies the new symbolic link name.
Target specifies the path (relative or absolute) that the new link
refers to.
注意:mklink 命令和参数需要作为 cmd 的单个参数提供。像这样引用整个命令
cmd //c 'mklink link target'
请注意,命令通常是
cmd /c 'mklink链接目标‘
这可以在 Cygwin 和其他 shell 环境中工作,甚至可以在现有的 CMD 会话中工作。但是,msys 似乎会破坏命令行参数(对于 Windows 命令),它会将其解释/c
为磁盘根目录的路径名C
,并将其转换为c:\
。输入//c
已发现会导致 msys 将/c
选项传递给cmd
。请参阅如何从 msys shell 运行内部 cmd 命令?
答案3
您可以使用 Windows 原生符号链接。要启用它,请取消注释以下行:
MSYS=winsymlinks:nativestrict
在 MSYS2 中启动 bat 文件。并以管理员权限运行 MSYS2。
答案4
MSYS=winsymlinks:nativestrict
要求您以提升模式运行 MSYS2,我对此确实感到不舒服。
此脚本仅在调用时提示 UAC 提升,当然它对于脚本编写来说没有用,但至少它满足我的需要:
〜/脚本/sh/msys2-ln.sh:
#!/bin/sh if [ "$#" -eq 2 -a "$1" == "-s" ]; then TARGET="$2" LINK=$(basename "$TARGET") elif [ "$#" -eq 3 -a "$1" == "-s" ]; then TARGET="$2" LINK="$3" else echo "this weak implementation only supports \`ln -s\`" exit fi if [ -d "$TARGET" ]; then MKLINK_OPTS="//d" fi TARGET=$(cygpath -w -a "$TARGET") LINK=$(cygpath -w -a "$LINK") echo "$TARGET" echo "$LINK" cscript //nologo ~/scripts/wsh/run-elevated.js \ cmd //c mklink $MKLINK_OPTS "$LINK" "$TARGET"
〜/脚本/ wsh /运行-elevated.js
var args = WScript.Arguments; if(args.length == 0){ WScript.Echo("nothing to run"); WScript.Quit(0); } var quoted_args = []; for(var i = 1; i < args.length; ++i){ var arg = args(i); // it's a callable, not array like if(arg.indexOf(" ") != -1){ arg = "\"" + arg + "\""; } quoted_args.push(arg); } var SHAPP = WScript.CreateObject("shell.application"); SHAPP.ShellExecute(args(0), quoted_args.join(" "), "", "runas", 1);
~/.bashrc
# workaround for MSYS2's awkward ln if [ $- == *i* -a ! -z $MSYSTEM ]; then alias ln='~/scripts/sh/msys2-ln.sh' alias ecmd='powershell "start-process cmd.exe \"/k cd /d $(pwd -W)\" -verb runas"' fi
附加的 ecmd 别名在当前目录中启动提升的 cmd,有时可能会有用,它也可以作为通过 powershell 获取 UAC 提升的示例,如果有人知道如何正确摆脱这个问题,我们就可以抛弃那个 WSH 助手。