What is the proper way to test if a parameter is empty in a batch file?

WindowsShellBatch FileCmd

Windows Problem Overview


I need to test if a variable is set or not. I've tried several techniques but they seem to fail whenever %1 is surrounded by quotes such as the case when %1 is "c:\some path with spaces".

IF NOT %1 GOTO MyLabel // This is invalid syntax
IF "%1" == "" GOTO MyLabel // Works unless %1 has double quotes which fatally kills bat execution
IF %1 == GOTO MyLabel // Gives an unexpected GOTO error.

According to this site, these are the supported IF syntax types. So, I don't see a way to do it.

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

UPDATE: on 2020-10-25, I updated the accepted answer from using brackets to using a tilde. Everyone says the tilde is better as it's more secure. I'm a little torn cause the tilde looks more complicated and is less clear as to what it's purpose is but nevertheless, I changed it.

Windows Solutions


Solution 1 - Windows

Use square brackets instead of quotation marks:

IF [%1] == [] GOTO MyLabel

Parentheses are insecure: only use square brackets.

Solution 2 - Windows

You can use:

IF "%~1" == "" GOTO MyLabel

to strip the outer set of quotes. In general, this is a more reliable method than using square brackets because it will work even if the variable has spaces in it.

Solution 3 - Windows

One of the best semi solutions is to copy %1 into a variable and then use delayed expansion, as delayedExp. is always safe against any content.

set "param1=%~1"
setlocal EnableDelayedExpansion
if "!param1!"=="" ( echo it is empty )
rem ... or use the DEFINED keyword now
if defined param1 echo There is something

The advantage of this is that dealing with param1 is absolutly safe.

And the setting of param1 will work in many cases, like

test.bat hello"this is"a"test
test.bat you^&me

But it still fails with strange contents like

test.bat ^&"&

To be able to get a 100% correct answer for the existence

It detects if %1 is empty, but for some content it can't fetch the content.
This can be also be useful to distinguish between an empty %1 and one with "".
It uses the ability of the CALL command to fail without aborting the batch file.

@echo off
setlocal EnableDelayedExpansion
set "arg1="
call set "arg1=%%1"

if defined arg1 goto :arg_exists

set "arg1=#"
call set "arg1=%%1"
if "!arg1!" EQU "#" (
	echo arg1 exists, but can't assigned to a variable
	REM Try to fetch it a second time without quotes
	(call set arg1=%%1)
	goto :arg_exists
)

echo arg1 is missing
exit /b

:arg_exists
echo arg1 exists, perhaps the content is '!arg1!'

If you want to be 100% bullet proof to fetch the content, you could read How to receive even the strangest command line parameters?

Solution 4 - Windows

From IF /?:

> If Command Extensions are enabled IF > changes as follows: > > IF [/I] string1 compare-op string2 command > IF CMDEXTVERSION number command > IF DEFINED variable command > > ...... > > The DEFINED conditional works just > like EXISTS except it takes an > environment variable name and returns > true if the environment variable is > defined.

Solution 5 - Windows

Unfortunately I don't have enough reputation to comment or vote on the current answers to I've had to write my own.

Originally the OP's question said "variable" rather than "parameter", which got very confusing, especially as this was the number one link in google for searching how to test for blank variables. Since my original answer, Stephan has edited the original question to use the correct terminology, but rather than deleting my answer I decided to leave it to help clear up any confusion, especially in case google is still sending people here for variables too:

%1 IS NOT A VARABLE! IT IS A COMMAND LINE PARAMETER.

Very important distinction. A single percent sign with a number after it refers to a command line parameter not a variable.

Variables are set using the set command, and are recalled using 2 percent signs - one before and one after. For example %myvar%

To test for an empty variable you use the "if not defined" syntax (commands explicitly for variables do not require any percent signs), for example:

set myvar1=foo  
if not defined myvar1 echo You won't see this because %myvar1% is defined.  
if not defined myvar2 echo You will see this because %myvar2% isn't defined.

(If you want to test command line parameters then I recommend referring to jamesdlin's answer.)

Solution 6 - Windows

Use "IF DEFINED variable command" to test variable in batch file.

But if you want to test batch parameters, try below codes to avoid tricky input (such as "1 2" or ab^>cd)

set tmp="%1"
if "%tmp:"=.%"==".." (
	echo empty
) else (
	echo not empty
)

Solution 7 - Windows

You can use

if defined (variable) echo That's defined!
if not defined (variable) echo Nope. Undefined.

