Which ‘which’ is which?

The ‘which’ utility is one of those really useful commands that never seems to cross the bridge from Unix to Windows. The CMD.EXE special %$PATH:f syntax seems to promise some relief, but of course it’s never that simple – I at least want to type “which foo” rather than “which foo.exe”.

So here’s which.cmd – a script that tries to DWIW.

Note that this script is wrong in one key detail: it searches inside-out. That is, any “foo.COM” will take precedence over any “foo.EXE” even if the .exe version occurs earlier in the PATH.

@echo off
REM Copyright (c) 2010, Austin Hastings.
REM This file may be used for any purpose without restriction.

REM NOTE: This script does not handle multiple entries with different
REM extensions correctly. It returns the first matching EXTENSION, rather
REM than returning the first DIRECTORY with any EXTENSION.

REM Analogous to unix 'which' command, look for a matching runnable
REM in %PATH% and print the location.

SETLOCAL ENABLEDELAYEDEXPANSION

set check_extensions= ;%PATHEXT%

:ext_loop
if "%check_extensions%" == "" goto done

for /F "tokens=1* delims=;" %%E in ( "%check_extensions%" ) do (
	set check_extensions=%%F
	set target=%1%%E
	for %%W in (  !target! ) do set answer=%%~f$PATH:W
)

if "%answer%" == "" goto ext_loop

:done
if "%answer%" == "" goto not_found

@echo %answer%
goto exit

:not_found
@echo No runnable matching '%1' was found.

:exit

Leave a Reply