|Batchfile Commands||Redirection Commands|
|IF||> Redirecting Output|
|IF ERRORLEVEL||> > Redirecting and Appending|
|IF string1==string2||< Redirecting Input|
|IF EXIST filename||| The Pipe|
|FOR IN DO||Other Commands|
|CALL||@ Blocking Output of Commands|
|GOTO||%string% Environment Variables|
C:\dir > lpt1 (press enter)
Assuming that you have a printer connected too your computer, you'll now have a copy of your directory on paper. Lets take a look at what happened. First, you told the computer to list a directory with the command `dir'. Next, you redirected the output (With the > symbol) to your printer, lpt1 (Local printer 1).
Lets say that you want to get a copy of several directories in one text file. You would use >>. What it does is redirect
output of a command into the end of a text file
without copying over anything in it. This is how it would look:
C:\> dir >> list.txt
C:\DOS> dir >> C:\list.txt
C:\123> dir >> C:\list.txt
C:\> dir >> list.txt
C:\DOS> dir >> C:\list.txt
C:\123> dir >> C:\list.txt
In the first line, we just put a directory listing into a file named list.txt
In the next line, a copy of our DOS directory was appended to the
end of the list file in the root directory. The third line did
the same with the 123 directory.
It would be more likely that you would output the
contents of a file to your printer. The file needs to a standard ASCII text file
(HTML source code for example) or contain mostly ASCII text for this to work right.
This involves using the TYPE command in
conjunction with the > symbol. Type the following at the DOS prompt:
C:\type file.txt > lpt1
C:\type file.txt > lpt1
Normally when you use TYPE with a file, it will dump the contents of the file to the screen. In our use of it, it dumped the contents of the file to the printer. If you want to learn more about the TYPE command, go to my `DOS Internal Commands' page.
C:\date < datefile.txt
This is what happened: we issued the date command which stops and asks for the date. Then we used the < symbol to direct a response from a file called `datefile.txt'. The datefile.txt just contained simple ASCII text (The date) and a carriage return like this:
5-23-97 Some ideas on use: if you have a batchfile menu system and have a command that formats a disk- make it start formatting without bothering you with the `Are you sure (Y,N)?' prompt. (Note- this may do more harm that good. I know that this prompt has saved me several times when I had the wrong disk in drive A:). A devious person might use this to a destructive end. You know how DOS asks you `Are you sure (Y/N)?' when you delete all files in a directory with DEL *.*? Well, you can redirect input, the letter y and a carriage return, into it and delete all files automatically. (The same is true for the FORMAT command). If someone were to insert that sequence of events into your AUTOEXEC.BAT file or something....
This command may be confused with > (Redirecting a programs output to a text file). Remember, > sends output to a plain text file, that's all. The pipe allows one programs output to be used as another's input. In my next example I will use this feature in a unique way to delete all files on a disk or directory.
C:\ECHO Y | DEL *.*
Lets go step by step through this. ECHO Y does just that. It echoes a Y on the next line down. But wait; that Y is redirected into the DEL *.* command. Remember, if you issue the command DEL *.* DOS will give you the question "Are you sure?" and/or "All files in the current directory will be deleted! Continue?". Only this time it gets its answer from the ECHO command. The pipe can be used with just about ALL DOS programs that have some type of output to the screen. Here is a more common application of the pipe command:
C:\TYPE EXAMPLE.TXT | MORE
TYPE usually dumps the contents of a file to your screen (To learn more about the TYPE command go to myDOS Internal Commands Page) but we have piped it into the MORE command (To learn more about the MORE command go to my DOS External Commands page). MORE then dumps the file (one page at a time) to your screen and prompts you to hit a key to scroll the page-full of text.
@BACKUP C:\WP51\*.WP1 A:
It's silly to put an @ECHO OFF command above the backup command (This is assuming you DON'T want to see the output).
This is a very useful thing to use. Suppose you create a batch file that will install some programs on a friends computer, but you don't know what drive they would like it on (if they have a hard drive with multiple partitions or something). You could have the drive letter entered after the file name on the command line like this:
A:\install.bat D: (D: is any value substituted by the user)
Now lets look at what was in the batch file.
COPY *.* %1\STUFF
To begin with, you need to know how DOS parses the command line. It considers the name of the program %0. Any value after that is %1, %2, ect. up to %9. If you need more that 9 parameters to be entered on one command line refer to the SHIFT command. Now, back to our batch example. What happened was the batch file looked for something to replace the %1 with and that was the D: (%1). Now, did you notice that I used the %1 parameter in the next line also? It replaced the drive letter so that it could copy the files on the floppy disk to the drive specified on the command line. Now, lets examine a more complicated batch file.
COPY %1 %2
This is how you use this batch file:
C:\MOVEIT C:\WP51\*.BK! A:\WPBAKUPS
MOVEIT is the name of the batch file. Now we have two variables that can be replaced. First, the program looks to see what files are to be copied specified by %1, and then copies them to the place specified by %2. Next up it deletes the files it originally copied (Anything specified by the %1 variable).
You can use replaceable parameters in a batch file anywhere
that a program or command needs input to work correctly.
Ok, here's another example. It's much more complex:
LABEL < %2
MD %1 %3
COPY C:\TEMP\*.BAK %3
Sorry, I had to throw in the > redirection sign to make the label
command work right. Here's what the batch file did:
C:\do_it.bat B: do_it.bat
Formatted a disk in the drive of your choice
Labeled it with the name of your choice
Made a directory with the name of your choice
Copied all *.BAK files in your TEMP directory to the directory that was made on the disk Here's how to use it:
B: ---Letter of drive the disk was in
TEMP_BACKUP --Name to label disk by
PHILES ---Name of directory to make on disk
C:\do_it.bat B:TEMP_BACKUP PHILES
do_it.bat---The name of our batch file
In order to set environment variables, you must use the SET command (See DOS Internal Commands page). Well, this is a tuff one to explain, so hang on. Type the word SET at the command prompt. You will get a list of parameters like this:
BLASTER=A220 I5 D1 H5 T6 P330
These are mostly conditions setup from within your AUTOEXEC.BAT file. If you look through it you should see a line for most of them like this:
(To learn more about the PATH or PROMPT command visit my DOS Internal Commands Page .) Your settings will vary depending on whether you have Windoze 95 or other programs. Some programs use these settings to determine where to put their temporary files. Other programs use environment variables for other things. Here I will go into how to use them with batch files. Suppose that you what a variable to stay the same from one batch file to the next. If you set it as an environment variable you can call upon it any time after you set it up. With DOS 6 and up you can now set up a simple menu system in your config.sys file that allows you to install different device drivers (For instance- say that you run a tape back-up at the end of every month- but the device driver takes a long time to set up. You don't want to wait through that every time you turn on your computer, so you can now select to install it only when you want to use it). When you install the device driver it can also set an environment variable that your AUTOEXEC.BAT can pick up on (Using an IF statement) and your AUTOEXEC.BAT can go ahead and start the backup. For more information on doing this, check out Config.sys Menu Setup.
This is one of the neater batch commands. It allows a more
"Programy" feel to a batch file. Here's the way to use it:
IF [not] ERRORLEVEL [number] [command]
IF [not] string1 == string2 command
IF [not] EXIST filename [command]
The [not] lets you choose whether you want an action taken when a condition is not met. In the first IF statement the [number] refers to a specific error level returned by a program. Most programs return some kind of an error level depending on how things went for the program. For example, BACKUP returns the following error levels depending on how the backup went:
IF [not] ERRORLEVEL [number] [command]
0 The backup was successful
1 No files were found to back up
2 Some files were not backed up because of file-sharing conflicts
3 The user pressed CTRL-C to stop the process
4 The process stopped because of some other type of error
Now, you'll never see these numbers on your screen. You have to write a batch file to call the BACKUP utility and use the error levels accordingly. Here's an example:
BACKUP C:\*.* A: /S
IF ERRORLEVEL 4 GOTO ERROR
IF ERRORLEVEL 3 GOTO ABORT
IF ERRORLEVEL 2 GOTO CONFLICT
IF ERRORLEVEL 1 GOTO NO_FILES
IF ERRORLEVEL 0 GOTO SUCCESS
ECHO BACKUP STOPPED THE PROCESS DUE TO SOME KIND OF ERROR
ECHO YOU PRESSED CTRL+C TO STOP THE BACKUP
ECHO SOME OF YER FILES WERN'T BACKED UP BECAUSE OF FILE SHARING CONFLICTS
ECHO SORRY BOUTCHA, THERE WEREN'T ANY FILES FOUND TO BACKUP
ECHO YER BACKUP WAS FULLY SUCCESSFUL
:EXIT Go back to the top of this page if you don't understand some of other commands used in this batch file. Sooner or later I'll get a page up about EXTERNAL COMMANDS, otherwise called DOS Utilities. In it will be EVERY DOS UTILITY and all known error levels returned by them if applicable.
IF [NOT] string1==string2 command
Here, the string can be an environment setting (environment string) or a replaceable parameter. Here's an example:
IF %DIRCMD% == /W/P GOTO DOES
ECHO DIRCMD IS NOT SET TO /W/P PRESS ANY KEY TO SET IT TO /W/P
ECHO OR CONTROL-C TO NOT SET IT.
ECHO DIRCMD was already set to /W/P
First off, the batch file checks for an environmental string (Check out the usage of the SET command on the Internal Commands List for an explanation of DIRCMD). Environment strings MUST be enclosed in %dollar_signs%. If %DIRCMD% is equal to /w/p it jumps down to the end of the file and nothing is done. But, if %DIRCMD% isn't equal to /w/p, it pauses and asks if you would like to set it to that. If you go ahead with it, it uses the SET command to set %DIRCMD% to /w/p. There are many ways to use this to your advantage, so get crazy with it!
This instance tests for the existence of files. Wild card variables like * and ? work as well. Lets say you want your autoexec to check for a file on your CD-ROM and execute it if it exists.
IF EXIST D:\GAMEMENU.EXE GOTO GAME
ECHO No Games Found
This will run the program GAMEMENU.EXE on drive D: IF it is there on boot-up. It is possible to test for the existence of a directory or drive by using the following trick:
IF EXIST D:\GAMES\NUL CALL D:\GAMES\DOOM
This will check for a games directory and run DOOM if the games directory is found. Also, remember you can use NOT so an action is preformed when a condition is NOT met. And last but not least, there is the undocumented feature of being able to test for DEVICE DRIVERS with IF EXIST. Here's the syntax:
IF EXIST [device driver name] [command]
You will need to use MEM or an equivalent memory checker to see what is in your memory. You can check for any COM or LPT that is physically on your computer, but you can't check for devices on these ports (At least in THIS method) as you will get a true response for the port only. This works on all versions of DOS 5.0 and greater as far as I know. If you should find it to work on 3.3 or not working on certain versions, please let me know. I will post it in this section.
FOR THE TECHIES out there, here is why you can abuse the IF EXIST command so much. DOS sees the NUL driver and all other DEVICE DRIVERS as files existing in ALL directories. So, you can test for the existence of a directory by testing for the NUL file within it. In fact, you could test to see if a directory and a device driver co-exist at the same time. Off the top of my head I can't think of a reason to do this, but that option is available. Also, you can nest the IF command as many times as you can fit onto one command line. It is possible to go beyond the command line length, but it has been reported to cause unusual behavior. As always, any input will be posted in its appropriate section.
@IF EXIST D:\GAMES\DOOM.EXE CALL C:\DOS\GAMEMENU.BAT
Another "useful" part of CALL is you can put a major change in an AUTOEXEC file without it being as noticeable. Say you want to help prevent some tampering on a public computer. You can add a single CALL command to run another batchfile in a directory that is inaccessible even to most hackers. This "called" batchfile might copy all .INI files back into the WINDOWS directory, preventing any changes made before the last boot-up to be circumvented (See my Secrets page for more on this.
Ok, %%x is a variable. Any letter will suffice here (No numbers, they are reserved
for command line variables within the set. See
Substitution for more on replaceable parameters). Side note: you can use
FOR IN DO from the command line but you need only one % after FOR. SET is any group of
files. They can be represented by substituted variables (%1 %2 %3), environment strings
(%string1% %string2%), or just plain file names (test.txt junk.* doom.exe test?.old).
Notice that wildcards are also valid. You can have ONLY ONE delimiter between each file within
the set (IE. one space: (test1.txt test2.txt test3.txt)). Also, the set MUST be enclosed
within () parentheses. COMMAND is almost any command, batchfile, or program that you
need to run.
NOTICE: the following commands WILL cause problems if they are not dealt with
GOTO - Since a batchfile will resume running from the point specified in the LABEL of the GOTO, it will break any FOR IN DO. That doesn't mean there isn't a way around this, you just have to be crafty in your programming. If you need a "subroutine" to be called by several FOR IN DO's you might just have to write a separate batchfile containing the subroutine and use CALL to invoke it.
FOR - When you try to nest a FOR IN DO you will get an error when you try to run your batchfile (It will say "For cannot be nested"). In order to get around this you need to call a second command interpreter (Use COMMAND.COM as the command). THEN you can start another FOR IN DO. Example:
FOR %%A IN (nest1 nest2) DO COMMAND/C FOR %%B IN (one two) DO ECHO %%A %%B
When you try to run this file you will notice that even though @ECHO OFF was used all processes after starting COMMAND.COM are echoed to the screen. That is because ECHO is set ON when COMMAND starts. I'll have more on using FOR IN DO later on, SORRY.
IF %DIRCMD%==%1 GOTO YES
ECHO DIRCMD isn't set to %1
ECHO DIRCMD was already set to %1
Here, GOTO is a command used by IF. If the environment variable is set to %1 the batchfile will jump down to the label :YES and perform all commands after it (Unless it meets another GOTO statement). If DIRCMD is NOT equal to %1 the condition is FALSE and the GOTO command will NOT be issued. The batchfile simply falls through to the next command, which is ECHO. After ECHOing "DIRCMD isn't..." another GOTO is met, and makes the batchfile jump to the :END label. Since there are not any commands after the :END label the batchfile ends.
IF "%1"=="" GOTO END
COPY %1 %TODIR%
This is how it works: SET makes the variable TODIR equal %1. Now, TODIR will equal
%1 no matter
what %1 is (If %1 is stuff.txt and %2 is text.txt, then a shift occurs, %1 will now be
text.txt). Ignore :GETFILE for now, well get to that later. Since we have saved %1 (Which
would be the name of the directory we are copying to) we can now
use SHIFT without loosing any data. The IF command finds out if there are any files to
copy. If %1 doesn't exist after the SHIFT then that means the user didn't
specify any files to copy and the batchfile skips to the end of the program. If there are
files to copy then the IF statement is FALSE and execution of our batchfile resumes on the
next line down, skipping the GOTO. Our next line copies the file specified in %1 to the
directory represented by %TODIR%. GOTO GETFILE sends batchfile execution back up above
SHIFT, so a SHIFT occurs. This pattern will continue forever, or at least until our IF
statement finds %1 equal to nothing. When this happens execution is jumped down to the label
:END. Then SET clears the environment variable %TODIR% so no extra memory is wasted after
our batchfile is done running.
Well, there are a million different ways to use SHIFT, so get wild and crazy and abuse it to the fullest extent of the law. Ok, maby it's not that useful, but it can help you out once in a while.
This might get on your nerves if you have to copy files to another directory and can't see all of your commands on one line. ECHO OFF will suppress that nasty path listing until ECHO ON is issued.
ECHO can also be handy with redirection.
REM a comment for myself
REM set %1==%DIRCMD%
REM ECHO Don't Do This! > testfile.txt It is my understanding that DOS redirects text after a REM statement to the NUL device (Correct me if I'm wrong). Well, in our example "ECHO Don't Do This!" is redirected into the NUL device. Then output is expected from the NUL device to go into a file named "testfile.txt". Since the NUL device has no output your batchfile will make an empty text file named "testfile.txt". There are many other unexpected things that can go wrong if you REM out a line with redirectors in it. Got it? Good. You gota remove ANY and ALL redirectors within a REM statement. You can also place " " around the redirector so DOS won't see it as a redirector. Who'da thought a simple command like REM could lock up a computer?! (Well, me obviously!)