Check for null variable in Windows batch

WindowsBatch File

Windows Problem Overview


I'm working on a Windows batch file that will bcp three text files into SQL Server. If something goes wrong in production, I want to be able to override the file names. So I'm thinking of doing something like this.

bcp.exe MyDB..MyTable1 in %1 -SMyServer -T -c -m0
bcp.exe MyDB..MyTable2 in %2 -SMyServer -T -c -m0
bcp.exe MyDB..MyTable3 in %3 -SMyServer -T -c -m0

I would like to be able to enter default names for all three files, to be used if the positional parameters are not supplied. The idea would be either to execute

myjob.bat

with no parameters, and have it use the defaults, or execute

myjob.bat "c:\myfile1" "c:\myfile2" "c:\myfile3"

and have it use those files. I haven't been able to figure out how to tell if %1, %2 and %3 exist and/or are null. I also don't know how to set those values conditionally. Is this possible? Any suggestions would be appreciated.

Windows Solutions


Solution 1 - Windows

To test for the existence of a command line paramater, use empty brackets:

IF [%1]==[] echo Value Missing

or

IF [%1] EQU [] echo Value Missing

The SS64 page on IF will help you here. Under "Does %1 exist?".

You can't set a positional parameter, so what you should do is do something like

SET MYVAR=%1

You can then re-set MYVAR based on its contents.

Solution 2 - Windows

The right thing would be to use a "if defined" statement, which is used to test for the existence of a variable. For example:

IF DEFINED somevariable echo Value exists

In this particular case, the negative form should be used:

IF NOT DEFINED somevariable echo Value missing

PS: the variable name should be used without "%" caracters.

Solution 3 - Windows

Both answers given are correct, but I do mine a little different. You might want to consider a couple things...

Start the batch with:

SetLocal

and end it with

EndLocal

This will keep all your 'SETs" to be only valid during the current session, and will not leave vars left around named like "FileName1" or any other variables you set during the run, that could interfere with the next run of the batch file. So, you can do something like:

IF "%1"=="" SET FileName1=c:\file1.txt

The other trick is if you only provide 1, or 2 parameters, use the SHIFT command to move them, so the one you are looking for is ALWAYS at %1...

For example, process the first parameter, shift them, and then do it again. This way, you are not hard-coding %1, %2, %3, etc...

The Windows batch processor is much more powerful than people give it credit for.. I've done some crazy stuff with it, including calculating yesterday's date, even across month and year boundaries including Leap Year, and localization, etc.

If you really want to get creative, you can call functions in the batch processor... But that's really for a different discussion... :)

Oh, and don't name your batch files .bat either.. They are .cmd's now.. heh..

Hope this helps.

Solution 4 - Windows

rem set defaults:
set filename1="c:\file1.txt"
set filename2="c:\file2.txt"
set filename3="c:\file3.txt"
rem set parameters:
IF NOT "a%1"=="a" (set filename1="%1")
IF NOT "a%2"=="a" (set filename2="%2")
IF NOT "a%3"=="a" (set filename1="%3")
echo %filename1%, %filename2%, %filename3%

Be careful with quotation characters though, you may or may not need them in your variables.

Solution 5 - Windows

Late answer, but currently the accepted one is at least suboptimal.

Using quotes is ALWAYS better than using any other characters to enclose %1.
Because when %1 contains spaces or special characters like &, the IF [%1] == simply stops with a syntax error.

But for the case that %1 contains quotes, like in myBatch.bat "my file.txt", a simple IF "%1" == "" would fail.

But as you can't know if quotes are used or not, there is the syntax %~1, this removes enclosing quotes when necessary.

Therefore, the code should look like

set "file1=%~1"
IF "%~1"=="" set "file1=default file"

type "%file1%"   --- always enclose your variables in quotes

If you have to handle stranger and nastier arguments like myBatch.bat "This & will "^&crash
Then take a look at SO:How to receive even the strangest command line parameters?

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
QuestionJohn M GantView Question on Stackoverflow
Solution 1 - WindowscrbView Answer on Stackoverflow
Solution 2 - WindowsLeonardo PugliaView Answer on Stackoverflow
Solution 3 - WindowsLarryFView Answer on Stackoverflow
Solution 4 - WindowsStanislav KniazevView Answer on Stackoverflow
Solution 5 - WindowsjebView Answer on Stackoverflow