Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2912

WSLからWindowsのexeを拡張子なしで実行する

$
0
0

Windows Subsystem for LinuxからはWindowsのアプリケーションを直接実行する事ができます。PATHが通っていれば単純に
$ explorer.exe
とすればエクスプローラーが立ち上がります。しかし、必ず拡張子まで含める必要があります。
コマンドプロンプトから実行するときのように、拡張子を省略して実行する方法です。

コマンドプロンプトで拡張子を省略できる理由

そもそも、なぜWindowsのコマンドプロンプトやPowerShellでは.exeや.cmdなどの拡張子を省略できるのかというと、コマンドが見つからない場合、PATHEXTという環境変数から拡張子のリストを読み込んで検索しているからです。この値はコマンドプロンプトから確認でき、筆者の環境では
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
となっていました。
これと同じことをすればできそうです。

実装

Windows側の設定

WSLと環境変数を共有するにはWSLENVという環境変数を用います。
コントロールパネル等でPATHEXTをWSLENVに追加するだけです。
pathext.png

WSL側の設定

コマンドが見つからなかった場合、PATHEXTから拡張子を取得して再検索するため、command_not_found_handleを利用します。すでに定義済みの場合は処理を挿入して再定義します。

.bashrc
if declare-f command_not_found_handle >/dev/null 2>&1;then
  eval'command_not_found_handle() {
    local ext
    for ext in ${PATHEXT//;/ }; do
      if which "$1$ext" >/dev/null 2>&1; then
        "$1$ext" "${@:2}"
        return $?
      fi
    done
    '"$(declare-f command_not_found_handle|tail -n +2)"'
  }'else
  command_not_found_handle(){local ext
    for ext in${PATHEXT//;/ };do
      if which "$1$ext">/dev/null 2>&1;then"$1$ext""${@:2}"return$?fi
    done
    printf"%s: command not found\n""$1" 1>&2
    return 127
  }fi

実行

余談ですが、NTFSはファイル名の大文字小文字を区別しないため、コマンド名の大文字小文字が違っていても実行できます。
ubuntu.png

おわりに

PATHが通っていれば補完が効くし、あまり意味はない気もする。

追記(2020/05/25 19:53)

いろいろといじっていたら短くなったのでそれも載せておきます

.bashrc
eval'command_not_found_handle() {
  local ext
  for ext in ${PATHEXT//;/ }; do
    if which "$1$ext" >/dev/null 2>&1; then
      "$1$ext" "${@:2}"
      return $?
    fi
  done
  '"$(declare-f command_not_found_handle|tail -n +2)"'
  printf "%s: command not found\n" "$1" 1>&2
  return 127
}'

参考文献

Linux との Windows の相互運用性


Viewing all articles
Browse latest Browse all 2912

Trending Articles