Batch File Programming

From FactotumNW Wiki

Jump to: navigation, search

Advanced Batch Programming - From the Basics to Recursivity

Written by: FoolFox Published by: SAJChurchey Published on: 2005-11-17 00:09:46

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 
       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 " 
       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 
   echo This is the help 

The IF statement can also be used in conjunction with the 'errorlevel' variable, a variable which handles the result of the last program executed.

   if errorlevel 0 goto OK 
   echo We have a problem! 
   goto End 
   echo WOW! Everything went smooth! 

  • 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 
   COPY c:temp%3 c:temp2%3 
   type c:temp2%3 
   echo ----------------------------------------------------------------------- 

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 
   COPY c:temp%3 c:temp2%3 
   type c:temp2%3 
   echo ----------------------------------------------------------------------- 

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 > 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 

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'. 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:


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:


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...

Personal tools