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?

4
  • How will you "recognize" your command ? Commented Aug 13, 2010 at 12:56
  • In MS-DOS (true DOS) this was rather simple; you just checked the existence of an exe file in c:\dos; but even then the question remains. Commented Aug 13, 2010 at 12:57
  • Sorry for the confusion. I meant essentially a command prompt in Windows. If I type "lkajsflksajdfj" I want to detect it isn't a command. If I type "notepad.exe", it's OK. Commented Aug 13, 2010 at 13:18
  • @Rook A search path existed in MS-DOS too (at least in later versions). Executables did not have to live in C:\DOS to be executable with just a basename. Commented Apr 12, 2020 at 20:34

11 Answers 11

95
WHERE mycommand IF %ERRORLEVEL% NEQ 0 ECHO mycommand wasn't found 
5
  • 18
    If someone doesn't want the output inside the cmd window just add >nul 2>nul behind the mycommand. Commented Aug 13, 2014 at 13:09
  • Note that there are more output channels than 1 and 2, since 1 stands for output buffer and 2 for error buffer, it depends on how the application was developed, it should work for common apps that ships with Windows, but an specific CLI program could still throwing text when channels 1 and 2 are redirected. Commented Oct 13, 2015 at 14:26
  • 7
    To avoid the output of the where command, one can use the /q (quiet) switch: where /q mycommand Commented Sep 24, 2020 at 13:05
  • There's actually a significant difference between using /q and >nul 2>nul. The first method will only suppress the errors if WHERE exist. The second will suppress absolutely everything, even if the WHERE command doesn't exist or if all PATH variables are cleared. Commented Jan 30, 2023 at 1:46
  • Should the syntax not be like this: IF ERRORLEVEL 1 ? Commented Nov 5 at 3:07
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.

3
  • This solution is perfect ! Commented Jul 8, 2019 at 23:19
  • 1
    Using the other answers in conjunction with this one is what I found best (e.g. replace javac -version with WHERE mycommand) Commented Dec 20, 2020 at 17:31
  • You should def. have another look onto WHERE as I had today :) Commented Nov 9, 2021 at 17:22
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.

2
  • 1
    This is perfect, does exactly what was asked for! Commented Feb 18, 2013 at 12:26
  • worth noting to people not too familiar with batch scripts: you can easily check multiple commands with this by using (command1.exe;my_other_command.exe) and so on, and use that %%x to get which command it found, e.g. useful to find various versioned programs, so you can set my_cmd=%%x and then instead of my_cmd_5.3.exe do something you just write %my_cmd% do something, can be for example useful for finding several lua or python versions Commented Jan 2, 2023 at 20:23
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 
2
  • where <my_exe> NUL 2>&1 || echo my.exe does not exist && goto :EOF works nicely in scripts Commented Nov 10, 2015 at 15:01
  • 1
    NB: This does not work if the file name you want to test includes path information. E.g., WHERE \Windows\System32\cmd.exe => INFO: Could not find files for the given pattern(s). Commented Aug 31, 2018 at 17:25
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" 
1
  • Why don't you redirect stdout too? Commented Aug 14, 2010 at 13:09
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.

2
  • Thanks for the reponse! Unfortunately, one of the requirements is that it has to run on a vanilla box (XP machines included) - so whereis isn't an option. Commented Aug 13, 2010 at 13:16
  • 2
    The second link Gilles gave has a nifty solution that uses FOR and no extra tools. Commented Aug 13, 2010 at 13:19
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 ) 
2
  • This is clever, I like it. Commented Aug 13, 2010 at 22:20
  • Yeah, but its ugly since, if the command is not found it throws a 2 line error. So, a cleaner solution could be found possibly. Commented Nov 28, 2012 at 18:43
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

1
  • 7
    This will only look whether a file/directory with that name exists in the current directory. It provides not much of a hint whether a runnable command with that name exists because to determine that you'd have to search the PATH. Commented Feb 19, 2013 at 7:18
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 
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.

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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.