Git Bash Shell无法创建符号链接

ico*_*ast 64 msys msysgit

当我尝试从Git Bash shell创建一个符号链接时,它每次都会失败:

$ ln -s /c/Users/bzisad0/Work testlink
ln: creating symbolic link `testlink' to `/c/Users/bzisad0/Work': Permission denied
Run Code Online (Sandbox Code Playgroud)

除了提供错误消息之外,它唯一能做的就是创建一个名为的空目录(在本例中)testlink.

我没有看到ln可执行文件有任何问题.例如,它由我拥有并标记为可执行文件:

$ which ln
/bin/ln

$ ls -hal /bin/ln
-rwxr-xr-x    1 BZISAD0  Administ      71k Sep  5 11:55 /bin/ln
Run Code Online (Sandbox Code Playgroud)

我也拥有当前目录(~,即/c/Users/bzisad0):

$ ls -dhal .
drwxr-xr-x  115 BZISAD0  Administ      40k Sep  5 12:23 .
Run Code Online (Sandbox Code Playgroud)

我有管理权限,我尝试用"以管理员身份运行"打开Git Bash shell,但这没有任何区别.

我尝试打开W​​indows属性ln.exe并将权限级别设置为"以管理员身份运行此程序",但这没有帮助.

我已经进入Windows中的安全性 - >高级属性,并使自己(而不是管理员组)成为所有者,但这也没有解决任何问题.

我不知所措.我不知道这个错误消息最终是来自lnBash,还是来自Windows,或者我怎么可能缺少权限.我怎样才能深究这一点?

Cam*_*tin 65

尽管非常尴尬,但在MSYSGIT中创建符号链接是可能的.

首先,我们需要确保我们在Windows上.这是一个用于检查以下内容的示例函数:

windows() { [[ -n "$WINDIR" ]]; }
Run Code Online (Sandbox Code Playgroud)

现在,我们不能这样做cmd /C,因为MSYSGIT将使用此参数进行fornicate并将其转换为C:.此外,不要试图使用/K它,它只适用于没有K:驱动器的情况.

因此,虽然它将在程序参数上替换此值,但它不会在heredocs上.我们可以利用这个优势:

if windows; then
    cmd <<< "mklink /D \"${link%/}\" \"${target%/}\"" > /dev/null
else
    ln -s "$target" "$link"
fi
Run Code Online (Sandbox Code Playgroud)

另外:请注意我包含,/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
}
Run Code Online (Sandbox Code Playgroud)

还要注意以下几点:

  1. 我刚写了这篇文章,并在Win7和Ubuntu上进行了简单的测试,如果你是从2015年开始使用Windows 9,请先尝试一下.
  2. NTFS具有重新分析点和连接点.我选择了重新分析点,因为它更像是一个实际的符号链接,适用于文件或目录,但是连接点可以在XP中作为一个可用的解决方案,除了它只是用于目录.
  3. 某些文件系统,特别是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
}
Run Code Online (Sandbox Code Playgroud)

  • 我在2019年,仍然没有Windows 9 :) (4认同)
  • `ln`的参数并不是真正向后,因为它支持多个参数,你可以只列出一堆文件和一个目录作为目的地,它将工作:)另外,正常的顺序它类似于`cp`而且`mv`不那么令人困惑. (3认同)
  • @Wolph看,我没有尝试创建“嵌入式”解决方案真是太好了,哈哈。我不知道您可以通过两个以上的路径来到达ln。 (2认同)
  • 嘿,这是一个“确实”的好答案,感觉就像在挑剔,但是...为什么您必须去颠倒参数顺序?相反,它是“链接目标链接名”。请 (编辑:好的,我意识到这是因为您希望单参数重载让它检查链接名称是否为链接,而unix`ln`不能这样做。点仍然站立。) (2认同)
  • 我来自未来,但我忘了购买Windows 9。 (2认同)

Ton*_*gan 20

解决方法是mklink从Bash 运行.这也允许您创建符号链接或连接.

注意将mklink命令作为单个参数发送给cmd...

cmd  /c "mklink link target"
Run Code Online (Sandbox Code Playgroud)

这是mklink... 的选项

$ 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.
Run Code Online (Sandbox Code Playgroud)

如果你想通过GUI创建链接......我建议使用Link Shell Extension作为Windows资源管理器插件来创建符号链接,硬链接,连接点和卷挂载点.我已经使用它多年了!

