LoginSignup
4
2

More than 5 years have passed since last update.

Windows で %PATHEXT% を利用した which コマンド

Posted at

Windows では、実行可能ファイルの拡張子が環境変数 PATHEXT に入っているので、PATHPATHEXT を利用すれば which コマンドが作れる。

PATHEXT について

PATHEXT にはセミコロン区切りで実行可能ファイルの拡張子が入っている。

PATHEXT
C:\Users\foo>echo %PATHEXT%
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

拡張子は格納順に優先度が高いため、上記の場合、foo.exefoo.bat が同じフォルダに存在する場合、foo を実行すると foo.exe が実行される。

which コマンドの実装

インタフェースは Linux の which コマンドと同様にする。

SYNOPSIS
  which [-a] filename

OPTIONS
  -a  見つかった全ての実行可能ファイルを表示する。

EXIT STATUS
  0   指定した全てのコマンドが見つかった
  1   指定したいずれかのコマンドが見つからなかった
  2   不正なオプションを指定した

-a オプションを指定すると、環境変数 PATH に存在する全ての実行可能ファイルを出力する。また、複数のコマンドを同時に指定することもできる。

以下の内容の which.cmd をパスの通ったフォルダに置く。

which.cmd
@echo offsetlocal  set ALL=0  set NOTFOUND=0  set OPT=%~1  if "%OPT%"=="" exit /b  if "%OPT%"=="-a" (    set ALL=1    shift  ) else if "%OPT:~0,1%"=="-" (    echo Illegal option %OPT%    echo Usage: which [-a] args    exit /b 2  )  if "%~1"=="" exit /b  :LOOP    set COMMANDS=;%PATHEXT%    call set COMMANDS=%%COMMANDS:;= %~1%%    set COMMANDS=(%COMMANDS:~1%)    for %%i in %COMMANDS% do (      if exist %%~$PATH:i (        echo %%~$PATH:i        if %ALL%==0 goto :NEXT      )    )    set NOTFOUND=1    :NEXT    shift    if not "%~1"=="" goto LOOP  if %NOTFOUND%==1 exit /b 1endlocal```

```cmd:実行結果
C:\Users\foo>which notepad ipconfig
C:\Windows\System32\notepad.exe
C:\Windows\System32\ipconfig.exe

実装方法

実装のポイントは、セミコロンで区切られた PATHEXT の各拡張子を取り出す方法。通常のプログラミング言語のように、".exe;.bat".split(";") などとして、拡張子をリストに分割できそうにないので、別の方法を考える。

forコマンド
C:\Users\foo> for %i in (foo.exe foo.bat) do echo %i
foo.exe
foo.bat

のように、 for コマンドを使用することでループは実現できるので、(foo.exe foo.bat) のような文字列を作ればよい。

which.cmd
set COMMANDS=;%PATHEXT%
=> ";.EXE;.BAT"
call set COMMANDS=%%COMMANDS:;= %~1%%
=> " foo.EXE .foo.BAT"
set COMMANDS=(%COMMANDS:~1%)
=> "(foo.EXE foo.BAT)"

で、変数 COMMANDS に、for で回すための文字列を作っている。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2