All About IBM Batch Files (COMPUTE! Magazine Sept/Oct 1985 by G. Russ Davies) A batch program is simply a disk file containing a series of DOS commands. The batch file executes these commands in sequence, just as if you manually typed them. The most familiar batch program is AUTOEXEC.BAT which is used to issue startup commands to configure the system and runs automatically when you turn on the system. To run a batch program that doesn't automatically run, simply enter the filename at the DOS prompt. This tells DOS to load the batch file from disk and carry out each of its commands in order. For example, to run a program named SETUP.BAT you would type SETUP after the DOS prompt and press Enter. The DOS manual explains how to type in short batch programs using the COPY CON: command from DOS. However, for any batch program longer than a few lines, it's easier to use a word processor or any text editor that creates standard ASCII files. You can also use the DOS EDLIN program, though it lacks the convenient editing featuers of word processors. A batch program can end by returning control to DOS, or by running a second batch program (permitting you to "chain" two or more programs together). For instance, ending a batch program with SECOND causes the system to load and run the batch program named SECOND.BAT. You can also use COMMAND /C to run one batch program from with another, i.e., COMMAND /C SECOND runs SECOND.BAT. Passing parameters (information) to a batch program is simple. Just include the needed information after the filename when running the program. For example, typing FIRST JULIA 123 runs the FIRST.BAT program and passes two parameters to it: a string (JULIA) and a number (123). In much the same way, one batch program can pass parameters to another. Let's use an example to demonstrate parameter passing in chained programs. Enter the following FIRST.BAT program and save it to disk: ECHO OFF ECHO FIRST.BAT USES FIRST PARAMETER: %1 ECHO PASSES %2 AND %3 TO SECOND.BAT REM SECOND %2 %3 Now enter and save SECOND.BAT: ECHO SECOND.BAT USES SECOND PARAMETER: %1 ECHO PASSES %2 TO THIRD.BAT THIRD %2 Finally, enter and save THIRD.BAT: ECHO THIRD.BAT USES THIRD PARAMETER: %1 At this point you have three batch programs, all of which expect parameters. To run the programs, enter FIRST followed by any three strings or numbers. Be sure to separate each parameter with a space. For instance, you might enter FIRST PARAM/ONE &H464 IBMBIO.COM. The FIRST.BAT programs takes in all three parameters, processing the first (displaying it in an ECHO statement) and passing the other two when it runs SECOND. SECOND.BAT process the second parameter and passes the third to THIRD.BAT. As shown in these examples, batch programs use dummy parameters (% followed by a digit from 0-9) to mark the spot where the real parameter is expected. When you run a batch program, each dummy parameter is replaced by actual data in the order it is received. Thus, the FIRST.BAT programs above uses %1 to signify the first parameter, %2 to represent the second, and so on. Dummy parameter %0 can only be replaced by a drive designator (A or B) and filename; don't use it unless you want to pass such information. Be sure to keep the dummy parameters numbers straight when chaining batch programs. The dummy number represents the order in which that program receives the data. In the example above, FIRST.BAT received three parameters, which it represents with the three dummies %1, %2 and %3. SECOND.BAT receives two parameters, using %1 to signify the first parameter it receives, and %2 to represent the second. Likewise, THIRD.BAT uses %1 to represent its single parameter. (Note that THIRD.BAT can't use %3 for the dummy. Though you may think of this parameter as the "third," it's the first one that THIRD.BAT receives. In addition to ordinary DOS commands, a batch program may include the following special batch commands: ECHO, FOR, GOTO, IF, SHIFT, PAUSE, and REM. ECHO ON causes DOS commands to be displayed as they're performed in a batch program; ECHO OFF turns off the display. As you say above, ECHO can also display messages. GOTO is discussed later. REM lets you include remarks, and SHIFT is used when more than ten parameters are passed at one time. The remaining commands (FOR, IF and PAUSE) permit loops, conditional tests and limited user input. The short file copying program below demonstrates all three of these commands. Enter the program and save it with the file name COPYUNQ.BAT. ECHO OFF REM--------------------------------------------------------------- REM name: COPYUNQ.BAT REM syntax: COPYUNQ source-drive-letter target-drive-letter (no colons) REM purpose: Only unique files are copied from source to target disk REM--------------------------------------------------------------- %1: FOR %%f in (*.*) DO IF exist %2:%%f ECHO %%f WILL NOT BE COPIED PAUSE READY TO BEGIN COPIES, FOR %%f in (*.*) DO IF not exist %2:%%f COPY %1:%%f %2:/V %2: The COPYUNQ.BAT program automatically copies files from a source disk to a target disk, copying only those files that don't already exist on the target disk. This ensures that existing files are not replaced, an improvement over DOS's COPY command, which would write over any like-named files on the target disk. To run this program, enter its name followed by the letter of the source drive and the letter of the target drive. Colons are not required after the drive letters. For instance, you would enter COPYUNQ.BAT A B when drive A holds the source disk and drive B holds the target disk. The program displays the names of files that are not copied. COPYUNQ.BAT offers a good demonstration of FOR and IF, which work differently than their BASIC equivalents. Since a FOR statement can't contain another FOR statement, you can't use nested FOR loops (one FOR loop enclosed by another). FOR statements take the following form: FOR %%variable IN (set) DO DOS command The set value after IN represents a group of files and must be some variation of a filename and extension. This parameter determines which disk files the FOR loop will affect. Since the pattern-matching symbols * and ? can be used, you may define this group to be very broad or very selective. The program shown above uses the statement IN (*.*) to affect the broadest possible group: every file on the disk. In other cases, you might use IN (*.BAS) to affect all files ending with .BAS, IN (ABC*.*) to affect all files starting with ABC, and so on. The first FOR statement in COPYUNQ.BAT (FOR %%f IN (*.*) DO) affects every file on the disk. As the FOR loop executes, the variable %%f represents each filename in order. Translated into plain English, this statement means "cycle through every filename on the source disk, using %%f to represent each filename in turn." IF can perform only a few tests. One of these (IF EXIST filename) tests whether a given file exists on the disk. Now you can understand the second part of the FOR statement (IF EXIST %2:%%f). The %2 parameter is a dummy, replaced by the second drive letter you entered when running the program. And the variable %%f is replaced by actual filenames when the program runs. In plain English, this statement means "if the current filenames exists on the disk in the target drive ...." Batch programs don't have the equivalent of BASIC's THEN statement (THEN is implied). But in other respects IF processing works much as it does in BASIC. Statements that come after the IF test (on the same line) are performed when the IF test is true, and skipped when the test is false. Consequently, in COPYUNQ.BAT, the ECHO command (which prints "filename WILL NOT BE COPIED") executes only when the file in question exists on both the source and target disks. Once you understand that much of COPYUNQ.BAT, the rest is not hard to decipher. PAUSE makes the system stop and display the message "Strike any key when ready." This is the only batch command that allows user input. Unfortunately, your choices are severely limited: You can continue only by pressing a key (perhaps after changing disks, etc.) or end the program by pressing Ctrl-Break. The number of options can be expanded as is explained below. The second FOR line in COPYUNQ.BAT has a FOR loop and an IF test very similar to the first. However, in this case NOT reverses the logic of the IF test. When the named file does not exist on the target disk, the IF test is true and the file is copied. In addition to testing EXIST (with or without NOT), IF can test two conditions: the equality symbol (==) and ERRORLEVEL. The equality symbol tests whether two strings are identical. ERRORLEVEL is always a number, ordinarily used to pass information from one program to another (indicating whether the first worked successfully and thus set ERRORLEVEL to the expected value). ERRORLEVEL is discussed further below. Batch programs have their limitations. Visual displays are often unexciting, consisting of single-color alphanumerics (no graphics characters, etc.), and user input is even more restricted. The PAUSE command allows only two options: continuing after the pause or ending the program. This virtually rules out complex, interactive programs that let you select from several different options to perform various tasks. The CHOOSE.COM program provides the equivalent of a new batch command. As the name suggests, CHOOSE lets you make a choice. It can be used by itself to request a yes/no response, or with additional information to offer several different options. Type, save and run the CHOOSE.BAS program below, and you can try out the simpler "yes/no" form of CHOOSE. An AUTOEXEC.BAT program that doesn't include the DOS commands DATE and TIME won't prompt you to enter the date and time (as normally happens when you boot up). Though it's often valuable to have correct date and time information on new files, there are also many times when you don't need it. The batch program that follows lets you choose whether to add date and time settings. Save this file with the filename AUTOEXEC.BAT. Because the program calls CHOOSE.COM, you must save it on a disk that contains CHOOSE.COM. ECHO OFF MODE CO80 ECHO Do you wish to set the date/time? REM Press Y,y,N, or n to answer CHOOSE IF ERRORLEVEL 1 GOTO :setdt GOTO :next :setdt DATE TIME :next CHKDSK BASICA MENU Run it by rebooting the system. When used without parameters, CHOOSE checks for a yes/no response, permitting uppercase as well as lowercase Y and N. Other responses (except Ctrl-Break) cause the prompt message to be displayed until a valid choice is made. After you respond with yes or no, CHOOSE passes this information to the batch program via ERRORLEVEL. In this example, CHOOSE sets ERRORLEVEL to 1 when the response is yes, and 0 when the response is no. The GOTO command then branches appropriately. Note that GOTO branches to a destination label, which is a colon followed by a string. This program uses the labels :setdt and :next. Don't confuse the label :next with BASIC's NEXT statement (which doesn't exist in batch programming). In this case, ERRORLEVEL can have only one or two possible values, but it can take higher values as well. When testing ERRORLEVEL with IF, keep in mind that the IF ERRORLEVEL statement is true when ERRORLEVEL is greater or equal to the number being tested. If you tested for 0 first in this program, ERRORLEVEL would always be 0 (1 and 0 are both greater than or equal to 0). When testing ERRORLEVEL, you must always test for higher values before testing for lower ones. Most utility programs offer a variety of options. Typically, they display a menu with a list of options, and you choose the option you want by pressing a certain key. CHOOSE makes it easy to present such menus within a batch program. First display the options on the screen, then use CHOOSE followed by a list of the keys you wish to test. For instance, the statement CHOOSE ABC checks the A, B, and C keys and returns appropriate values in ERRORLEVEL. The ERRORLEVEL value corresponds to the position of the key in the list after the CHOOSE command. Thus, after the program performs CHOOSE ABC, ERRORLEVEL equals 1 if A was pressed, 2 if B was pressed, and so on. When using CHOOSE with several option keys, it's critical to list the keys in the right order. Since you must always test for higher ERRORLEVEL values before testing for lower ones, you'll want to put the most likely (or most speed-critical) options at the end of the option key list. This assigns higher ERROELEVEL values to the more important ones. The FILES.BAT program demonstrates multiple-option selection as well as a colorful, attractively formatted menu and help panel. It sorts any disk directory by file size, date, filename extension, or alphabetical order, and can also create separate files for mass DOS operations. Entering the program requires several steps: 1. Make sure your disk contains the system file called ANSI.SYS. This file contains the screen/keyboard driver used for graphics displays and temporary key assignments. 2. Make sure your disk contains a file named CONFIG.SYS that includes the statement DEVICE=ANSI.SYS. If your disk doesn't have one a CONFIG.SYS file, create one by entering these lines: COPY CON:CONFIG.SYS DEVICE=ANSI.SYS 3. Enter FILES.BAT as shown below. Several lines in the listing contain the characters {Ctrl-P}. The braces indicate that this is a special control character which you must enter by pressing a combination of keys. Do not type the braces. Instead, wherever you see {Ctrl-P} in the listing, hold down the Ctrl key and press the P key. On the screen, you'll see the wedge-shaped control character that precedes special ANSI.SYS screen or keyboard instructions. 4. Enter and save the FILES.MNU file (do not use any other filename). This file is graphics date for the menu. Whenever you see {Ctrl-P} in the listing, enter Ctrl-P as described above. A number enclosed in braces indicates a graphics character (the number is an ASCII code) which you must enter with the Alt-keypad technique on the PC. For instance, where the listing contains {218}, hold down the Alt key, then type the characters 2, 1, and 8 on the numeric keypad. When you release the Alt key, character 218 appears on the screen. When the braces enclose two numbers, several characters are needed; the first value shows how many characters to enter, and the second is the ASCII code. For instance, where you see {5 196}, use the above procedure to enter character 196 five times. Where you see the letters SP followed by a number and enclosed in braces, you should type the space bar the indicated number of times. For example, {SP 16} means to type 16 spaces. 5. Enter and save the FILES.HLP file (don't use any other filename). This file contains graphics date for the Help screen. 6. Enter a batch program that contains nothing but a REM statement and save it with the filename QUIT.BAT, i.e.: COPY CON:QUIT.BAT REM ANYTHING Press the F6 key and Enter. 7. Enter and save the FILEGRP.BAS program. 8. Finally, before using FILES.BAT, check your disk to make sure all the necessary files are present. IT must contain CHOOSE.COM, ANSI.SYS, CONFIG.SYS, FILES.BAT, FILES.HLP, FILES.MNU, FILEGRP.BAS, and QUIT.BAT. The program will not work correctly unless all these files are on one disk and named as shown. Note that the FILEGRP option (see below) also requires BASIC. Before you run this program, reboot the system so that the ANSI.SYS driver is present. To run FILES.BAT, enter FILES at the DOS prompt and press Enter. Most of the program is self-explanatory; that's what the menus and help screens are for. The FILEGRP option lets you create a separate batch file (named FILEGRP.BAT) for performing operations on a group of files. Every line in FILEGRP.BAT consists of a filename from the subject disk and four dummy parameters in this order: %1 filename.extension %2 %3 %4 Dummy parameters are replaced by actual parameters you supply when running FILEGRP.BAT. This makes it easy to perform the same operation (copy, print, delete, etc.) on a large group of files. After using the FILEGRP option, exit to DOS and use a word processor to edit FILEGRP.BAT as needed, deleting the names of any files you don't want to include in the operation. Then run FILEGRP.BAT by entering its name followed by the needed parameters. The first parameter can be any DOS command; the rest will be parameters that are relevant to that command. For instance, you might enter FILEGRP COPY B:/V to copy the files listed in FILEGRP.BAT onto drive B. Incidentally, BASIC does not provide any way to set ERRORLEVEL. FILES.BAT employs several techniques you may find useful. The DOS command BREAK ON makes the system respond to Ctrl-Break in more instances than normal. The TYPE command is used to display graphics like the menu and help screen. TYPE creates such displays much faster than the DOS ECHO command (you could also use COPY). The ANSI.SYS driver assigns the lowercase keys a, s, d, e, b, and i to their uppercase equivalents to reduce the amount of testing required. The F1 and F10 keys are assigned to keys H and X, respectively, so those function keys perform their usual HELP and EXIT roles. After CHOOSE accepts a response, the modified keys are restored to their original definitions. Pressing Ctrl-Break while CHOOSE is active (or pressing Y in response to "Terminate batch file?") leaves these keys reassigned. To avoid this effect, you should normally exit by pressing F10. The F10 (EXIT) functions uses a trick to perform a quick exit. It simply runs QUIT.BAT, a batch program that consists of a do-nothing REM statement. When any batch program ends, it ends all preceding batch programs as well. Note that since ECHO OFF is in effect when QUIT.BAT is called, the REM is not displayed. Batch commands are not particularly fast. To optimize speed, structure the program so that the most-often used (or speed-critical) routines are closest to the place you're branching from. The fewer program lines that a GOTO has to skip over, the quicker it executes. You can also speed up batch programs by using extra disk buffers as explained in the DOS Manual. REM statements slow batch programs drastically; if you want to document the program, store your comments in a separate file. In some cases it's useful to test for the absence of a parameter. For instance, you might want to re-prompt the user with a message like "You must enter more information." This can be done with a statement such as IF .--%1.GOTO.NOPARM. This line means "if a dot equals the parameter plus a dot then go to the no-parameter routine." The IF test is true only when no parameters have been entered. CHOOSE.BAS (to create CHOOSE.COM): 100 OPEN "CHOOSE.COM" FOR OUTPUT AS #1 110 READ X$:IF X$="/*" GOTO 130 120 PRINT #1,CHR$(VAL("&H"+X$));:GOTO 110 130 CLOSE #1:END 140 DATA A0,80,0,3C,0,75,2D,90,BA,60,1,B4,9,CD,21,B4 150 DATA C,B0,7,CD,21,3C,59,74,F,3C,4E,74,10,3C,79,74 160 DATA 7,3C,6E,74,8,EB,E1,90,B0,1,EB,3,90,B0,0,B4 170 DATA 4C,CD,21,90,BA,80,1,B4,9,CD,21,B4,C,B0,8,CD 180 DATA 21,88,C4,90,BD,0,0,45,8A,86,80,0,3C,D,74,E4 190 DATA 38,E0,75,F3,89,E8,90,48,B4,4C,CD,21,90,90,90,90 200 DATA 43,68,6F,6F,73,65,20,59,20,28,79,65,73,29,20,6F 210 DATA 72,20,4E,20,28,6E,6F,29,20,2E,2E,2E,D,A,24,20 220 DATA 43,68,6F,6F,73,65,20,64,65,73,69,72,65,64,20,6F 230 DATA 70,74,69,6F,6E,20,2E,2E,2E,D,A,24,0,0,0,0 240 DATA /* FILES.BAT: echo off rem Name: FILES.BAT [filename.ext] See help panel for usage break on dir %1 >temp.dir :menu cls type files.mnu echo{Ctrl-P}["a";"A"p{Ctrl-P}["s";"S"p{Ctrl-P}["d";"D"p{Ctrl-P} ["e";"E"p{Ctrl-P}["b";"B"p{Ctrl-P}["i";"I"p echo{Ctrl-P}[0;59;"H"p{Ctrl-P}[0;68;"X"p{Ctrl-P}[2A choose EIBSDHAX echo{Ctrl-P}["a";"a"p{Ctrl-P}["s";"s"p{Ctrl-P}["d";"d"p{Ctrl-P} ["e";"e"p{Ctrl-P}{"b";"b"p{Ctrl-P}["i";"i"p echo{Ctrl-P}[0;59;0;59p{Ctrl-P}[0;68;0;68p{Ctrl-P}[0m if errorlevel 8 QUIT if errorlevel 7 goto :a if errorlevel 6 goto :h if errorlevel 5 goto :d if errorlevel 4 goto :s if errorlevel 3 goto :b if errorlevel 2 goto :i goto :e :a cls sort /+1 con pause goto :menu :h copy files.hlp con pause goto :menu :d cls sort /+24 con pause goto :menu :s cls sort /+14 /R con pause goto :menu :b basic filegrp echo ---------- FILEGRP.BAT Created ---------- pause goto :menu :i cls dir %1 /p pause goto :menu :e cls sort /+10 con pause goto :menu FILES.MNU: {Ctrl-P}[2J {Ctrl-P}[32m {SP 16}{218}{5 196} {Ctrl-P}[33m DIRECTORY DISPLAYS MENU {Ctrl-P} [32m{5 196}{191} {SP 16}{179}{SP 35}{179} {SP 16}{179}{Ctrl-P}[35m A {Ctrl-P}[32m- Alphabetical order by filename {179} {SP 16}{179}{SP 35}{179} {SP 16}{179}{Ctrl-P}[35m E {Ctrl-P}[32m- Ext name order{SP 17}{179} {SP 16}{179}{SP 35){179} {SP 16}{179}{Ctrl-P}[35m D {Ctrl-P}[32m- Date order, Yr not significant {179} {SP 16}{179}{SP 35}{179} {SP 16}{179}{Ctrl-P}[35m S {Ctrl-P}[32m- Size order{SP21}{179} {SP 16}{179}{SP 35}{179} {SP 16}{179}{Ctrl-P}[35m B {Ctrl-P}[32m - Bat file creation: FILEGRP.bat {179} {SP 16}{179}{SP 35}{179} {SP 16}{179}{Ctrl-P}[35m I {Ctrl-P}[32m- Intrinsic order of dir entries {179} {SP 16}{179}{SP 35}{179} {SP 16}{179}{Ctrl-P}[35mF1 {Ctrl-P}[32m- HELP{SP 27}{179} {SP 16}{179}{SP 35}{179} {SP 16}{179}{Ctrl-P}[35mF10 {Ctrl-P}[32m- EXIT{SP 27}{179} {SP 16}{179}{SP 35}{179} {SP 16}{192}{36 196}{217} {Ctrl-P}[31m FILES.HLP: {Ctrl-P}[44;33m{Ctrl-P}[2J{Ctrl-P}[1m {SP 7}{210}{15 205} {Ctrl-P}[35m DIRECTORY DISPLAY HELP {Ctrl-P}[33m {16 205}{187} {SP 7}{186}{SP 2}PURPOSE: Procudes a directory listing{SP 17}{186} {SP 7}{186}{SP 12}sorted in the desired order.{SP 16}{186} {SP 7}{186}{SP 2}SYNTAX:{SP 2}FILES [d:][filename][.ext]{SP 20}{186} {SP 7}{186}{SP 9}(if parameters are omitted, *.* used){SP 10}{186} {SP 7}{186}{SP 56}{186} {SP 7}{186}{sp 2}MENU OPTIONS:{SP 41}{186} {SP 7}{186}{SP 4}A: Directory sorted ascending by filename){SP 11}{186} {SP 7}{186}{SP 4}E: Directory sorted ascending by file extension {SP 5}{186} {SP 7}{186}{SP 4}D: Directory sorted ascending by file date (mm-dd) {SP 2}{186} {SP 7}{186}{SP 7}giving calendar order, year least significant {SP 4}{186} {SP 7}{186}{SP 4}S: Directory sorted DESCENDING by file size{SP 9}{186} {SP 7}{186}{SP 7}allowing quick determination of largest files {SP 4}{186} {SP 7}{186}{SP 4}B: FILEGRP.BAT created as : %1 filename.ext %2 %3 %4 {186} {SP 7}{186}{SP 7}for editing and mass file copy, erase, type, etc. {186} {SP 7}{186}{SP 4}I: Directory in the order of the directory entries {SP 2}{186} {SP 7}{186}{SP 56}{186} {SP 7}{186}{SP 4}H or F1: Displays this help panel{SP 19}{186} {SP 7}{186}{SP 4}X or F10: Fast exit to DOS{SP 26}{186} {SP 7}{200}{56 205}{188}{Ctrl-P}[0m FILEGRP.BAS: 10 'This program creates a batch file named FILEGRP.BAT using the 20 'TEMP.DIR file created by FILES.BAT. FILEGRP.BAT is useful for 30 'group file operations such as copying, deleting, printing, etc. 40 'Each line in FILEGRP.BAT has the format: %1 filename.ext %2 %3 %4 50 'Use a word processor or text editor to delete non-participating 60 'files from FILEGRP.BAT. 70 OPEN "temp.dir" FOR INPUT AS #1 'input file 80 OPEN "filegrp.bat" FOR OUTPUT AS #2 'output file 90 FOR X=1 TO 4:IF EOF(1) THEN SYSTEM 'skip 4-line header 100 LINE INPUT #1,X$:NEXT 110 IF EOF(1) THEN SYSTEM 'check for end-of-file 120 LINE INPUT #1,X$ 'get input line 130 IF LEFT$(X$,1)=" " GOTO 110 'skip lines beginning with space 140 Z=INSTR(X$," "):Z=Z-1 'find length of filename 150 PINRT #2,"%1 ";MID$(X$,1,Z);".";MID$(X$,10,3);" %2 %3 %4" 160 GOTO 110 'continue til end-of-file