Batch files are, in essence, command-line commands typed into a text file rather than typed directly at the command prompt. You can tell the command shell to read this text file and interpret its commands as if you were typing them. This serves several purposes:
Batch files can also use primitive programming commands to handle varying situations: "if a particular situation arises, do this, otherwise , do that" or "repeat this step for every file in a certain folder." Creating and Editing Batch FilesYou can place batch files in any folder you want. You can place them on your own hard drive, or you may want to place your batch files on a shared network folder so they can be used from any computer. I place my personal batch files in a folder named c:\bat and put this folder in the PATH so that I can run them by name from any command prompt. Regardless of their folder location, batch files should be given the extension .CMD or .BAT . Either is fine. The .BAT extension is more traditional, whereas .CMD makes it clear that the batch file is written for Windows NT/2000/XP, because DOS and Windows 9x will not recognize such files as batch files. To create a sample batch file, open a Command Prompt window or use the one opened earlier in this section. Type the command notepad test.bat and then click Yes when Notepad asks, Do you want to create a new file? In the empty Notepad window, type the following lines: @echo off cls echo The command line argument is %1 pause Save the file and at the command line type: test xxx The Command Prompt window should clear, and you should see the following: The command line argument is xxx Press any key to continue . . . Press Enter, and the command prompt should return. You can use this same procedure to create any number of batch files. Later, if you want to edit the files, you can use the name notepad command to open and modify the files and make changes. One batch file you may want to create right now is named bat.bat , with this one line inside: pushd c:\bat With this file in place, if you type bat at any command prompt, your current directory will be instantly changed to c:\bat so that you can edit or create new batch files. Type popd to go back to whatever directory you were using beforehand. Of course, you could just type pushd c:\bat directly. It may seem silly to create a batch file just to save nine keystrokes, but when you're actively developing batch files, you'll quickly find that this really does make life easier. I have about a dozen batch files like this that I use on a daily basis to move into directories for specific projects. For projects that use special command-line programs, the batch file has a second line that adds the program directory to the beginning of the search path, using a command such as this: path c:\some\new\folder;%path% If you find yourself frequently working with command-line programs, you will want to make "tiny handy batch files" for your projects as well. Batch File ProgrammingThe following sections discuss programming techniques that take advantage of the extended commands provided by the cmd shell. The commands that are most useful in batch files are listed in Table 9.12. Table 9.12. Batch File Commands
If you've written batch files for DOS, Windows 9x, and Windows NT, you'll find that most of these commands have been significantly enhanced, so even if you are familiar with these commands, you should read the discussions in this chapter, and check out the online Command Line Reference in Windows Help and Support. Argument SubstitutionMany times you'll find that the repetitive tasks you encounter use the same programs and steps, but operate on different files each time. In this case, you can use command-line arguments to give information to the batch file when you run it. When you start a batch file from the command line with a command such as batchname xxx yyy zzz any strings after the name of the batch file are made available to the batch program as arguments. The symbols %1, %2, %3 , and so on are replaced with the corresponding arguments. In this example, anywhere that %1 appears in the batch file, cmd replaces it with xxx . Then, %2 is replaced with yyy , and so on. Argument substitution lets you write batch files like this: @echo off notepad %1.vbs cscript %1.vbs This batch file lets you edit and then run a Windows Script Host program. If you name the batch file ws.bat , you can edit and test a script program named, say, test.vbs just by typing this: ws test In this case, cmd treats the batch file as if it contained the following: @echo off notepad test.vbs cscript test.vbs This kind of batch file can save you many keystrokes during the process of developing and debugging a script. Note The command @echo off at the top of a batch file keeps cmd from printing out each of the program steps as it encounters them. This reduces "clutter" in the Command Prompt window. If your batch file is behaving in some way you don't understand, you can temporarily change this to @echo on , to see the steps as they are run. Besides the standard command-line arguments %1, %2 , and so on, you should know about two special argument replacements : %0 and %*. %0 is replaced with the name of the batch file, as it was typed on the command line. %* is replaced with all the command-line arguments as they were typed, with quotes and everything left intact. If I have a batch file named test.bat with the contents @echo off echo The command name is %0 echo The arguments are: %* then the command test a b c will print the following: The command name is test The arguments are: a b c %0 is handy when a batch file has detected some problem with the command-line arguments the user has typed and you want it to display a "usage" message. Here's an example: if "%1" == "" ( rem - no arguments were specified. Print the usage information echo Usage: %0 [-v] [-a] filename ... exit /b ) If the batch file is named test.bat , typing test would print out the following message: Usage: test [-v] [-a] filename ... The advantage of using %0 is that it will always be correct, even if you rename the batch file at a later date and forget to change the "usage" remarks inside. Argument Editingcmd lets you modify arguments as they're replaced on the command line. Most of the modifications assume that the argument is a filename and let you extract or fill in various parts of the name. You might want to use this feature when, say, a batch file argument specifies a Microsoft Word file with the .DOC extension, and you want the batch file to construct a new filename with the same root name but a different extension. When command extensions are enabled, cmd can insert edited versions of the arguments by placing a tilde ( ~ ) and some additional characters after the % sign. The editing functions let you manipulate filenames passed as arguments. Table 9.13 lists the edit options, using argument number 1 as an example. Table 9.13. Argument Editing Expressions
For example, if I ran a batch file with the argument "under the hood.doc" , the results might be as follows :
Here's how these features might be used: Suppose I have a series of files that I need to sort . The input files could come from any folder, but I want to store the sorted files in C:\sorted and give them the extension .TAB regardless of what the original extension was. I can write a batch file named sortput.bat to do this: @echo off sort <%1 >c:\sorted\%~n1.tab The sort command will read the file as I've specified it on the command line, but the output file will use only the base part of the input file's name. If I run the command sortput "c:\work files\input.txt" the substituted command will be sort <" c:\work files\input.txt " >c:\sorted\ input .tab Conditional Processing with ifOne of the most important capabilities of any programming language is the ability to choose from among different instructions based on conditions the program finds as it runs. For this purpose, the batch file language has the if command. The Basic if CommandIn its most basic form, if compares two strings and executes a command if the strings are equivalent: if string1 == string2 command This is used in combination with command-line variable or environment variable substitution, as in this example: if "%1" == "ERASE" delete somefile.dat If and only if the batch file's first argument is the word ERASE , this command will delete the file somefile.dat . The quotation marks in this command aren't absolutely required. If they are omitted and the command is written as if %1 == ERASE delete somefile.dat the command will still work as long as some command-line argument is given when the batch file is run. However, if the batch file is started with no arguments, %1 would be replaced with nothing, and the command would turn into this: if == ERASE delete somefile.dat This is an invalid command. cmd expects to see something before the == part of the command and will bark if it doesn't. Therefore, it's a common practice to surround the items to be tested with some characterany character. Even $ will work, as shown here: if $%0$ == $ERASE$ delete somefile.dat If the items being tested are identical, they will still be identical when surrounded by the extra characters. If they are different or blank, you'll still have a valid command. The if command also lets you reverse the sense of the test with the not option: if not "%1" == "ERASE" then goto no_erase Checking for Files and FoldersThe exist option lets you determine whether a particular file exists in the current directory: if exist input.dat goto process_it echo The file input.dat does not exist pause exit /b :process_it Of course, you can specify a full path for the filename if that's appropriate, and you can use environment variables and % arguments to construct the name. If the filename has spaces in it, you'll need to surround it with quotes. The not modifier can be used with exist as well. Tip The exist test only checks for files, not folders. However, the special file nul appears to exist in every folder. You can perform the test if exist c:\foldername\nul command to see whether the folder c:\foldername exists. Checking the Success of a ProgramWhen a command line or even a Windows program exits, it leaves behind a number called its exit status or error status value. This is a number that the program uses to indicate whether it thinks it did its job successfully. An exit status of zero means no problems; larger numbers indicate trouble. There is no predetermined meaning for any specific values. The documentation for some programs may list specific error values and give their interpretations, which means that your batch files can use these values to take appropriate action. How? Through the errorlevel variation of the if command. After running a command in a batch file, an if statement of the form if errorlevel number command will execute the command if the previous program's exit status value is the listed number or higher . For example, the net use command returns if it is able to map a drive letter to a shared folder, and it will return a nonzero number if it can't. A batch file can take advantage of this as follows: @echo off net use f: \bali\corpfiles if errorlevel 1 goto failed echo Copying network data... if not exist c:\corpfiles\nul mkdir c:\corpfiles copy f:\*.xls c:\corpfiles exit /b :failed echo Unable to access network share \bali\corpfiles pause You can also use not with this version of the if command. In this case, the command is executed if the error status is less than the listed number. The error testing in the previous example can be rewritten this way: if not errorlevel 1 goto success echo Unable to access network share \bali\corpfiles pause exit /b :success echo Copying network data... if not exist c:\corpfiles\nul mkdir c:\corpfiles copy f:\*.xls c:\corpfiles In this version, the flow of the batch file is a bit easier to follow. However, even this can be improved upon, as you'll see next . Grouping Commands with ParenthesesOften, you'll want to execute several commands if some condition is true. In the old days, before the extended cmd shell came along, you would have to use a goto command to transfer control to another part of the batch file, as in the if exist example given in the previous section. With the extended version of if , this is no longer necessary. The extended if command lets you put more than one statement after an if command, by grouping them with parentheses. For example, you can place multiple commands on one line, as shown here: if not errorlevel 1 (echo The network share was not available & exit /b) Or you can put them on multiple lines: if not errorlevel 1 ( echo The network share was not available pause exit /b ) I recommend the second version, because it's easier to read. Look how much clearer the network file copying example becomes when parentheses are used instead of goto : @echo off net use f: \bali\corpfiles if errorlevel 1 ( echo Unable to access network share \bali\corpfiles pause exit /b ) echo Copying network data... if not exist c:\corpfiles\nul mkdir c:\corpfiles copy f:\*.xls c:\corpfiles You can also execute one set of commands if the if test is true and another if the test is false by using the else option, as in this example: if exist input.dat echo input.dat exists else echo input.dat does not exist You can use else with parentheses, but you must take care to place the else command on the same line as if , or on the same line as the closing parenthesis after if . You should write a multiple-line if...else command using the same format as this example: if exist input.dat ( echo Sorting input.txt... sort <input.txt >source.data ) else ( echo Input.txt does not exist. Creating an empty data file... echo. >source.data ) Extended TestingThe extended if command lets you perform a larger variety of tests when comparing strings, and it can also compare arguments and variables as numbers. The extended comparisons are listed in Table 9.14. Table 9.14. Comparison Operators Allowed by the if Command
As a bonus, if the strings being compared contain only digits, cmd compares them numerically . For example, you could test for a specific exit status from a program with a statement like this: some program if %errorlevel% equ 3 ( echo The program returned an exit status of 3 which echo means that the network printer is offline. ) Processing Multiple ArgumentsWhen you have many files to process, you may get tired of typing the same batch file commands over and over, like this: somebatch file1.dat somebatch file2.dat somebatch file3.dat ... It's possible to write batch files to handle any number of arguments on the command line. The tool to use is the shift command, which deletes a given command-line argument and slides the remaining ones down. Here's what I mean: Suppose I started a batch file with the command line batchname xxx yyy zzz Inside the batch file, the following argument replacements would be in effect before and after a shift command:
This lets a batch file repeatedly process the item named by %1 and shift until %1 is blank. To process a variable number of command-line arguments, use the shift command to delete arguments until they're all gone, as in this example: @echo off if "%1" == "" ( rem if %1 is blank there were no arguments. Show how to use this batch echo Usage: %0 filename ... exit /b ) :again rem if %1 is blank, we are finished if not "%1" == "" ( echo Processing file %1... rem ... do something with file %1 here rem - shift the arguments and examine %1 again shift goto again ) If you want to have the program process a default file if none is specified on the command line, you can use this variation of the pattern: @echo off if "%1" == "" ( rem - no file was specified - process the default file "test.for" call :process test.for ) else ( rem - process each of the named files :again rem if %1 is blank, we are finished if not "%1" == "" ( call :process %1 rem - shift the arguments and examine %1 again shift goto again ) ) exit /b :process echo Processing file %1... . . . In this version, if no arguments are specified on the command line, the script will process a default filein this case test.for . Otherwise, it will process all files named on the command line. This version of the pattern uses batch file subroutines, which are discussed later in this chapter under "Using Batch Files Subroutines." The extended version of the shift command, shift / n , lets you start shifting at argument number n , leaving the lower-numbered arguments alone. The following illustrates what shift /2 does in a batch file run with the command "batchname xxx yyy zzz" :
In actual use, you might want to use this feature if you need to have the batch file's name ( %0 ) available throughout the batch file. In this case, you can use shift /1 to shift all the remaining arguments, but keep %0 intact. You may also want to write batch files that take a command line of the form batchname outputfile inputfile inputfile ... with an output filename followed by one or more input files. In this case, you could keep the output filename %1 intact but loop through the input files with shift /2 , using commands like this: @echo off rem be sure they gave at least two arguments if "%2" == "" ( echo Usage: %0 outfile infile ... exit /b ) rem collect all input files into SORT.TMP if exist sort.tmp del sort.tmp :again if not "%2" == "" ( echo ...Collecting data from %2 type %2 >>sort.tmp shift /2 goto again ) rem sort SORT.TMP into first file named on command line echo ...Sorting to create %1 sort sort.tmp /O %1 del sort.tmp Working with Environment VariablesAlthough environment variables were initially designed to hold system-configuration information such as the search path, they are also the "working" variables for batch files. You can use them to store filenames, option settings, user input from prompts, or any other information you need to store in a batch program. The set command is used to set and modify environment variables. However, you should know that, by default, changes to environment variables made in a batch file persist when the batch file finishes because the variables "belong" to the copy of cmd that manages the Command Prompt window and any batch files in it. This is great when you want to use a batch file to modify the search path so that you can run programs from some nonstandard directory. However, it's a real problem if your batch file assumes that any variables it uses are undefined (empty) before the batch file starts. Here's a disaster waiting to happen: @echo off set /p answer=Do you want to erase the input files at the end (Y/N)? if /i "%answer:~,1%" EQU "Y" set cleanup=YES ... more commands here ... then, at the end, if "%cleanup%" == "YES" ( rem they wanted the input files to be erased del c:\input\*.dat ) If you respond to the prompt with Y , the environment variable cleanup will be set to YES , and the files will be erased. However, the next time you run the batch file, cleanup will still be set to YES , and the files will be erased no matter how you answer the question. Of course, the problem can be solved by adding the statement set cleanup= at the beginning of the batch file. In fact, good programming practice requires you to do so in any case (you should always initialize variables before using them), but the point is still important: Environment variables are "sticky." In the old DOS days, a batch file program would usually add set statements to the end of batch files to delete any environment variables used by the program. However, cmd provides an easier method of cleaning up. If you plan on using environment variables as working variables for a batch file, you can use the setlocal command to make any changes to the variables "local" to the batch file. At the end of the batch file, or if you use an endlocal command, the environment will be restored to its original state at the time of the setlocal command. It would be prudent to put setlocal at the beginning of any batch file that does not require its environment changes to persist outside the batch file itself. Environment Variable EditingAs with the old command.com , in any command, strings of the form %var% are replaced with the value of the environment variable named var . One of cmd's extensions is to let you modify the environment variable content as it is being extracted. Whereas the edits for command-line arguments are focused around filename manipulation, the edits for environment variables are designed to let you extract substrings. The following types of expressions can be used:
Using the environment variable var=ABCDEFG , here are some examples:
Expressions of the form %name: str1 = str2 % replace every occurrence of the string str1 with str2 . str2 can be blank to delete all occurrences of str1 . You can start str1 with an asterisk (*) , which makes cmd replace all characters up to and including str1 . Using the environment variable var=ABC;DEF;GHI , here are some examples:
The first example listed is particularly useful if you want to use the PATH list in a for loop; for wants to see file or folder names separated by spaces, whereas PATH separates them with semicolons. I'll discuss this in more detail later on. Processing Multiple Items with the for CommandYou'll often want to write batch files that process "all" of a certain type of file. Command-line programs can deal with filename wildcards: For example, you can type delete *.dat to delete all files whose names end with .dat . In batch files, you can accomplish this sort of thing with the for loop. Note If you have a UNIX background, the need for special statements to deal with wildcards may seem confusing at first. On UNIX and Linux systems, the command shell expands all command-line arguments with wildcards into a list of names before it starts up the command, so to the command it appears that the user typed out all of the names. This is called globbing . On DOS and Windows, the shell doesn't do this. When command-line arguments contain wildcard characters, it's up to the command or batch file to expand the name into a list of filenames. The basic version of the for command scans through a set or list of names and runs a command once for each. The format for batch files is for %%x in ( set of names ) do command where set of names is a list of words separated by spaces. The for command executes command once for each item it finds in the set. At each iteration, variable x contains the current name, and any occurrences of %%x in the command are replaced by the current value of x . You can choose any alphabetic letter for the variable name. Also, upper- and lowercase matters, meaning a and A are different to the for command. Note When you type a for command directly at the command prompt, you only use single percent signs. In a batch file, you must double them up. Otherwise, they confuse cmd because they look sort of like command-line arguments. cmd could have been written to know the difference, but it wasn't, so we're stuck with this. For example, the command for %%x in (a b c d) do echo %%x prints four lines: a , b , c , and d . What makes for especially useful is that if any item in the set contains the wildcard characters ? or * , for will assume that the item is a filename and will replace the item with any matching filenames. The command for %%x in (*.tmp *.out *.dbg) do delete %%x will delete any occurrences of files ending with .tmp , .out , or .dbg in the current directory. If no such files exist, the command will turn into for %%x in () do delete %%x which is fine...it does nothing. To get the same "silent" result when specifying the wildcards directly in the delete command, you would have to enter if exist *.tmp delete *tmp if exist *.out delete *.out if exist *.dbg delete *.dbg because delete complains if it can't find any files to erase. As another example, the command [View full width]
prints a list of all faxes received from the Windows Fax service and the time they were received. Note If you use variable substitution edits, choose as your for variable a letter that you don't need to use as one of the editing letters. for stops looking at the editing expression when it hits the for variable letter. For instance, in the example, if I had needed to use the ~f editing function, I would have had to choose another variable letter for the for loop. The extended for command lets you scan for directories, recurse into subdirectories, and several other useful things that you can't do any other way. Using Multiple Commands in a for Loopcmd lets you use multiple command lines after a for loop. This makes the Windows XP for command much more powerful than the old DOS version. In cases where you would have had to call a batch file subroutine in the past, you can now use parentheses to perform complex operations. For example, this batch file examines a directory full of Windows bitmap (BMP) files and makes sure that there is a corresponding GIF file in another directory; if the GIF file doesn't exist, it uses an image-conversion utility to create one: @echo off setlocal echo Searching for new .BMP files... for %%F in (c:\incoming\*.bmp) do ( rem output file is input file name with extension .GIF set outfile=c:\outgoing\%%~nF.gif if not exist %outfile% ( echo ...Creating %outfile% imgcnv -gif %%F %outfile% ) ) Therefore, every time you run this batch file, it makes sure there is a converted GIF file in the \outgoing folder for every BMP file in the \incoming folder. This sample script uses several of the techniques we've discussed in this chapter:
A batch file like this can make short work of maintaining large sets of files. You might accidentally overlook a new file if you were trying to manage something like this manually, but the batch file won't. As a final example, the following handy batch file tells you what file is actually used when you type a command by name. I call this program which.bat , and when I want to know what program is run by, say, the ping command, I type the following: which ping The batch file searches the current folder, and then every folder in the PATH list. In each folder, it looks for a specific file, if you typed a specific extension with the command name, or it tries all the extensions in the PATHEXT list, which contains .EXE , .COM , .BAT , and the other usual suspects : @echo off if "%1" == "" ( echo Usage: which command echo Locates the file run when you type 'command'. exit /b ) for %%d in (. %path%) do ( if "%~x1" == "" ( rem the user didn't type an extension so use the PATHEXT list for %%e in (%pathext%) do ( if exist %%d\%1%%e ( echo %%d\%1%%e exit /b ) ) ) else ( rem the user typed a specific extension, so look only for that if exist %%d\%1 ( echo %%d\%1 exit /b ) ) ) echo No file for %1 was found As you can see, the for command lets you write powerful, useful programs that can save you time and prevent errors, and the syntax is cryptic enough to please even a Perl programmer. Delayed ExpansionEnvironment variables and command-line arguments marked with % are replaced with their corresponding values when cmd reads each command line. However, when you're writing for loops and compound if statements, this can cause some unexpected results. For example, you might want to run a secondary batch file repeatedly with several files, with the first file handled differently, like this: call anotherbatch firstfile.txt FIRST call anotherbatch secondfile.txt MORE call anotherbatch xfiles.txt MORE You might want to do this so that the first call will create a new output file, while each subsequent call will add on to the existing file. You might be tempted to automate this process with the for command, using commands like this: set isfirst=FIRST for %%f in (*.txt) do ( call anotherbatch %%f %isfirst% set isfirst=MORE ) The idea here is that the second argument to anotherbatch will be FIRST for the first file and MORE for all subsequent files. However, this will not work. cmd will replace %isfirst% with its definition MORE when it first encounters the for statement. When cmd has finished processing % signs, the command will look like this: set isfirst=FIRST for %%f in (*.txt) do ( call anotherbatch %%f FIRST set isfirst=MORE ) Because FIRST is substituted before the for loop starts running, anotherbatch will not see the value of isfirst change, and the result will be call anotherbatch firstfile.txt FIRST call anotherbatch secondfile.txt FIRST call anotherbatch xfiles.txt FIRST which is not at all what you wanted. There is a way to fix this: Delayed expansion lets you specify environment variables with exclamation points rather than percent signs, as an indication that they are to be expanded only when cmd actually intends to really execute the command. Because ! has not traditionally been a special character, this feature is disabled by default. To enable delayed expansion, specify /V:ON on the cmd command line or use SETLOCAL to enable this feature inside the batch file. The statements setlocal enabledelayedexpansion set isfirst=FIRST for %%f in (*.txt) do ( call anotherbatch %%f !isfirst! set isfirst=MORE ) will work correctly. Although delayed expansion is disabled by default in Windows XP, you can change the default setting through the Registry key HKLM\Software\Microsoft\Command Processor\EnableExtensions . If this DWORD value is present and set to , command extensions are disabled by default. Any nonzero value for EnableExtensions enables them. Another place delayed expansion is useful is to collect information into an environment variable in a for list. The following batch file adds c:\mystuff and every folder under it to an environment variable named dirs : setlocal ENABLEDELAYEDEXPANSION set dirs= for /R c:\mystuff %%d in (.) do set dirs=!dirs!;%%d The for statement recursively visits every folder, starting in c:\mystuff , and %%d takes on the name of each folder in turn. The set statement adds each directory name to the end of the dirs variable. Using Batch Files SubroutinesThe cmd shell lets you write batch file subroutines using the call command. Although the new capability to group statements with parentheses makes batch file subroutines somewhat less necessary than they were in the past, the subroutine is still an important tool in batch file programming. For example, in a task that involves processing a whole list of files, you might write a batch file subroutine to perform all the steps necessary to process one file. Then, you can call this subroutine once for each file you need to process. In the old days of command.com , batch file subroutines had to be placed in separate .BAT files. You can still do this, but with cmd, you can also place subroutines in the same file as the main batch file program. The structure looks like this: @echo off rem MAIN BATCH FILE PROGRAM ------------------------ rem call subroutine "onefile" for each file to be processed: cd \input for %%f in (*.dat) do call :onefile %%f subroutine called here rem main program must end with exit /b or goto :EOF exit /b rem SUBROUTINE "ONEFILE" --------------------------- :onefile echo Processing file %1... echo ... commands go here ... exit /b The call command followed by a colon and a label name tells cmd to continue processing at the label. Any items placed on the call command after the label are arguments passed to the subroutine, which can access them with %1 , %2 , and so on. The original command-line arguments to the batch file are hidden while the call is in effect. Processing returns to the command after the call when the subroutine encounters any of these conditions:
Normally, any of these conditions would indicate the end of the batch file, and cmd would return to the command prompt. After call , however, these conditions end the subroutine, and the batch file continues. Caution You must be sure to make the main part of the batch file stop before it runs into the first subroutine. In other scripting languages such as VBScript, the end of the "main program" is unmistakable, but in the batch file language it is not. You must use goto :EOF or exit /B before the first subroutine's label; otherwise, cmd will plow through and run the subroutine's commands again. Tip When I have a bunch of files that I have to process in some way, I often don't like to use the for command. Instead I use the command dir /b >filename.bat to create the beginnings of the batch file. I edit the batch file with Notepad and put call :process before each filename. I put @echo off at the top. At the bottom, I put the lines goto :EOF :process echo Processing file %s... ... (commands go here) The reason I go to this trouble is that I can manually delete from the list any files that I want to skipyou can't do that with for !. And if I have to interrupt the procedure before it finishes, I can delete the call lines for any files that had already been processed, or use a goto to skip over them, before running the batch file again. Prompting for InputIf your batch file has to print a message you definitely don't want the users to miss , use the pause statement to make the batch file sit and wait until they've read the message and acknowledged it. Here's an example: echo The blatfizz command failed. This means that the world as echo we know it is about to end, or, that your input file needs to echo be corrected. pause exit /b If you want to ask a user whether to proceed after a mishap, or if you want the batch file to prompt for input filenames or other data, you can use the new extended set /p command. set /p reads a user's response into an environment variable, where it can be tested or used as a command argument. Here's an example: :again echo The input file INPUT.DAT does not exist set /p answer=Do you want to create it now (Y/N)? if /i "%answer:~,1%" EQU "Y" goto editit if /i "%answer:~,1%" EQU "N" exit /b echo Please type Y for Yes or N for No goto again These commands ask the user to type a response, examine the leftmost letter with %answer:,1% , and take the appropriate action only if the user types a valid response. To prompt a user for a yes/no answer, use a series of commands following this pattern: :again echo If the question is long or requires an explanation, echo use echo commands to display text before the question. set /p answer= Ask the question here (Y/N)? if /i "%answer:~,1%" EQU "Y" command to execute for Yes if /i "%answer:~,1%" EQU "N" command to execute for No echo Please type Y for Yes or N for No goto again Put a single space after the question mark on the set /p command. If you use this pattern more than once in the same batch file, be sure to use a different label for each one. I used again in this version, but you can use any word as the label. If the work that has to be done given either the Yes or No answer is more than a few commands (placed in parentheses), you can use be a goto :label command to continue execution in another part of the batch file. You can modify this pattern to create a menu. You can write a prompt like this: echo Options: [A]dd, [D]elete, [P]rint, [Q]uit, [H]elp" set /p answer=Enter selection: In this example, instead of comparing the response to the letters Y and N, you would compare it to A, D, P, Q, and H. |