[batch-file] How can I check if an argument is defined when starting/calling a batch file?

I'm trying to use the following validation logic in a batch file but the "usage" block never executes even when no parameter is supplied to the batch file.

if ("%1"=="") goto usage

@echo This should not execute

@echo Done.
goto :eof

:usage
@echo Usage: %0 <EnvironmentName>
exit 1

What am I doing wrong?

This question is related to batch-file arguments

The answer is


The check for whether a commandline argument has been set can be [%1]==[], but, as Dave Costa points out, "%1"=="" will also work.

I also fixed a syntax error in the usage echo to escape the greater-than and less-than signs. In addition, the exit needs a /B argument otherwise CMD.exe will quit.

@echo off

if [%1]==[] goto usage
@echo This should not execute
@echo Done.
goto :eof
:usage
@echo Usage: %0 ^<EnvironmentName^>
exit /B 1

IF "%1"=="" will fail, all versions of this will fail under certain poison character conditions. Only IF DEFINED or IF NOT DEFINED are safe


This is the same as the other answers, but uses only one label and puts the usage first, which additionally makes it serve as a kind of documentation commend of the script which is also usually placed at the top:

@echo off
:: add other test for the arguments here...
if not [%1]==[] goto main
:: --------------------------
echo This command does something.
echo.
echo %0 param%%1 param%%2
echo       param%%1 the file to operate on
echo       param%%1 another file

:: --------------------------
exit /B 1

:main
:: --------------------------
echo do something with all arguments (%%* == %*) here...

However, if you don't have to use cmd/batch, use bash on WSL or powershell, they have more sane syntax and less arcane features.


A more-advanced example:

? unlimited arguments.

? exist on file system (either file or directory?) or a generic string.

? specify if is a file

? specify is a directory

? no extensions, would work in legacy scripts!

? minimal code ?

@echo off

:loop
      ::-------------------------- has argument ?
      if ["%~1"]==[""] (
        echo done.
        goto end
      )
      ::-------------------------- argument exist ?
      if not exist %~s1 (
        echo not exist
      ) else (
        echo exist
        if exist %~s1\NUL (
          echo is a directory
        ) else (
          echo is a file
        )
      )
      ::--------------------------
      shift
      goto loop
      
      
:end

pause

? other stuff..?

¦ in %~1 - the ~ removes any wrapping " or '.

¦ in %~s1 - the s makes the path be DOS 8.3 naming, which is a nice trick to avoid spaces in file-name while checking stuff (and this way no need to wrap the resource with more "s.

¦ the ["%~1"]==[""] "can not be sure" if the argument is a file/directory or just a generic string yet, so instead the expression uses brackets and the original unmodified %1 (just without the " wrapping, if any..)

if there were no arguments of if we've used shift and the arg-list pointer has passed the last one, the expression will be evaluated to [""]==[""].

¦ this is as much specific you can be without using more tricks (it would work even in windows-95's batch-scripts...)

¦ execution examples

save it as identifier.cmd

it can identify an unlimited arguments (normally you are limited to %1-%9), just remember to wrap the arguments with inverted-commas, or use 8.3 naming, or drag&drop them over (it automatically does either of above).


this allows you to run the following commands:

?identifier.cmd c:\windows and to get

exist
is a directory
done

?identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" and to get

exist
is a file
done

? and multiple arguments (of course this is the whole-deal..)

identifier.cmd c:\windows\system32 c:\hiberfil.sys "c:\pagefile.sys" hello-world

and to get

exist
is a directory
exist
is a file
exist
is a file
not exist
done.

naturally it can be a lot more complex, but nice examples should always be simple and minimal. :)

Hope it helps anyone :)

published here:CMD Ninja - Unlimited Arguments Processing, Identifying If Exist In File-System, Identifying If File Or Directory

and here is a working example that takes any amount of APK files (Android apps) and installs them on your device via debug-console (ADB.exe): Make The Previous Post A Mass APK Installer That Does Not Uses ADB Install-Multi Syntax


Get rid of the parentheses.

Sample batch file:

echo "%1"

if ("%1"=="") echo match1

if "%1"=="" echo match2

Output from running above script:

C:\>echo "" 
""

C:\>if ("" == "") echo match1 

C:\>if "" == "" echo match2 
match2

I think it is actually taking the parentheses to be part of the strings and they are being compared.


IF "%1"=="" GOTO :Continue
.....
.....
:Continue
IF "%1"=="" echo No Parameter given

IF "%~1"=="" GOTO :Usage

~ will de-quote %1 if %1 itself is quoted.

" " will protect from special characters passed. for example calling the script with &ping