You are on page 1of 5

Advanced Batch Programming - From the Basics to Recursivity

Well, in times where most of end-users face computers through windowed systems, many of us may still need to get some tasks done through a more basic interface . . . You can find many introduction papers to the basics of batch programming, but this time, we'll try to go a little bit beyond that up to recursive batch programming. But, before digressing too much, here's a quick review of common commands that you can issue within a batch. Commands To get help on the format of commands, type <command> /? into your command windows:

ATTRIB--Change file attributes


attrib +r+h test.txt

The previous command sets read-only and hidden attributes on the file test.txt. CLS--Clear the screen EXIT--Close the command session. Self explanatory I think. FOR--Initiate a loop. See below for a sample FIND--Allows you to search for text in one or more files, allows you to search for specific files in memory, retrieving BIOS info. . . GOTO--Branch flow to a known label
goto Step1 echo this one is never printed :Step1 echo this one is printed

IF--Allows for conditional statements


if exist autoexec.bat echo Found!

The previous command prints Found! on the screen if the file autoexec.bat is in the current dir. MORE--Allows you to print output screen by screen
type help.txt | more

MOVE--Move a file SET--Define environment variable


set msg="Welcome " msg2=%msg%%username% echo msg2

The previous batch sets one variable, creates a second one by concatenating the first variable with the username, and finally prints the result to the screen.

SHIFT--I'm pretty sure you were not as much aware of this one, a real nice trick, SHIFT allows you to move a parameter one step to left in a batch file. START--Start the execution of a program in a new window. The user can select the type of window: maximized, minimized, or title, priority class for the running progam, or run it without any window. You can even WAIT for the process to terminate before executing your next batch instruction. TYPE--Output file to default As you can see, most of those commands are in fact little executables that are run when requested by a batch file. Understand that you can issue ANY command or file name in a batch file, and it will be run. The usage of some of these commands will be explained later. Symbols that can be used %--Using a % allows the use of variables inside a batch @--Adding an at (@) in front of a command prevents the command from being echoed on the screen. For example, @DIR will execute DIR without showing the DIR command on one line. >--Adding a > at the end of a command allows you to redirect the output. Overwriting the file in case of redirection to a file. Output can be a file result, text shown by the batch, etc. For example, DIR a: > test.txt will output content of dir into the file test.txt. >>--Adding >> at the end of a command allows you to redirect the output. Appending in the case of redirection to a file.
@DIR a: > test.txt ;will output content of the dir in the file test.txt) @DIR c: >> test.txt ;will append c: dir to previous file)

NUL - Null Device. Everything that is redirected to this devices as its output is sent to trash.
@DIR c: /s > NUL ( will output dir of the whole HD (using /s) on NUL device. Lot of work, nothing is shown)

< - Adding a < at the end of a command allow to pass the part at the right of the "<" symbol (command, file, etc...) as parameter for the first command. ex :
debug < file.txt (will send command in file.txt to the debugger)

| - Send output of the command to the input of another program ex :


mem /c |find "MOUSE" (will execute mem /c and send output to find.exe which will output only lines containing 'MOUSE')

Advanced Batching: Now, let's play a little with basic commands we have seen before. The FOR loop
for %%f in (*.*) do echo There is a file called: %%f

The previous command initiates a loop that searches for all file names in the current directory (*.*). All files found are then shown. Using this command you'll get a

list of files found in current directory. Of course, you can be more specific in the location specification, or in the command. The following line will silently copy the content of %windir%repair to a floppy :
for %f in (%windir%repair*.*) do @copy %f a:

There is also a feature to use standard FOR loops with counters


for /L %i in (1,1,5) do echo counter: %i

The /L switch specifies that we are working with numbers. This loop will start at 1, use increment of 1, and will do the loop up to 5. Of course you can send all results to a file :
for /L %i in (1,1,5) do echo counter: %i > result.txt

The IF statement The IF statement can be used to check if a condition is true or not. This statement can work with variables, or parameters sent to the batch:
if [%1]==[/?] goto ShowHelp goto Continue :ShowHelp echo This is the help :Continue

The IF statement can also be used in conjunction with the 'errorlevel' variable, a variable which handles the result of the last program executed.
RunProg.exe if errorlevel 0 goto OK echo We have a problem! goto End :OK echo WOW! Everything went smooth! :End

