80

I'm writing a bat script in which I invoke a program (such as javac). For simplicity, I want to check if the command exists before I run it. i.e. If the command exists in PATH.

For example,

if (my_command.exe is a recognized command) then (
  my_command.exe my_args
) else (
  REM Output was probably "'my_command.exe' is not recognized as an internal or external command, operable program or batch file."
  REM Do not run my_command.exe
)

What's the best way to do this in Windows?

Joey
  • 41,098
user46097
  • 841

11 Answers11

95
WHERE mycommand
IF %ERRORLEVEL% NEQ 0 ECHO mycommand wasn't found 
30

The code below should always execute cleanly with no garbage output.

javac -version >nul 2>&1 && (
    echo found javac
) || (
    echo fail
)

Output:

found javac

The same code as a one-liner:

javaz -version >nul 2>&1 && ( echo found javac ) || ( echo fail )

Output:

fail

Note that the order of && and || seems to matter. Also, the command whose existence you are testing for needs to return with an errorlevel <= 0 for this to work. Hopefully the command has /? or --help arguments or, as with java, a version info command.

ngreen
  • 401
  • 4
  • 5
11

The easiest way is to simply run the command, but that has other problems, of course, since maybe you don't want to have a random process started.

for %%x in (my_command.exe) do if not [%%~$PATH:x]==[] set MyCommandFound=1

is an alternative which searchs for the program in the paths listed by the %PATH% environment variable. It's essentially a pure batch version of which(1). It can be made better but essentially this is it.

Joey
  • 41,098
5

Some refinements to version below. Test that command exists and suppress unneeded output.

WHERE scp >nul 2>nul
IF %ERRORLEVEL% EQU 0 ECHO scp found
yuliskov
  • 471
4

For my situation. The absolute simplest way is using the || or && operator.

my_command.exe -version 2>NUL && echo "my_command exists"

or

my_command.exe -version 2>NUL || echo "my_command doesn't exist"
user46097
  • 841
2

If requiring the installation of extra tools is ok, there's a where command in the resource kits; see Windows equivalent of whereis?.

Otherwise, for versions of Windows that are not too ancient, it's doable in pure cmd, as mentioned in Dos executable lookup except PATH.

1

I know this not quite what you're looking for, but with a slight change in logic it should accomplish what you need.

Every command that is run has a return code (aka errorlevel), if the return code is 0 (zero), the command has run successfully, if the return code is greater than 0, something has gone wrong.

See here for more details.

Something like -

my_command
if (%ERRORLEVEL% > 0) then (
  REM Output was probably "'my_command.exe' is not recognized as an internal or external command, operable program or batch file.  OR SOMETHING WENT WRONG WITH IT."
  REM Do not run my_command.exe
)
bryan
  • 8,528
  • 4
  • 30
  • 42
0

If you are dealing with a broad command that can also be a DOSKEY and if you are fine with executing it and just want to make sure it returns no error (i.e. when it is missing or not declared):

my-command 1>NUL 2>NUL
IF NOT %ERRORLEVEL% == 0 ECHO my-command is faulty or missing
Martin Braun
  • 933
  • 2
  • 14
  • 24
0
set JAVA_CMD=
for /f %i in ('where java 2^>nul') do ( if exist "%i" set "JAVA_CMD=%i" )
echo %JAVA_CMD%

try this.

YUPEN
  • 101
0

You can use WHERE for this and specify the /Q parameter to suppress output and return only the exit code:

WHERE /Q myCommand.exe
IF ERRORLEVEL 1 ECHO myCommand.exe not found

If you're including path information, you either need to use the /R parameter or use : to separate the path and file name. These are essentially the same:

WHERE /R "C:\Windows\System32" cmd.exe
WHERE "C:\Windows\System32:cmd.exe"

Putting it together based on your question:

WHERE /Q my_command.exe
IF ERRORLEVEL 1 (
    :: command not found, so don't run it
    :: maybe show an error message here, can use %ERRORLEVEL% for more information
) ELSE (
    :: command exists, so run it with args
    my_command.exe my_args
)

Probably more useful when specifying a path parameter, but when handling a command not found you can use %ERRORLEVEL% for more information. Examples:

Error Code Description
1 Unrecognized command (not found)
2 Command/file not found in the specified location
3 Path not found
5 Access denied
areyling
  • 111
0

While all those way might work, why not the built in way?

If exists my_command do echo "my_command exists"

Run "if /?" on the command line for details

uSlackr
  • 9,053