rynd
rynd

Reputation: 1885

Check whether command is available in batch file

I'm writing a batch file for Windows and use the command 7z (7-Zip). I have put the location of it in the PATH. Is there a relatively easy way to check whether the command is available?

Upvotes: 9

Views: 7763

Answers (5)

Mofi
Mofi

Reputation: 49086

There can be used the following code in a batch file not using any other executable than cmd.exe processing the batch file which is working even on Windows XP which does not have %SystemRoot%\System32\where.exe by default (could be copied from Windows Server 2003) or PowerShell.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
if exist "%~dp07z.exe" (set "SevenZip=%~dp07z.exe") else if exist "7z.exe" (for %%I in ("7z.exe") do set "SevenZip=%%~fI") else for %%I in ("7z.exe") do set "SevenZip=%%~$PATH:I"
if not defined SevenZip echo ERROR: Could not find the 7-Zip executable 7z.exe!& pause & exit /B 2
echo Found: "%SevenZip%"
rem Add here other command lines using "%SevenZip%".
endlocal

The third command line searches first in the directory of the batch file for the executable 7z.exe and defines the environment variable SevenZip with the fully qualified file name (drive + path + name + extension) of 7-Zip executable if the file exists in the batch file directory.

Next the third command line checks the existence of 7z.exe in the current working directory and defines the environment variable SevenZip with the fully qualified file name of 7-Zip executable if the file exists in the current working directory. The current working directory can be by chance identical to the batch file directory, but can be also any other directory.

Last on 7-Zip executable still not found the internal command FOR of cmd.exe is used to search for 7z.exe in all directories of the local environment variable PATH one after the other. The environment variable SevenZip is defined with the fully qualified file name of 7z.exe if the file could be found in one of the folder paths. It is important to specify the file name to find in the folders of the environment variable PATH with name and extension. The file would not be found by FOR on using just the name without extension although cmd.exe itself finds the file in this case with using additionally the file extensions list of local environment variable PATHEXT.

The environment variable SevenZip is for sure not defined if the file 7z.exe could not be found in batch file directory or current working directory or any directory listed in PATH even on existing already by chance because of being defined outside of the batch file. The fourth command line informs the user of the batch file about the failed search for 7z.exe, pauses the batch file processing until the user presses a key and then exits the processing of the batch file with exit code 2 indicating this error to the parent process.

The value of the environment variable SevenZip with the fully qualified file name of found file 7z.exe can be otherwise used in the remaining batch file by using "%SevenZip%" with the appropriate options and arguments.

The third and fourth command line can be used to find any executable or script file (other batch file) used next in the batch file multiple times. There must be replaced just all occurrences of 7z.exe by the file name of the executable or script file and all occurrences of environment variable SevenZip by a suitable environment variable name. Please note that the command call must be used on referencing the environment variable value with the found fully qualified file name enclosed in " on using this code to find a batch file with file extension .bat or .cmd as otherwise the Windows Command Processor would continue the batch file processing on the other batch file without returning back to the current batch file. Run call /? in a command prompt window and read the output usage help.

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • call /? … explains %~dp0 … drive and path of batch file (argument 0)
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

See also single line with multiple commands using Windows batch file for an explanation of the unconditional command operator & as used on fourth command line.

Upvotes: 0

Sachin Joseph
Sachin Joseph

Reputation: 19677

Do not execute the command to check its availability (i.e., found in the PATH environment variable). Use where instead:

where 7z.exe >nul 2>nul
IF NOT ERRORLEVEL 0 (
    @echo 7z.exe not found in path.
    [do something about it]
)

The >nul and 2>nul prevent displaying the result of the where command to the user. Executing a program directly to check its availability (even if it is a familiar program) has the following issues:

  • Not immediately obvious what the program does
  • Unintended side effects (change the file system, send emails, etc.)
  • Resource intensive, slow startup, blocking I/O, ...

You can also define a routine, which can help users ensure their system meets the requirements:

rem Ensures that the system has a specific program installed on the PATH.
:check_requirement
set "MISSING_REQUIREMENT=true"
where %1 > NUL 2>&1 && set "MISSING_REQUIREMENT=false"

IF "%MISSING_REQUIREMENT%"=="true" (
  echo Download and install %2 from %3
  set "MISSING_REQUIREMENTS=true"
)

exit /b

Then use it such as:

set "MISSING_REQUIREMENTS=false"

CALL :check_requirement curl cURL https://curl.haxx.se/download.html
CALL :check_requirement svn SlikSVN https://sliksvn.com/download/
CALL :check_requirement jq-win64 jq https://stedolan.github.io/jq/download/

IF "%MISSING_REQUIREMENTS%"=="true" (
  exit /b
)

PowerShell:

On PowerShell, the Get-Command cmdlet can be considered to be the equivalent of cmd's where.exe.

Get-Command <cmd>
IF ($? -ne $true)
{
    Write-Host "<cmd> not found in path"
    # Do something about it
}

Upvotes: 30

nullpotent
nullpotent

Reputation: 9260

Yup:

@echo off
set found=
set program=7z.exe
for %%i in (%path%) do if exist %%i\%program% set found=%%i
echo "%found%"

Upvotes: 1

Marc
Marc

Reputation: 11613

An attempt to execute 7z.exe will return an %errorlevel% of 9009 if the command is not found. You can check that.

7z.exe
if %errorlevel%==9009 echo Command Not Found

Note: This solution is viable for this specific 7zip use case, and likely for plenty of others. But as a general rule, executing a command to determine whether it's present could potentially be harmful. So make sure you understand the effect of executing the command you're checking for, and use your discretion with this approach.

Upvotes: 0

Sachin Kainth
Sachin Kainth

Reputation: 46740

Yes, open a command window and type "7z" (I assume that is the name of the executable). If you get an error saying that the command or operation is not recognised then you know the path statement has a problem in it somewhere, otherwise it doesn't.

Upvotes: -1

Related Questions