Solution 8 - Windows

I created this small batch script based on the answers here, as there are many valid ones. Feel free to add to this so long as you follow the same format:

REM Parameter-testing

Setlocal EnableDelayedExpansion EnableExtensions

IF NOT "%~1"=="" (echo Percent Tilde 1 failed with quotes) ELSE (echo SUCCESS)
IF NOT [%~1]==[] (echo Percent Tilde 1 failed with brackets) ELSE (echo SUCCESS)
IF NOT  "%1"=="" (echo Quotes one failed) ELSE (echo SUCCESS)
IF NOT [%1]==[] (echo Brackets one failed) ELSE (echo SUCCESS)
IF NOT "%1."=="." (echo Appended dot quotes one failed) ELSE (echo SUCCESS)
IF NOT [%1.]==[.] (echo Appended dot brackets one failed) ELSE (echo SUCCESS)

pause

Solution 9 - Windows

I test with below code and it is fine.

@echo off

set varEmpty=
if not "%varEmpty%"=="" (
    echo varEmpty is not empty
) else (
    echo varEmpty is empty
)
set varNotEmpty=hasValue
if not "%varNotEmpty%"=="" (
    echo varNotEmpty is not empty
) else (
    echo varNotEmpty is empty
)

Solution 10 - Windows

I usually use this:

IF "%1."=="." GOTO MyLabel

If %1 is empty, the IF will compare "." to "." which will evaluate to true.

Solution 11 - Windows

Empty string is a pair of double-quotes/"", we can just test the length:

set ARG=%1
if not defined ARG goto nomore

set CHAR=%ARG:~2,1%
if defined CHAR goto goon

then test it's 2 characters against double-quotes:

if ^%ARG:~1,1% == ^" if ^%ARG:~0,1% == ^" goto blank
::else
goto goon

Here's a batch script you can play with. I think it properly catches the empty string.

This is just an example, you just need to customize 2 (or 3?) steps above according to your script.

@echo off
if not "%OS%"=="Windows_NT" goto EOF
:: I guess we need enableExtensions, CMIIW
setLocal enableExtensions
set i=0
set script=%0

:LOOP
set /a i=%i%+1

set A1=%1
if not defined A1 goto nomore

:: Assumption:
:: Empty string is (exactly) a pair of double-quotes ("")

:: Step out if str length is more than 2
set C3=%A1:~2,1%
if defined C3 goto goon

:: Check the first and second char for double-quotes
:: Any characters will do fine since we test it *literally*
if ^%A1:~1,1% == ^" if ^%A1:~0,1% == ^" goto blank
goto goon

:goon
echo.args[%i%]: [%1]
shift
goto LOOP

:blank
echo.args[%i%]: [%1] is empty string
shift
goto LOOP

:nomore
echo.
echo.command line:
echo.%script% %*

:EOF

This torture test result:

.test.bat :: ""  ">"""bl" " "< "">"  (")(") "" :: ""-"  " "( )"">\>" ""
args[1]: [::]
args[2]: [""] is empty string
args[3]: [">"""bl" "]
args[4]: ["< "">"]
args[5]: [(")(")]
args[6]: [""] is empty string
args[7]: [::]
args[8]: [""-"  "]
args[9]: ["( )"">\>"]
args[10]: [""] is empty string

command line:
.test.bat :: ""  ">"""bl" " "< "">"  (")(") "" :: ""-"  " "( )"">\>" ""

Solution 12 - Windows

#Script 1: Input ("Remove Quotes.cmd" "This is a Test")

@ECHO OFF

REM Set "string" variable to "first" command line parameter
SET STRING=%1

REM Remove Quotes [Only Remove Quotes if NOT Null]
IF DEFINED STRING SET STRING=%STRING:"=%

REM IF %1 [or String] is NULL GOTO MyLabel
IF NOT DEFINED STRING GOTO MyLabel


REM   OR   IF "." equals "." GOTO MyLabel
IF "%STRING%." == "." GOTO MyLabel

REM GOTO End of File
GOTO :EOF

:MyLabel
ECHO Welcome!

PAUSE

Output (There is none, %1 was NOT blank, empty, or NULL):


Run ("Remove Quotes.cmd") without any parameters with the above script 1

Output (%1 is blank, empty, or NULL):

Welcome!

Press any key to continue . . .

