Frequently Asked Questions about Batch (not an official FAQ, just answering frequently asked questions...) How do I write a batch? Where can I get batch information? How do I perform if-then-else in batch? How do I use the [insert name] command? How do I get deltree to work without giving permission? How do I delete all files in a dir without giving permission? How do I check if a directory exists? How do I set a variable to the contents of a file? How do I set a variable to the output of a program? How do I extract a line from a file and set a variable to it? How do I get keystrokes from the user or make a menu? How do I get string input from the user? How do I concatenate files into one file? How do I start Windows 95 programs or associated files? How do I save and restore the current directory? How do I check the output of a program for a specific string? How do I rename a file to the current time or date? How do I send keystrokes to a program? What do all those }{ and $ things mean? Utility programs for batch files The following is optimised for Dos 6 and Windows 95. Not responsible for wrong answers, but I gladly try to answer batch questions. So do many others, just ask us. No "how do I destroy" type questions please. Many basic concepts are not covered, to understand batch you'll need to know about redirection and pipes (< > |), setting and using environment variables (set this=that, echo %this%), using command line parameters (%1 to %9) and other stuff. Surf around! *** How do I write a batch? Fire up Notepad or any text editor, write your batch, then save it with a .bat extension - with Notepad select all files when saving so notepad doesn't tack .txt on the end, or rename it after saving. Note for Win95 - in Windows Explorer go to View, Options, make sure hide extensions isn't checked. To run your batch enter its name from a dos prompt or double-click it from Windows. Learn some dos first! Be careful since batch misapplied can reduce your computer to an expensive paperweight until you reload whatever you wiped out... To get your batch to run from any directory, put the batch in a path directory.. enter PATH at a dos prompt for a list. Modify autoexec.bat to set up your own batch path directory, for example: PATH C:\windows;C:\Windows\command;C:\batch *** Where can I get batch information? The best reference is probably the dos help files, if entering HELP does nothing look on your Win95 CD in other\oldmsdos. Also available at Microsoft's web site. It doesn't cover Win95 but there really isn't much difference. Batch information on the web... http://www.maem.umr.edu/~batch/ - Ted Davis' page http://www.pressroom.com/~tglbatch/ - Tom Lavedas' page http://www.calweb.com/~webspace/batch/ - Eric's page http://www.infionline.net/~wtnewton/batch/ - Terry's page http://purl.oclc.org/net/dirk/batcoll.all - Dirk's bat techniques http://bigfoot.com/~batfiles/ - Laurence Soucy's page
Questions about dos/Win9x/WinME batch files should be directed to the alt.msdos.batch newsgroup, WinNT/Win2000 batch questions should be directed to alt.msdos.batch.nt newsgroup instead. *** How do I perform if-then-else in batch? if not .%1==.help goto else rem then commands here goto endif :else rem else conditions here :endif The :else and :endif labels are purely arbitrary, these words mean nothing to dos. The . in .%1==.help is a dummy character to prevent syntax error if %1 (the first parameter btw) is empty. Almost any character on both sides of == will do. Don't worry too much about if-then-else, batch isn't structured. if [not] condition statement is about it. But people ask. *** How do I use the [insert name] command? Before asking for batch help, please use nameofcommand /? first. Almost all commands have built-in help. For example... *** How do I get deltree to work without giving permission? Typing deltree /? tells us that /y suppresses the confirmation, so the answer is deltree /y directory *** How do I delete all files in a dir without giving permission? The del command has no such switch, so you have to simulate a Y keystroke... echo y | del dirname\*.* > nul it is recommended that the dirname be hard-coded to avoid data loss, in case the current directory isn't what you expect. *** How do I check if a directory exists? This works for local hard drives... @echo off if exist c:\windows\nul goto exists echo Windows not found goto end :exists echo You've got Windows :end For NT/network compatibility change nul to nul.x, any extension should do. This technique does not work on removeable drives like CDROM, for this a more complex solution is needed to avoid abort-retry-fail or even work at all. Here's one possible kludge for dos 6/win95 only... (short dir names only) :: chkdir.bat dir :: sets exists to yes or no @echo off set exists=yes %comspec% /f /c dir /-p %1 | find /i "%1" > nul if errorlevel 1 set exists=no As written, displays error messages if the directory or drive doesn't exist. The only way I'm aware of fixing that is to add ctty nul/ctty con statements to the beginning and end of the procedure, slightly risky since this uses the undocumented /f switch to automatically fail and if the option isn't available there would be no way to type 'f' or 'a' to unhang it. *** How do I set a variable to the contents of a file? The simplest method of setting a variable to a file uses a helper file, for the sake of example I'll name it sethelp$ set result=
Must be a single line without a return at the end! In Notepad type up to the = then save without pressing return. To set a variable to a specified ONE line file and return it in %result% use this batch... @echo off copy sethelp$ + %1 $tmp$.bat > nul call $tmp$.bat del $tmp$.bat If running from the path you'll have to hard-code the location of the sethelp$ file. If incorporating in another batch, change the %1 to the name of the input file. Note... the file cannot contain redirection (< > or |) unless enclosed by quotes, a feature common to all batch input methods. Here is a similar procedure only it creates its own helper using the debug command... :: Read a specified One line file into 'result' @echo off > (tmp).bac echo n (tmp).bah >>(tmp).bac echo e 100 "set result=" >>(tmp).bac echo rcx >>(tmp).bac echo 0b >>(tmp).bac echo w >>(tmp).bac echo q debug < (tmp).bac > nul copy (tmp).bah + %1 (tmp).bat > nul call (tmp).bat del (tmp).ba? The "0b" under "rcx" defines the HEX length (11) of the set line, alter if modifying the length of the variable name. Additional file input batches can be found at: http://www.infionline.net/~wtnewton/batch/batinput.txt Eric Pement has a page about input methods for batch: http://www.cornerstonemag.com/sed/bat_env.htm To avoid the complexity and problems with batch-only input methods you might prefer using a utility. *** How do I set a variable to the output of a program? Use a technique similar to setting an evar to a file, except create the temp file using redirection... program > tempfile call setfile.bat tempfile del tempfile Setfile.bat refers to one of the set-to-file batches. If the program outputs more than one line, filter through FIND as in... program | find "matchstring" > tempfile etc. *** How do I extract a line from a file and set a variable to it? Use the FIND command to extract the line you want to a tempfile then use your favorite kludge... find "matchstring" < input.fil > tempfile call setfile.bat tempfile del tempfile Setfile.bat refers to one of the set-to-file batches. If the line can't be matched with a unique string, you'll probably need a utility or qbasic/sed/perl routine. *** How do I get keystrokes from the user or make a menu? The CHOICE command is used to get single keypresses. Here is a menu example... @echo off :menu cls echo. echo A - Text for item A echo B - Text for item B echo C - End echo. choice /c:ABC > nul if errorlevel 3 goto end if errorlevel 2 goto B if errorlevel 1 goto A echo Error... choice not installed goto end :A echo Commands for item A pause goto menu :B echo Commands for item B pause goto menu :end *** How do I get string input from the user? This is based on a batch from PC Magazine June 27, 1995, most other all-batch solutions use FC and DATE in a similar way. Notes! Don't enter redirection characters (< > |) or errors will result, possibly overwriting files. If 'enter.bat' exists in the current directory it will be deleted. It depends on the English version of dos, change all occurences of 'enter' to the first word of the date command input prompt to use with other languages. It does not work with Windows NT. @echo off echo What's your name? :: ... input routine, returns 'str' variable > $tmp$.bat fc con nul /lb1 /n|date|find " 1: " > enter.bat echo set str= >>enter.bat echo :loop >>enter.bat echo if not '%%str%%==' set str=%%str%% %%5 >>enter.bat echo if '%%str%%==' set str=%%5 >>enter.bat echo shift >>enter.bat echo if not '%%5==' goto loop call $tmp$.bat del $tmp$.bat del enter.bat :: ... echo Hello %str%! You might prefer using a utility program instead. *** How do I concatenate files into one file? copy /b *.txt output.fil If you want separations between the files, try something like this... @echo off if .%1==.Loop goto process > output.fil rem for %%a in (*.txt) do call %0 Loop %%a goto end :process >>output.fil echo. >>output.fil echo ----------- File %2 ----------- >>output.fil type %2 :end Modify as needed. *** How do I start Windows 95 programs or associated files? start /w "windows file.ext" enter start /? for more options. *** How do I save and restore the current directory? Here are a pair of batch files written by Tom Lavedas for saving and restoring the current directory... :: Push.bat - Store current folder (directory) name. @echo off echo @prompt set _Here=$p$_ > %temp%\_temp_A.bat %comspec% /e:2048 /c %temp%\_temp_A.bat > %temp%\_temp_B.bat call %temp%\_temp_B.bat del %temp%\_temp_?.bat and :: Pop.bat - Return to last saved folder (directory). @echo off %_Here%\ cd %_Here% Pop.bat works with long directory names only if they do not contain a space, for full Windows long name compatibility change each %_Here% to "%_Here%, the quote tells Windows it's a long name. Here's a universal modification... :: Pop.bat - Return to last saved folder (directory). :: Universal version @echo off ver | find "MS" > nul if not errorlevel 1 goto dospop "%_Here%\ cd "%_Here% goto popend :dospop %_Here%\ cd %_Here% :popend For Push.bat to work properly the 'temp' variable must contain a valid directory and not end with "\". *** How do I check the output of a program for a specific string? program | find "string" > nul if errorlevel 1 goto notfound rem string was found ... If the case of "string" isn't known, use find /i "string". *** How do I rename a file to the current time or date? Here are a pair of very clever batch files from Tom Lavedas for setting the variables 'ptime' and 'pdate', Win9x only... :: PTime95.bat - A routine for Win 9x that parses the current Time :: Tom Lavedas <lavedas@pressroom.com> :: http://www.pressroom.com/~tglbatch/ @echo %dbgr% off > {a}.bat echo @prompt set PTime=$_echo $ty $b del call /p $g {a}.bat > {b}.bat %comspec% /e:2048 /c {a}.bat > delete.bat echo set PTime=%%PTime%%%Delim2%%%{T}%% >>delete.bat echo set {T}=%Delim1% :: long line... >>delete.bat echo for %%%%v in (0 1 2 3 4 5 6 7 8 9) do if %%1==(Y/N)?%%%%v set {T}=%%%%v :: end long line > call for %%v in ({b}.bat {a}.bat set) do call %%v {T}= for %%v in ({?}.bat delete.bat) do del %%v for %%v in (%For example%) do %%v PTime: %PTime% and for the date ... :: PDate95.bat - A routine for Win 9x that parses the current Date :: Tom Lavedas <lavedas@pressroom.com> :: http://www.pressroom.com/~tglbatch/ @echo %dbgp% off %2 if [%1]==[] %0 DateName :: :: long line... > {a}.bat echo @prompt set PDate=$_for %%%%%%%%v in ($d) do set {D}=%%%%%%%%v$_ :: end long line > {b}.bat %comspec% /e:2048 /c {a}.bat > call call {b}.bat > delete.bat echo set PDate=%%PDate%%%Delim2%%%{D}%% >>delete.bat echo set {D}=%Delim1% :: long line... >>delete.bat echo for %%%%v in (0 1 2 3 4 5 6 7 8 9) do if %%1==(Y/N)?%%%%v set {D}=%%%%v :: end long line echo %{D}%y | del call /p > {b}.bat set {D}=> nul for %%v in ({b}.bat del) do call %%v {?}.bat del delete.bat for %%v in (%For example%) do %%v PDate: %PDate% These routines contains long lines that may get wrapped in email, there should be only one line between the :: symbols where noted. If not, put cursor at end of 1st line and press space delete. Also note that there should not be a delete.bat in the current directory or it will be deleted. <g> Usage: call ptime95 rename thisfile.txt %ptime%.txt call pdate95 md %pdate% etc. *** How do I send keystrokes to a program? That depends. If it's a program that accepts standard input (like a dos command or simple utility), and it's ok to also send an enter character at the end, then all you need to do is feed it characters using redirection, for example... echo YNQ | program If multiple enter keys are involved, write to a temp first... echo.>tempfile - write a single enter echo>>tempfile name - write "name" + enter program < tempfile (for example) del tempfile To avoid the enter at the end use Notepad or similar to create a file with exacly the keystrokes you want. If you need to delay the keystrokes or the program doesn't read from standard input, you need a key-stuffer utility, look in the archive links. *** What do all those }{ and $ things mean? They're uniquely named temp files or variable names. It is desirable to make the filenames as weird as possible to avoid overwriting files that happen to have the same name. Also, confusion is found in spacing and where the redirection characters are, these all write "hey!" to a temp file... echo>[myfile] hey! >$$$tmp$$.$ echo hey! echo hey! > tempfile *** Utility programs for batch files Batch simply wasn't designed to do the kinds of things users want to do, although us batch hackers ignore this and try to do them anyway. Batch input routines are especially kludgy and incompatible, often it's easier to just use a utility designed for the purpose and avoid the hassle. SENVAR by Ed Schwartz makes it very easy to set an environment variable to standard-input... senvar evar - input from keyboard program | senvar evar > nul - input from program senvar evar < file > nul - input from file SENVAR is at http://www.infionline.net/~wtnewton/batch/senvar.txt The shareware XSET program by Marc Stern has many extra options, like reading a file from a specific column and line number... xset /mid 6 2 /line 3 evar < file > nul XSET is at http://members.tripod.com/~marcstern/xset.htm ASET by Richard Breuer, free, makes mathematical operations as easy as ASET result=2+2, functions for math, string handling, file/kb input and more. File aset10.zip at Simtel. Strings by Douglas Boling, free, provides commands for string handling, modifying memory and master environment, reading files, math, keyboard input and more. File string25.zip at Simtel. Many more useful batch utilities can be found at... Garbo: http://garbo.uwasa.fi/pc/batchutil.html SimTel: ftp://ftp.simtel.net/pub/simtelnet/msdos/batchutl/
-------------------------------------------------------------- This is beta 0.36 of the Batch-FAQ, totally subject to change. Written by Terry Newton, last (majorly) updated March 15, 1999 Minor adjustments April 28, 2003 (sorry no new stuff...) Better/more questions and/or answers welcome!