Variables in Batch Files

By giskier

I will be writing about different topics all related to batch files.  Today I picked variables.  The variables used in batch files are environment variables.  Every process has an environment associated with it, and every environment has a list of variables.  To see the list of variables in your machine, open a command prompt window and type set.  It will give an alphabetical listing of all the variables.  Some of the common ones are USERNAME, USERDOMAIN, PROCESSOR_ARCHITECTURE, COMPUTERNAME, and SystemRoot

In batch files you can use these and create more of them.  The variables you create won’t affect the environment from which the batch file started running.  They are unique to the process running your batch file.  Variables can be defined to store information to be used later on, just like in any other language.  Most of the times variables are strings, but they can be integers if defined using the /A option, as follows:

set /a FileCount=5

In this case variable FileCount is 5.  Variable names are not case sensitive.  That means that I can refer to FILECOUNT, or filecount and both are the same thing.  A mix of upper case and lower case is the same also.

When a variable is defined as an integer, it can also be used as a string.  So, the following is valid

set /a FileCount=5
if “%FileCount%”==”5″ (echo yes) else (echo no)

This code will echo ‘yes’ to the console.  As you can see, to get the value of an environment variable you sorround it by percent signs.  (e.g.  %varibleName%).  If the variable you use is not defined you will get empty string when the batch file is running.  From the command line you get the literal (e.g. %nonExistentVar%).

Numeric Values

When variables store numeric values, you can perform operations with them.  Batch commands support grouping, arithmetic, logical, assignment operators and more.  You can see the list of operators by typing set /? in the command line.   All these operators give you the ability to keep count of things.  Something like set /a FileCount+=1 is perfectly valid.  So is set /a FileCount=%Previouscount% + 17.  When you use arithmetic expressions, you can avoid using the percent signs to denote variables.  That means that the following 2 expressions are equivalent:

set /a FileCount=%PreviousCount% + 17
set /a Filecount=PreviousCount + 17

This is only true when the /a option is used in a set command.   So what happens if a variable does not store a numeric value?  What happens is the value of PreviousCount in the example is the string ‘Yellow’.  Then the value is replaced by zero.

Some of the operators can be confused with special characters intended for pipelines and redirection (|, >>, <<).  If you are using arithmetic expressions involving any of these characters, use double quotes to avoid confusions.  Like this:

set /a myVar=”foo >> 2 | 7″

Without the quotes you get an error when running this command.  The if command provides some operators to compare numeric variables.  These are NEQ, EQU, LSS, LEQ, GTR, GTE, which stand for “not equal”, “equal to”, “less than”, “less than or equal”, “greater than” and “greater than or equal to” respectively.  An example on how to use these operators can be

if %fileCount% GTR 10 echo Too many files opened.  Process will abort.

String Variables

When variables hold strings, they can be used to save values, folder names, etc.  They can be used in comparisons just like numbers, and denoted with replacements too.  Another interesting point is that variables can store parts of instructions to be executed.  This can be useful when you have a value entered by the user, and based on it define where the code should execute, as this:

goto Option%chosenOption%

if the value for ChosenOption is ‘Label1′ the code would jump to label OptionLabel1.  This makes the value of variables more powerful and versatile than in other languages.   Complete instructions can be executed this way, as follows:

set myInstruction=echo This data comes from a variable
%myInstruction%

These 2 instructions will result in the string being echoed.  This makes environment variables even more powerful than in some other languages.  You can create code on the fly and execute it.  Pretty cool.

Watching out for common pitfalls

There are some things to be careful about.  Watch the following assignment:

set myVariable = myValue

At first sight it may seem fine.  But it’s not.  The name of the variable just created is ‘myVariable ‘ (with a space at the end), and it stores the value ‘ myValue’ (with a space at the beginning).  Running Steps will warn you if it finds this type of constructions in your files.   If you accidentally had spaces after ‘myValue’ on the line, the spaces will become part of the variable’s value.  Running Steps will warn you about that too.  Be careful not to fall into those.

Special Variables

There are some special variables which are predefined in your environment.  These are: errorlevel, cd, time, date, comspec, Random, and CmdExtVersion.  You should never create variables with these names.  If you do, you will be creating a variable that shadows out the special variable with the same name.  This leads to very hard to find bugs in your code.  Running Steps will warn you again this practice when it finds it.

Setlocal and Endlocal commands

Finally, I will briefly mention setlocal and endlocal commands.  When you execute a setlocal command, a new set of environment variables is created.  A copy of your set of variables.  From there on, any changes to your variables are applied in this new set.  Where did the initial set go?  It’s still there, and it will become active when an endlocal command executes.  As you can see these commands will effectively stack sets of variables (setlocal is like a push (push current and get a copy of it) and endlocal pops the old set from the stack and throws away the previous active set).   If you return from a routine (using goto :EOF or exit) you will return to the caller.  Upon returning, any new sets of variables will be discarded as if you had called endlocal several times.  My advice: don’t rely on this behavior.  Using as many endlocal instructions as setlocal will make your code more readable and maintainable.  Running Steps will count how many setlocal instructions a file has, and also how many endlocal’s.  If the numbers do not match, a warning will be issued.  Just for fun, try the following:

call :MyRoutine
.
.
:Myroutine
set myVariable=myVariable version 0
setlocal
set myVariable=myVariable version 1

setlocal
set myVariable=myVariable version 2
goto :EOF

There are things related to variables that I did not mention here.  Specifically delayed expansion syntax.  I will write about that topic some other day.  It’s a whole topic in itself.

The topic of variables is very extensive and long.  I know.  But it’s the foundation for doing things with batch files.  I hope you stayed with me till the end.  If not, it’s OK too.   You may come and use this article as reference some other time.

I hope this will be helpful.  Enjoy!

GISkier

Leave a Reply