Note: If you set a variable inside an IF ( ) ELSE ( ) statement, it will not be available to DEFINED until after it exits the "IF" statement (unless "Delayed Variable Expansion" is enabled; once enabled use an exclamation mark "!" in place of the percent "%" symbol}.

For example:

#Script 2: Input ("Remove Quotes.cmd" "This is a Test")

@ECHO OFF

SETLOCAL EnableDelayedExpansion

SET STRING=%0
IF 1==1 (
  SET STRING=%1
  ECHO String in IF Statement='%STRING%'
  ECHO String in IF Statement [delayed expansion]='!STRING!'
) 

ECHO String out of IF Statement='%STRING%'

REM Remove Quotes [Only Remove Quotes if NOT Null]
IF DEFINED STRING SET STRING=%STRING:"=%

ECHO String without Quotes=%STRING% 

REM IF %1 is NULL GOTO MyLabel
IF NOT DEFINED STRING GOTO MyLabel

REM GOTO End of File
GOTO :EOF

:MyLabel
ECHO Welcome!

ENDLOCAL
PAUSE

Output:

C:\Users\Test>"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd" "This is a Test"  
String in IF Statement='"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"'  
String in IF Statement [delayed expansion]='"This is a Test"'  
String out of IF Statement='"This is a Test"'  
String without Quotes=This is a Test  
  
C:\Users\Test>  

Note: It will also remove quotes from inside the string.

For Example (using script 1 or 2): C:\Users\Test\Documents\Batch Files>"Remove Quotes.cmd" "This is "a" Test"

Output (Script 2):

String in IF Statement='"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"'  
String in IF Statement [delayed expansion]='"This is "a" Test"'  
String out of IF Statement='"This is "a" Test"'  
String without Quotes=This is a Test  

Execute ("Remove Quotes.cmd") without any parameters in Script 2:

Output:

Welcome!

Press any key to continue . . .

Solution 13 - Windows

To sum things up:

set str=%~1
if not defined str ( echo Empty string )

This code will output "Empty string" if %1 is either "" or " or empty. Added it to the accepted answer that's currently incorrect.

Solution 14 - Windows

I've had a lot of issues with a lot of answers on the net. Most work for most things, but there's always a corner case that breaks each one.
Maybe it doesn't work if it's got quotes, maybe it breaks if it doesn't have quotes, syntax error if the var has a space, some will only work on parameters (as opposed to environment variables), other techniques allow an empty set of quotes to pass as 'defined', and some trickier ones won't let you chain an else afterward.

Here's a solution I'm happy with, please let me know if you find a corner case it won't work for.

:ifSet
if "%~1"=="" (Exit /B 1) else (Exit /B 0)

Having that subroutine either in a your script, or in it's own .bat, should work.
So if you wanted to write (in pseudo):

if (var)
then something
else somethingElse

You can write:

(Call :ifSet %var% && (
    Echo something
)) || (
	Echo something else
)

It worked for all my tests:

(Call :ifSet && ECHO y) || ECHO n
(Call :ifSet a && ECHO y) || ECHO n
(Call :ifSet "" && ECHO y) || ECHO n
(Call :ifSet "a" && ECHO y) || ECHO n
(Call :ifSet "a a" && ECHO y) || ECHO n

Echo'd n, y, n, y, y


More examples:

  • Wanna just check if? Call :ifSet %var% && Echo set
  • Just if not (only the else)? Call :ifSet %var% || Echo set
  • Checking a passed argument; works fine. Call :ifSet %1 && Echo set
  • Didn't want to clog up your scripts/dupe code, so you put it in it's own ifSet.bat? No problem: ((Call ifSet.bat %var%) && Echo set) || (Echo not set)

Solution 15 - Windows

Using ! instead of " for empty string checking

@echo off
SET a=
SET b=Hello
IF !%a%! == !! echo String a is empty
IF !%b%! == !! echo String b is empty

Solution 16 - Windows

This way looks correct:

if "%~1" == "" if [%1] == [] echo Argument 1 is really empty.

First filter (if "%~1" == "") из safe way to detect argument is empty or "".
Second filter (if [%1] == []) will skip "" argument.
Remember we have two kind of empty arguments : really empty (nothing) and empty quotes "".
We have to detect both.

Next code takes all arguments "as is" in variable args:

:GetArgs
set args=%1
:ParseArgs
shift /1
if "%~1" == "" if [%1] == [] goto :DoneArgs
set args=%args% %1
goto :ParseArgs
:DoneArgs
if not defined args echo No arguments
if defined args echo Aguments are: %args%

