| < Day Day Up > |
|
Normally, the Windows command shell executes scripts line by line, starting at the beginning of the file and continuing until the end of the file. You can change the order of execution and to do this, you use either of the following:
Subroutines With subroutines, you jump to a label within the current script, and execution proceeds to the end of the file.
Procedures With procedures, you call another script and execution of the called script proceeds to the end of its file, and then control returns to the line following the call statement in the original script.
As you can see, the difference between a subroutine and a procedure is primarily in what you want to do. Additionally, while arguments passed in to the script are available in a goto subroutine directly, the list of arguments within a called procedure is changed to include the procedure name rather than the script name as argument 0 (%0).
Subroutines have two parts:
A goto call that specifies the subroutine to which you want to jump
A label that designates the start of the subroutine
Consider the following subroutine call:
if "%1"=="1" goto SUB1
Here if the first parameter passed into the script is a 1, the subroutine called SUB1 is called and the command shell would jump to the corresponding subroutine label. To create a label, you enter a keyword on a line by itself, beginning with a colon, such as
:SUB1
Although labels can contain just about any valid type of character, you’ll usually want to use alphanumeric characters as this makes the labels easy to read when you or someone else is going through the code.
When you use goto, execution of the script resumes at the line following the target label and continues to the end of the file, unless it’s necessary to process any procedure calls or goto statements encountered along the way. If the label is before the current position in the script, the command shell can go back to an earlier part of the script. This can create an endless loop (unless there is a control to bypass the goto statement). Here’s an example of an endless loop:
:START
.
.
.
goto START
If the label is after the goto statement, you can skip commands and jump ahead to a new section of the script, such as
goto MIDDLE
.
.
.
:MIDDLE
Here, execution of the script jumps to the :MIDDLE label and continues to the end of the file. You cannot go back to the unexecuted commands unless you use another goto statement.
Sometimes you may not want to execute the rest of the script and instead will want to exit the script after executing subroutine statements. To do this, create an exit label and then go to the exit at the end of the routine, such as
goto MIDDLE
.
.
.
:MIDDLE
.
.
.
goto EXIT
.
.
.
:EXIT
Listing 3-4 shows a detailed example of working with goto and labels. In this example, the value of the script’s first parameter determines what subroutine is executed. The first if statement handles the case when no parameter is passed in by displaying an error message and exiting. The goto EXIT statement following the if statements handles the case when an invalid parameter is passed in. Here, the script simply goes to the :EXIT label.
Listing 3-4: Using goto
@echo off
if "%1"=="" (echo Error: No parameter passed with script!) & (goto
EXIT)
if "%1"=="1" goto SUBROUTINE1
if "%1"=="2" goto SUBROUTINE2
if "%1"=="3" goto SUBROUTINE3
goto EXIT
:SUBROUTINE1
echo In subroutine 1
goto EXIT
:SUBROUTINE2
echo In subroutine 2
goto EXIT
:SUBROUTINE3
echo In subroutine 3
goto EXIT
:EXIT
echo Exiting...
Tip | Remember if the label you call doesn’t exist, you’ll get an error when the end of the file is reached during the search for the nonexistent label, and then the script exits without executing the other subsequent commands. Old-school command-shell programmers who have been at this for a long time, like me, like to use goto EXIT and then provide an actual :EXIT label, as shown in the previous example. However, the command interpreter for Windows Server 2003 and Windows XP supports a target label of :EOF, which transfers control to the end of the file. This makes :EOF an easy way to exit a batch script without defining a label. |
You use procedures to call other scripts without exiting the current script. When you do this, the command shell executes the named script, executing its commands, and then control returns to the original script, starting with the first line following the original call. Consider the following example:
if "%1"=="1" call system-checks
if "%1"=="2" call C:\scripts\log-checks
Caution | If you forget to use the call statement and reference a script name within a script, the second script executes, but control isn’t returned to the caller. |
Here the first call is made to a script expected to be in the current working directory or in the command path. The second call is made to a script with the file path c:\scripts\log-checks.
Any arguments passed to the original script are passed to the called script with one change: The list of arguments is updated to include the procedure name as argument 0 (%0). These procedure-specific arguments remain in effect until the end of the file is reached and control returns to the original script.
You can also pass arguments to the called script, such as
set Arg1=mailer1
set Arg2=dc2
set Arg3=web3
call system-checks Arg1 Arg2 Arg3
Now within the called script, the variables Arg1, Arg2, and Arg3 are available.
| < Day Day Up > |
|