web-dev-qa-db-ja.com

msysでmklinkを使用する

Windowsが* Vista以降*でmklinkシェルコマンドを提供することを理解しています。これをMsys端末から利用したいと思います。どのようにアイデアはありますか?

Msysターミナルでmklinkと入力すると、sh: mklink: command not foundが出力されます。 Msysは、lnと実質的に同じように見える偽のcpユーティリティのみを提供します。

シェルスクリプトを記述してWindowsシェルを開き、その中でmklinkを実行しようとしましたが、シェルスクリプトがcmd /C <instructions>を実行しようとすると、msysはWindowsシェルを現在のターミナルのフォアグラウンドに移動して終了します。命令を実行せずに、そこにあります。

** XPはVistaより大きいが、mklinkユーティリティがなかったため、「大なり記号」とは言いません。*

10
JellicleCat

MSYSbashコマンドラインで直接cmd //c 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.

注:mklinkコマンドと引数は、cmdへの単一の引数として提供する必要があります。コマンド全体をそのように引用します

cmd //c 'mklink link target'

コマンドは通常次のようになることに注意してください

cmd/c'mklink リンクターゲット'

これは、Cygwinやその他のシェル環境、さらには既存のCMDセッションでも機能します。ただし、msysは(Windowsコマンドに対する)コマンドライン引数をマングルしているようで、/cCディスクのルートへのパス名として解釈し、それをc:\に変換します。 //cと入力すると、msysが/cオプションをcmdに渡すことが判明しています。 msysシェルから内部cmdコマンドを実行する方法 を参照してください。

12
ak2

Windowsのネイティブシンボリックリンクを使用できます。これを有効にするには、次の行のコメントを解除します。

MSYS=winsymlinks:nativestrict

mSYS2でbatファイルを開始します。そして、管理者権限でMSYS2を実行します。

6
driftcrow

Windows 10は、Windows設定で開発者モードをオンにしている限り、管理者として実行しなくてもシンボリックリンクをサポートするようになりました。

それが完了すると、ホームディレクトリの.bashrcファイルの1行でlnが正しく機能するようになります。

export MSYS=winsymlinks:nativestrict

(同等の.iniファイルがGit Bashインストールのどこにあるかを理解できませんでした。しかし、そこで環境変数を設定することもおそらく機能します。)

Josh Kelleyによるこの非常に役立つ記事の詳細: https://www.joshkel.com/2018/01/18/symlinks-in-windows/

4
AmeliaBR

MSYS=winsymlinks:nativestrict MSYS2を昇格モードで実行する必要がありますが、私はそれが本当に快適ではありません。

このスクリプトは、呼び出されたときにUACの昇格のみを要求します。もちろん、その場合はスクリプトには役立ちませんが、少なくとも私のニーズには合っています。

  • 〜/ scripts/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"
    
  • 〜/ scripts/wsh/run-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ヘルパーを破棄できます。

4
JimmyZ