Git Bash Shell无法创建符号链接

时间:2013-09-05 16:50:52

标签: msysgit msys

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

$ ln -s /c/Users/bzisad0/Work testlink
ln: creating symbolic link `testlink' to `/c/Users/bzisad0/Work': Permission denied

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

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

$ which ln
/bin/ln

$ ls -hal /bin/ln
-rwxr-xr-x    1 BZISAD0  Administ      71k Sep  5 11:55 /bin/ln

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

$ ls -dhal .
drwxr-xr-x  115 BZISAD0  Administ      40k Sep  5 12:23 .

我有管理权限,并且我尝试使用“以管理员身份运行”打开Git Bash shell,但这没有任何区别。

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

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

我很茫然。我不知道这个错误消息最终是来自ln,来自Bash,还是来自Windows,或者我怎么可能缺少权限。我怎样才能深究这一点?

9 个答案:

答案 0 :(得分:60)

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

首先,我们需要确保我们在Windows上。这是检查:

的示例函数
windows() { [[ -n "$WINDIR" ]]; }

现在,我们无法cmd /C,因为MSYSGIT将使用此参数进行fornicate并将其转换为C:。此外,不要试图使用/K,只有在您没有K:驱动器的情况下才有效。

因此,虽然它会在程序参数上替换此值,但它不会对heredocs产生影响。我们可以利用这个优势:

if windows; then
    cmd <<< "mklink /D \"${link%/}\" \"${target%/}\"" > /dev/null
else
    ln -s "$target" "$link"
fi

另外:请注意我包含/D,因为我只对目录符号链接感兴趣; Windows有这种区别。通过大量的努力,您可以编写一个包含Windows API的ln() { ... }函数,并将其作为一个完整的插件解决方案,但这仍然是读者的练习。


编辑:感谢您接受的答案,这是一个更全面的功能。

# 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
}

还要注意以下几点:

  1. 我刚刚写了这篇文章并在Win7和Ubuntu上进行了简单的测试,如果您从2015年开始使用Windows 9,请先尝试一下。
  2. NTFS具有重新分析点和连接点。我选择了重新分析点,因为它更像是一个真正的符号链接,适用于文件或目录,但是连接点可以成为XP中可用的解决方案,除了它只是用于目录。
  3. 某些文件系统,特别是FAT文件系统,不支持符号链接。现代Windows版本不再支持从它们启动,但Windows和Linux可以安装它们。
  4. 奖金功能:删除链接。

    # 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
    }
    

答案 1 :(得分:17)

解决方法是从Bash运行mklink。这也允许您创建Symlink or a Junction

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

cmd  /c "mklink link target"

这里是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.

如果您想通过GUI创建链接......我建议Link Shell Extension是用于创建符号链接,硬链接,连接和卷装入点的Windows资源管理器插件。我已经使用它多年了!

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

答案 2 :(得分:15)

我相信msysGit附带的ln只是试图复制其参数,而不是弄乱链接。这是因为链接仅在NTFS文件系统上工作(类型),并且MSYS团队不想重新实现ln。

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

答案 3 :(得分:14)

对于我的设置,即在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非常重要,只有管理员可以创建符号链接。 因此,为了使tar -xf工作并创建所需的符号链接:

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

答案 4 :(得分:2)

由于这是在Msys或git bash中搜索创建符号链接时出现的顶级链接之一,我发现答案是添加 调用set MSYS=winsymlinks:native(我运行ConEmu)或取消注释git-cmd.exe

中的同一行时msys2_shell.bat

答案 5 :(得分:1)

与CMD相比,我更喜欢Powershell,并认为我会分享它的Powershell版本。

在我的情况下,它包括将〜/.$ file链接到〜/ dotfiles / $ file的符号链接, 用于dotfile配置。我将其放在.sh脚本中,并使用git-bash运行:

powershell New-Item -ItemType SymbolicLink\
    -Path \$Home/.$file\
    -Target \$Home/dotfiles/$file

答案 6 :(得分:1)

在Windows 10上需要使用/ j参数开关来扩展Camilo Martin的anwser;否则,呼叫将仅返回“您没有足够的权限执行此操作。”

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

from Crypto.Protocol.KDF import PBKDF2
from Crypto.PublicKey import RSA

password = "swordfish"   # for testing
salt = "yourAppName"     # replace with random salt if you can store one

master_key = PBKDF2(password, salt, count=10000)  # bigger count = better

def my_rand(n):
    # kluge: use PBKDF2 with count=1 and incrementing salt as deterministic PRNG
    my_rand.counter += 1
    return PBKDF2(master_key, "my_rand:%d" % my_rand.counter, dkLen=n, count=1)

my_rand.counter = 0
RSA_key = RSA.generate(2048, randfunc=my_rand)

答案 7 :(得分:1)

Grant yourself privileges' to create symlinks

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

这使您可以创建符号链接。注意,这在下次登录时生效。

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

env | grep MSYS

我们正在寻找的是 MSYS=winsymlink:,它控制 ln 如何创建符号链接。

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

setx MSYS winsymlinks:nativestrict

不要

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

说明

这个错误是不言自明的,但又难以捉摸。

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

为什么?

默认情况下,windows 只授予管理员创建符号链接的权限?

CYGWIN 必须做一首歌曲和舞蹈来绕过 Windows 对符号链接的低级处理。

为什么?

Something, something "secturity"

¯\_(ツ)_/¯

编辑:

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

答案 8 :(得分:0)

对于对如何在Windows 10 Git Bash 2.28.0.0.1中完成此操作感兴趣的任何人, 您必须在ln -s前面加上MSYS=..前缀,而不是首先执行export MSYS=..,也就是说,它只是一个命令:

 MSYS=winsymlinks:nativestrict ln -s <TARGET> <NEW_LINK_NAME>