This code correctly process "normal" arguments (simple words, "multiword phrases" or "") with balanced quotes.
Quoted arguments can even contain special chars like "a & b".
But it is still can fail with "abnormal" expressions with unbalanced quotes (do not use them).

Solution 17 - Windows

The simplest solution, made of two lines of code:

SET /A var02 = %var01% / 1
IF %ERRORLEVEL% NEQ 0 (ECHO Variable var01 is NOT EXIST)

Solution 18 - Windows

I got in in just under a month old (even though it was asked 8 years ago)... I hope s/he's moved beyond batch files by now. ;-) I used to do this all the time. I'm not sure what the ultimate goal is, though. If s/he's lazy like me, my go.bat works for stuff like that. (See below) But, 1, the command in the OP could be invalid if you are directly using the input as a command. i.e.,

"C:/Users/Me"

is an invalid command (or used to be if you were on a different drive). You need to break it in two parts.

C:
cd /Users/Me

And, 2, what does 'defined' or 'undefined' mean? GIGO. I use the default to catch errors. If the input doesn't get caught, it drops to help (or a default command). So, no input is not an error. You can try to cd to the input and catch the error if there is one. (Ok, using go "downloads (only one paren) is caught by DOS. (Harsh!))

cd "%1"
if %errorlevel% neq 0 goto :error

And, 3, quotes are needed only around the path, not the command. i.e.,

"cd C:\Users" 

was bad (or used to in the old days) unless you were on a different drive.

cd "\Users" 

is functional.

cd "\Users\Dr Whos infinite storage space"

works if you have spaces in your path.

@REM go.bat
@REM The @ sigh prevents echo on the current command
@REM The echo on/off turns on/off the echo command. Turn on for debugging
@REM You can't see this.
@echo off
if "help" == "%1" goto :help

if "c" == "%1" C:
if "c" == "%1" goto :done

if "d" == "%1" D:
if "d" == "%1" goto :done

if "home"=="%1" %homedrive%
if "home"=="%1" cd %homepath%
if "home"=="%1" if %errorlevel% neq 0 goto :error
if "home"=="%1" goto :done

if "docs" == "%1" goto :docs

@REM goto :help
echo Default command
cd %1
if %errorlevel% neq 0 goto :error
goto :done

:help
echo "Type go and a code for a location/directory
echo For example
echo go D
echo will change disks (D:)
echo go home
echo will change directories to the users home directory (%homepath%)
echo go pictures
echo will change directories to %homepath%\pictures
echo Notes
echo @ sigh prevents echo on the current command
echo The echo on/off turns on/off the echo command. Turn on for debugging
echo Paths (only) with folder names with spaces need to be inclosed in         quotes (not the ommand)
goto :done

:docs
echo executing "%homedrive%%homepath%\Documents"
%homedrive%
cd "%homepath%\Documents"\test error\
if %errorlevel% neq 0 goto :error
goto :done

:error
echo Error: Input (%1 %2 %3 %4 %5 %6 %7 %8 %9) or command is invalid
echo go help for help
goto :done

:done

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionblak3rView Question on Stackoverflow
Solution 1 - WindowsDan StoryView Answer on Stackoverflow
Solution 2 - WindowsjamesdlinView Answer on Stackoverflow
Solution 3 - WindowsjebView Answer on Stackoverflow
Solution 4 - WindowsAndy MorrisView Answer on Stackoverflow
Solution 5 - WindowsAutoMattTickView Answer on Stackoverflow
Solution 6 - WindowszackzView Answer on Stackoverflow
Solution 7 - WindowsnonameView Answer on Stackoverflow
Solution 8 - WindowskayleeFrye_onDeckView Answer on Stackoverflow
Solution 9 - WindowsKateView Answer on Stackoverflow
Solution 10 - WindowsaphoriaView Answer on Stackoverflow
Solution 11 - Windowsuser6801759View Answer on Stackoverflow
Solution 12 - WindowsMr. RickView Answer on Stackoverflow
Solution 13 - WindowsGrayFaceView Answer on Stackoverflow
Solution 14 - WindowsHashbrownView Answer on Stackoverflow
Solution 15 - WindowsLin WView Answer on Stackoverflow
Solution 16 - WindowsAlex KuryakinView Answer on Stackoverflow
Solution 17 - Windowsalive-oneView Answer on Stackoverflow
Solution 18 - WindowsXorangeView Answer on Stackoverflow