SHIFTing parameters This can be useful when you have more than 10 parameters to pass to the batch file. Parameters are handled by batch files through escaped digits %0...%9. %0 contain the name of the batch file. If you have more than 9 parameters to go through, you can use the SHIFT command. This command will shift down each argument (%1 become %0, %2 become %1.... %9 gets a new param). For each SHIFT, %0 disappears. Once shifted out, an argument cannot be recovered.

Recursive batch files This one is really nifty. You can make recursive batch jobs using escaped digits. Let's take an example. I want to check all files in folder c:temp, if not existing in c:temp2 then the batch have to copy the file, then dump content to the screen (type).
echo off %1 %2 for /F "tokens=1 delims= " %%i in ('dir /A-D /B c:temp*.*') do if not exist c:temp2%%i call %0 goto step1 %%i goto end :step1 COPY c:temp%3 c:temp2%3 type c:temp2%3 echo ----------------------------------------------------------------------:end

The point here to see is : call %0 goto step1 %%i within the DO command. We just ask the batch to call itself supplying goto and step1 as args %1 and %2. Now guess what the %1 %2 line does.... we could have done it in a much better way, like selecting in which case we have to perform the command :
echo off if "%1" == "()" goto %2 for /F "tokens=1 delims= " %%i in ('dir /A-D /B c:temp*.*') do if not exist c:temp2%%i call %0 () step1 %%i :step1 COPY c:temp%3 c:temp2%3 type c:temp2%3 echo ----------------------------------------------------------------------:end

This way you can add several conditions at startup..... Creating ASM files using batch files: Yeah. Even creation of asm files is possible through a batch-job. Let's see the following batch :
@echo off echo n prog.com > file1.txt echo a 0100 mov ah,09 >> file1.txt echo a 0102 mov dx,0109 >> file1.txt echo a 0105 int 21 >> file1.txt echo a 0107 int 20 >> file1.txt echo a 0109 db 'hello world!$ >> file1.txt echo rcx >> file1.txt echo 16 >> file1.txt echo w >> file1.txt echo q >> file1.txt debug < file1.txt del file1.txt prog

At first, we are killing all echoing to the screen (echo off), this command itself is not shown. Then we create a file called file1.txt, of which the first line will be 'n prog.com'. This is a command for the debugger, defining the name of the executable to create. We then append several lines to the file file1.txt, which contain all assembly instruction to be compiled by the debugger (yeah, debug.exe, one of the fabulous tools you'll be able to find on EVERY windows installation, is also able to ASSEMBLE!!. I'm pretty sure you'll see those little dos exe in a different way now..). Current program will just print 'hello world' using INT 21h. Last lines include commands for the debugger (echo w = write file for the debugger, echo q = quit for the debugger, etc..) Then we compile our file ( debug < file1.txt ), delete the source and run the result.

How to close the console at the end of a batch job : You probably have already faced those command windows that stay wide open while the title say "Finished - xxxx". Instead of letting the user close the window himself, you can use the following command at the end of your batch:
@cls

When the batch is terminated, and the command screen remain blank, the system closes the window.

Using var as modifying code: We have seen that the use of the symbol % allow us to use a variable as a parameter. The fun thing here is that you can also use it as a command. Look at the following batch:
@%sign%cls

now, define sign as an empty variable (set sign= ). Run the batch; it will execute the command. Now if you define sign as a command (set sign=REM), you can run the batch the line will not be executed. How to get a list of all .bat files on HD : Yeah, How to do so? Everybody knows the dir /s command, for sure, but there are more subtle ways to do it:
@echo off chkdsk /v | find /i ".bat" > res.txt type res.txt | more del res.txt

The /v option of chkdsk allows us to see each filename in every directory as the disk is checked. This list is piped through the find command, /i parameter is used to ignore case, and the %1 parameter specifies what we search for. Basically, everything. Warning, this will work when chkdsk output the file names. Won't work under NTFS. As Find will launch a new process each time it's called, we can't use it more efficiently. It won't work at all, in fact, each find command outputs one line to more, which print the line before returning to the loop. Using a temporary file to circumvent this. I hope having covered all what is needed to go a little beyond the basics, if you are interested in further inspecting this area, I strongly encourage you to turn your hear in the direction of batch virii, even if the domain is not ethical, they contain some nasty tricks that can help you learn a lot about what you are able to do with a batch file...

You might also like