Using Batch File Parameters
Most command-line utilities require extra information such as a filename (for example, when you use COPY or DEL) or a folder path (such as when you use CD or MD). These extra pieces of information—they’re called parameters—give
you the flexibility to specify exactly how you want a command to work.
You can add the same level of flexibility to your batch files. To
understand how this works, first look at the following example:
@ECHO OFF
ECHO.
ECHO The first parameter is %1
ECHO The second parameter is %2
ECHO The third parameter is %3
As you can see, this batch file doesn’t do much except ECHO four lines to the screen (the first of which is just a blank line). Curiously, however, each ECHO command ends with a percent sign (%) and a number. Type and save this batch file as Parameters.bat. Then, to see what these unusual symbols mean, enter the following at the command line:
This produces the following output:
C:\>parameters A B C
The first parameter is A
The second parameter is B
The third parameter is C
The following ECHO command in Parameters.bat produces the first line in the output (after the blank line):
ECHO The first parameter is %1
When Windows sees the %1 symbol in a batch file, it examines the original command, looks for the first item after the batch filename, and then replaces %1 with that item. In the example, the first item after parameters is A, so Windows uses that to replace %1. Only when it has done this does it proceed to ECHO the line to the screen.
Note
If your batch file command has more parameters than
the batch file is looking for, it ignores the extras. For example,
adding a fourth parameter to the parameters command line has no
effect on the file’s operation. Note, too, that you can’t use more than
nine replaceable parameters in a batch file (%1 through %9). However, a tenth replaceable parameter (%0) holds the name of the batch file.
Tip
If the replaceable parameter is a string that
includes one or more spaces, surround the parameter with quotation marks
(for example, "%1").
FOR: Looping in a Batch File
The FOR command is a batch file’s way of looping through an instruction:
FOR %%parameter IN (set) DO command
%%parameter | This is the parameter that changes each time through the loop. You can use any single character after the two % signs (except 0 through 9). There are two % signs because Windows deletes single ones as it processes the batch file. |
IN (set) | This is the list (it’s officially called the set) of choices for %%parameter. You can use spaces, commas, or semicolons to separate the items in the set, and you must enclose them in parentheses. |
DO command | For each item in the set, the batch file performs whatever instruction is given by command. The %%parameter is normally found somewhere in command. |
Here’s an example of the FOR command in a simple batch file that might help clear things up:
@ECHO OFF
FOR %%B IN (A B C) DO ECHO %%B
This batch file (call it Parameters.bat) produces the following output:
C:\BATCH>parameters2
A
B
C
All this does is loop through the three items in the set (A, B, and C) and substitute each one for %%B in the command ECHO %%B.
GOTO: Jumping to a Line in a Batch File
Your basic batch file lives a simple, linear
existence. The first command is processed, and then the second, the
third, and so on to the end of the file. It’s boring, but that’s all you
need most of the time.
However, sometimes the batch file’s usual
one-command-after-the-other approach breaks down. For example, depending
on a parameter or the result of a previous command, you might need to
skip over a line or two. How do you do this? With the GOTO batch command:
...
... (the opening batch commands)
...
GOTO NEXT
...
... (the batch commands that get skipped)
...
:NEXT
...
... (the rest of the batch commands)
...
Here, the GOTO command is telling the batch file to look for a line that begins with a colon and the word NEXT (this is called a label) and to ignore any commands in between.
GOTO is useful for processing different batch commands depending on a parameter. Here’s a simple example:
@ECHO OFF
CLS
GOTO %1
:A
ECHO This part of the batch file runs if A is the parameter.
GOTO END
:B
ECHO This part of the batch file runs if B is the parameter.
:END
Suppose that this file is named GOTOTest.BAT and you enter the following command:
In the batch file, the line GOTO %1 becomes GOTO A. That makes the batch file skip down to the :A label, where it then runs the commands (in this example, just an ECHO statement) and skips to :END to avoid the rest of the batch file commands.
IF: Handling Batch File Conditions
Batch files sometimes have to make decisions before
proceeding. Here are a few examples of what a batch file might have to
decide:
If the %2 parameter equals /Q, jump to the QuickFormat section. Otherwise, do a regular format.
If the user forgets to enter a parameter, cancel the program. Otherwise, continue processing the batch file.
If the file that the user wants to move already exists in the new folder, display a warning. Otherwise, proceed with the move.
If the last command failed, display an error message and cancel the program. Otherwise, continue.
For these types of decisions, you need to use the IF batch command. IF has the following general form:
condition | This is a test that evaluates to a yes or no answer (“Did the user forget a parameter?”). |
command | This is what is executed if the condition produces a positive response (“Cancel the batch file”). |
For example, one of the most common uses of the IF
command is to check the parameters that the user entered and proceed
accordingly. From the previous section, the simple batch file that used GOTO can be rewritten with IF as follows:
@ECHO OFF
CLS
IF "%1"=="A" ECHO This part of the batch file runs if A is the parameter.
IF "%1"=="B" ECHO This part of the batch file runs if B is the parameter.
The condition part of an IF statement is a bit tricky. Let’s look at the first one: "%1"=="A".
Remember that the condition is always a question with a yes or no
answer. In this case, the question boils down to the following:
Is the first parameter (%1) equal to A?
The double equal sign (==) looks weird, but that’s
just how you compare two strings of characters in a batch file. If the
answer is yes, the command executes. If the answer is no, the batch file
moves on to the next IF, which checks to see whether the parameter is "B".
Note
Strictly speaking, you don’t need to include the quotation marks ("). Using %1==A accomplishes the same thing. However, I prefer to use them for two reasons: First, it makes it clearer that the IF
condition is comparing strings; second, as you’ll see in the next
section, the quotation marks enable you to check whether the user forgot
to enter a parameter.
Caution
This batch file has a serious flaw that will prevent
it from working under certain conditions. Specifically, if you use the
lowercase "a" or "b" as a parameter, nothing happens because, to the IF command, "a" is different from "A". The solution is to add extra IF commands to handle this situation:
IF "%1"=="a" ECHO This part of the batch file runs if a is the parameter
Proper batch file techniques require you to check to
see not only what a parameter is, but whether one exists. This can be
vital because a missing parameter can cause a batch file to crash and
burn. For example, here’s a batch file called DontCopy.bat
designed to copy all files in the current folder to a new destination
(given by the second parameter) except those you specified (given by the
first parameter):
@ECHO OFF
CLS
ATTRIB +H %1
ECHO.
ECHO Copying all files to %2 except %1:
ECHO.
XCOPY *.* %2
ATTRIB -H %1
What happens if the user forgets to add the destination parameter (%2)? Well, the XCOPY command becomes XCOPY *.*, which terminates the batch file with the following error:
File cannot be copied onto itself
The solution is to add an IF command that checks to see whether %2 exists:
@ECHO OFF
CLS
IF "%2"=="" GOTO ERROR
ATTRIB +H %1
ECHO.
ECHO Copying all files to %2 except %1:
ECHO.
XCOPY32 *.* %2
ATTRIB -H %1
GOTO END
:ERROR
ECHO You didn't enter a destination!
ECHO Please try again...
:END
The condition "%2"=="" is literally comparing %2 to nothing (""). If this proves to be true, the program jumps (using GOTO) to the :ERROR
label, and a message is displayed to admonish the user. Notice, too,
that if everything is okay (that is, the user entered a second
parameter), the batch file executes normally and jumps to the :END label to avoid displaying the error message.
Another variation of IF is the IF EXIST command, which checks for the existence of a file. This is handy, for example, when you’re using COPY or MOVE.
First, you can check whether the file you want to copy or move exists.
Second, you can check whether a file with the same name already exists
in the target folder. (As you probably know, a file that has been copied
over by another of the same name is downright impossible to recover.)
Here’s a batch file called SafeMove.bat, which uses the MOVE command to move a file but first checks the file and then the target folder:
@ECHO OFF
CLS
IF EXIST %1 GOTO SO_FAR_SO_GOOD
ECHO The file %1 doesn't exist!
GOTO END
:SO_FAR_SO_GOOD
IF NOT EXIST %2 GOTO MOVE_IT
ECHO The file %1 exists on the target folder!
ECHO Press Ctrl+C to bail out or, to keep going,
PAUSE
:MOVE_IT
MOVE %1 %2
:END
To explain what’s happening, I’ll use a sample command:
safemove moveme.txt "%userprofile%\documents\moveme.txt"
The first IF tests for the existence of %1 (MOVEME.TXT in the example). If there is such a file, the program skips to the :SO_FAR_SO_GOOD label. Otherwise, it tells the user that the file doesn’t exist and then jumps down to :END.
The second IF is slightly different. In this case, I want to continue only if MOVEME.TXT doesn’t exist in the current user’s Documents folder, so I add NOT to the condition. (You can include NOT in any IF condition.) If this proves true (that is, the file given by %2 doesn’t exist), the file skips to :MOVE_IT and performs the move. Otherwise, the user is warned and given an opportunity to cancel.