development

Git Bash Shell이 ​​심볼릭 링크를 생성하지 못함

big-blog 2020. 12. 4. 19:43
반응형

Git Bash Shell이 ​​심볼릭 링크를 생성하지 못함


Git Bash 셸에서 심볼릭 링크를 만들려고하면 항상 실패합니다.

$ 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 셸을 열어 보았지만 아무런 차이가 없습니다.

Windows 속성을 열고 ln.exe권한 수준을 "관리자 권한으로이 프로그램 실행"으로 설정해 보았지만 도움이되지 않습니다.

Windows의 보안-> 고급 속성으로 이동하여 관리자 그룹이 아닌 나 자신을 소유자로 설정했지만이 방법으로도 문제가 해결되지 않습니다.

나는 헤매고있다. 이 오류 메시지가 궁극적으로 ln, Bash 또는 Windows에서 오는지 또는 어떻게 권한이 부족할 수 있는지 알 수 없습니다. 이 문제를 어떻게 해결할 수 있습니까?


매우 어색 하긴하지만 MSYSGIT에서 심볼릭 링크를 만드는 것은 가능합니다.

먼저 Windows에 있는지 확인해야합니다. 이를 확인하는 예제 함수는 다음과 같습니다.

windows() { [[ -n "$WINDIR" ]]; }

이제 우리는 할 수 없습니다. cmd /CMSYSGIT가이 주장으로 음행하고 그것을 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
}

또한 몇 가지 사항에 유의하십시오.

  1. 방금 작성하고 Win7 및 Ubuntu에서 간단히 테스트했습니다. 2015 년에서 Windows 9를 사용하는 경우 먼저 시도해보세요.
  2. NTFS has reparse points and junction points. I chose reparse points because it's more of an actual symlink and works for files or directories, but junction points would have the benefit of being an usable solution in XP, except it's just for directories.
  3. Some filesystems, the FAT ones in particular, do not support symlinks. Modern Windows versions do not support booting from them anymore, but Windows and Linux can mount them.

Bonus function: remove a link.

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

A workaround is to run mklink from Bash. This also allows you to create either a Symlink or a Junction.

Take care to send the mklink command as a single argument to cmd ...

cmd  /c "mklink link target"

Here's the options for 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.

If you want to create links via a GUI instead ... I recommend Link Shell Extension that is a Windows Explorer plugin for creating Symbolic Links, Hardlinks, Junctions, and Volume Mountpoints. I've been using it for years!

Symlinks can be a life saver if you have a smaller SSD drive on your system C: drive and need to symlink some bloated folders that don't need to be on SSD off onto other drives. I use the free WinDirStat to find the disk space hogs.


For my setup, that is Git for Windows 2.11.0 installed on Windows 8.1 export MSYS=winsymlinks:nativestrict does the trick as explained here: https://github.com/git-for-windows/git/pull/156 It's important to launch the Git Bash shell as administrator as on Windows only administrators could create the symbolic links. So, in order to make tar -xf work and create the required symlinks:

  1. Run Git Bash shell as an administrator
  2. Run export MSYS=winsymlinks:nativestrict
  3. Run tar

I believe that the ln that shipped with msysGit simply tries to copy its arguments, rather than fiddle with links. This is because links only work (sort of) on NTFS filesystems, and the MSYS team didn't want to reimplement ln.

See, for example, http://mingw.5.n7.nabble.com/symbolic-link-to-My-Documents-in-MSYS-td28492.html


Since this is one of the top links that come up when searching for creating symlinks in Msys or git bash, I found the answer was to add set MSYS=winsymlinks:native when calling git-cmd.exe (I run ConEmu) or uncomment the same line in the msys2_shell.bat


Extending Camilo Martin's anwser as you need to use the /j parameter switch for Windows 10; otherwise the call will just return "You do not have sufficient privilege to perform this operation."

This works for git bash 2.20.1.windows.1/MINGW64 (Windows 10) without Admin rights (if you can read/write both /old/path and /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

I prefer Powershell to CMD, and thought i'd share the powershell version of this.

In my case it consists of making symlinks linking ~/.$file to ~/dotfiles/$file, for dotfile configurations. I put this inside a .sh script and ran it with git-bash:

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

참고URL : https://stackoverflow.com/questions/18641864/git-bash-shell-fails-to-create-symbolic-links

반응형