如果您的系统C:驱动器上有一个较小的SSD驱动器,则符号链接可以节省生命,并且需要将一些不需要在SSD上的膨胀文件夹符号链接到其他驱动器上.我使用免费的WinDirStat来查找磁盘空间.

  • @CamiloMartin`/c`可以像这样`// c`进行转义,而不是C:盘来获取powershell命令.我还想添加几个例子,说明在git bash shell中使用`mklink`的语法需要什么样,因为我花了一些时间才弄明白.正如Tony所描述的那样引用整个m`mklink`命令将起作用,如下所示:`cmd // c"mklink.\ b_dir\test.txt.\ a_dir\test.txt"`,或者你可以省略引号并逃脱像这样的后退:`cmd // c mklink.\\ b_dir \\ test.txt.\\ a_dir \\ test.txt` (6认同)
  • 普遍来说,MSYSGIT 设法通过使`cmd /c` 无法运行来进一步鸡奸用户,因为`/c` 总是会被替换为`C:`(它的文件系统使用`/c/Windows/... `约定)。幸运的是你可以做`echo -n | cmd /k ...` 如果你没有 `K:` 驱动器。杰出的。 (2认同)
  • 除了出于安全原因需要管理员之外,还有其他原因为什么人们说“Windows 对符号链接的支持很差”?您可以授予用户使用 secpol.msc 创建未提升的符号链接的权限。 (2认同)
  • @JustinDunlap 在 Windows NT/2000 中进行链接的早期实现很差,看起来就像是“黑客”事后的想法(Vista/Win7/8 实现对此进行了清理)。大多数 Windows 开发人员/系统管理员不习惯使用它们,MS 文档几乎从不提及它们。因此,许多 Windows 开发人员在软件解决方案中不考虑它们!我怀疑产品供应商没有考虑许多与链接相关的安全场景,因此 MS 将它们设为“仅限管理员”。在 Linux/OSX/Unix 上,它们是主流/受鼓励的,因此大多数应用程序都经过良好的测试,并有望与它们一起使用。 (2认同)

小智 19

对于我的设置,在Windows 8.1 export MSYS=winsymlinks:nativestrict上安装的Git for Windows 2.11.0可以解决这里所解释的问题:https://github.com/git-for-windows/git/pull/156 启动Git Bash shell非常重要作为管理员,在Windows上,只有管理员才能创建符号链接.因此,为了完成tar -xf工作并创建所需的符号链接:

  1. 以管理员身份运行Git Bash shell
  2. export MSYS=winsymlinks:nativestrict
  3. 运行tar

  • 如果打开 Windows 开发者模式(需要 Windows 10 版本 1703 或更高版本),则无需以管理员身份运行 https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your -开发设备 (6认同)
  • 这才是真正的答案~ (2认同)

Aus*_*ngs 15

我相信lnmsysGit附带的内容只是试图复制它的参数,而不是简化链接.这是因为链接仅在NTFS文件系统上工作(类型),并且MSYS团队不想重新实现ln.

例如,参见http://mingw.5.n7.nabble.com/symbolic-link-to-My-Documents-in-MSYS-td28492.html

  • 你是对的.当我尝试做`ln file1 file2; ln file1 file3; ln file1 file4`我在`ls -l`的输出中看到了有效的链接计数.但请注意,如果您尝试使用`ln:目录不允许使用硬链接,则会失败. (2认同)
  • 是的,这似乎是一个明显的遗漏,没有人可以责怪微软。 (2认同)

Cer*_*vEd 14

\n

授予自己创建符号链接的权限

\n
    \n
  1. 搜索local security policies
  2. \n
  3. Local Policies/User Rights Assignment/Create symbolic links
  4. \n
  5. 花点时间骂Windows。“糟糕的操作系统!糟糕!”
  6. \n
  7. 利润
  8. \n
\n

这授予您创建符号链接的权限。请注意,这将在下次登录时生效。

\n

下一步是弄清楚如何ln配置:

\n
env | grep MSYS\n
Run Code Online (Sandbox Code Playgroud)\n

我们正在寻找MSYS=winsymlink:哪个控制如何ln创建符号链接。

\n

如果该变量不存在,请创建它。请注意,这将覆盖现有的MSYS环境变量。

\n
setx MSYS winsymlinks:nativestrict\n
Run Code Online (Sandbox Code Playgroud)\n

不要

\n

以管理员身份运行 shell 只是为了创建符号链接。

\n

解释

\n

这个错误有点不言自明,但却难以捉摸。

\n

您缺乏运行该命令的适当权限。

\n

为什么?

\n

默认情况下,Windows 仅向管理员授予符号链接创建权限。

\n

Cygwin必须做一些歌舞来绕过 Windows 对符号链接的低劣处理。

\n

为什么?

\n

某事,某事“安全”的东西

\n

\xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf

\n

编辑:

\n

我刚刚意识到 OP 有管理员权限。我留下这个答案,希望对其他人有用。

\n


Oli*_*del 6

扩展Camilo Martin 的答案,因为您需要使用 Windows 10 的 /j 参数开关;否则该调用将仅返回“您没有足够的权限来执行此操作”。

这适用于没有管理员权限的 Git Bash 2.20.1.windows.1/MINGW64 (Windows 10)(如果您可以读取/写入 /old/path 和 /link/path:

original_folder=$(cygpath -w "/old/path")
create_link_new_folder=$(cygpath -w "/link/path")
cmd <<< "mklink /j \"${create_link_new_folder}\" \"${original_folder}\"" > /dev/null
Run Code Online (Sandbox Code Playgroud)


小智 5

对于任何对如何在 Windows 10 Git Bash 2.28.0.0.1 中完成此操作感兴趣的人:

您必须在ln -s命令前面加上前缀,MSYS=..而不是export MSYS=..首先执行,即它只是一个命令:

MSYS=winsymlinks:nativestrict ln -s <TARGET> <NEW_LINK_NAME>
Run Code Online (Sandbox Code Playgroud)