web-dev-qa-db-ja.com

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シェルを開こうとしましたが、違いはありません。

ln.exeのWindowsプロパティを開き、特権レベルを「このプログラムを管理者として実行する」に設定しようとしましたが、それは役に立ちません。

Windowsの[セキュリティ]-> [詳細設定]プロパティに移動し、(管理者グループではなく)自分を所有者にしましたが、それでも何も修正されません。

私は迷っています。このエラーメッセージが最終的にlnから、Bashから、またはWindowsから来ているのかどうか、または許可が不足している可能性があるかどうかはわかりません。どうすればこの最下部に到達できますか?

60
iconoclast

非常に厄介ではありますが、MSYSGITでシンボリックリンクを作成することは可能です。

まず、Windows上にいることを確認する必要があります。これを確認する関数の例を次に示します。

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

現在、MSYSGITはこの引数を使用して、_cmd /C_に変換するため、_C:_を実行できません。また、_/K_を使用しようとしないでください。_K:_ドライブがない場合にのみ機能します。

したがって、プログラムの引数でこの値を置き換えますが、ヒアドキュメントでは置き換えません。これを活用して、次のことができます。

_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はそれらをマウントできます。

ボーナス機能:リンクを削除します。

_# 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
}
_
62
Camilo Martin

回避策は、Bashからmklinkを実行することです。これにより、 シンボリックリンクまたはジャンクション を作成することもできます。

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にある必要のない肥大化したフォルダーを他のドライブにシンボリックリンクする必要がある場合、Symlinksは命を救うことができます。無料の WinDirStat を使用して、ディスク領域を占有します。

17
Tony O'Hagan

私のセットアップでは、Windows 8.1にインストールされているGit for Windows 2.11.0 export MSYS=winsymlinks:nativestrictは、ここで説明されているトリックを実行します。 https://github.com/git-for-windows/git/pull/156 起動することが重要です管理者としてのGit Bashシェルは、Windows上の管理者のみがシンボリックリンクを作成できます。したがって、tar -xf動作し、必要なシンボリックリンクを作成します。

  1. Git Bash Shellを管理者として実行する
  2. 実行export MSYS=winsymlinks:nativestrict
  3. Tarを実行
16

MsysGitに同梱されているlnは、リンクをいじるのではなく、単に引数をコピーしようとするだけだと思います。これは、リンクがNTFSファイルシステムでのみ機能するため、MSYSチームはlnを再実装したくなかったためです。

たとえば、 http://mingw.5.n7.nabble.com/symbolic-link-to-My-Documents-in-MSYS-td28492.html を参照してください

15
Austin Hastings

Windows 10で/ jパラメータースイッチを使用する必要がある場合のCamilo Martinのanwserの拡張。そうでない場合、呼び出しは「この操作を実行するための十分な特権がありません」を返すだけです。

これは、管理者権限のない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
2
Oliver Zendel

これは、Msysまたはgit bashでシンボリックリンクの作成を検索するときに表示されるトップリンクの1つであるため、set MSYS=winsymlinks:native(ConEmuを実行)を呼び出すときにgit-cmd.exeを追加するか、同じコメントを外すmsys2_Shell.batの行

2
swee lim

私はCMDよりPowershellを好むので、このPowershellバージョンを共有すると思いました。

私の場合、ドットファイル設定のために〜/.$ fileを〜/ dotfiles/$ fileにリンクするシンボリックリンクを作成します。これを.shスクリプトに入れて、git-bashで実行しました。

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