General Batch File Notes
I have some peculiar ways of doing things in my batch files. I have collected examples of my most frequently used oddball techniques here. If you know about them, you just might be able to follow what I do in the rest of my batch file examples.

  • Downloading Example Batch Files
  • Toggling ECHO ON/OFF for Debugging
  • Setting Breakpoints and Tracing Variables
  • Minimalist Error Handlers and Mini Subroutines
  • Peculiar Redirection
  • Useless(?) Redirection
  • Undefined Environment Variables as Comments
  • Recursion and the Double Colon (::)
  • Fixes, Changes and Disclaimers

  •   Downloading Example Batch Files
    In an effort to beautify my web site, an unwanted side effect was introduced. Using 'cut and paste' to extract the example procedures from the displayed text is not as useful as I would have hoped (at least not using the browser I have). The pasted text wanders all over the page, with lots of extra spaces prefixing most lines. In addition, some of my examples use special ASCII characters that Windows does not like to show. Displayable substitutions are made in the text to counter this effect, but it's time consuming to correct the procedures once they've been pasted into an editor. So, links to a plain text version of each of the example batch files are provided. Access this copy by clicking on the batch file's name in the example. Using a 'right-click' in the most commonly used browsers allows them to be saved directly, without the intermediate step of pasting in an editor. Use cut and paste of the displayed text version, if need be. The downloaded file may not display correctly, but it will have all of the necessary bits and pieces intact.
      Toggling ECHO ON/OFF for Debugging
    The least intrusive way to disable an ECHO OFF command in a batchfile is to put a simple environment variable between the words ECHO and OFF. This is useful when a routine is first being checked out or modified so that the operation can be traced to find errors. When the variable is SET equal to the string ON (not case sensitive) it will restore command echoing while the procedure runs. Issuing 'SET VAR=' restores the normal operation of the ECHO OFF command.

    In use, you might do something like this ...

    @ECHO %DBG% OFF
     ECHO The rest of the batch file ..
    By simply typing
    SET DBG=ON
    at the C:\> prompt, the initial ECHO OFF will be defeated. To clear the debug mode, simply type
    SET DBG=
    I have added a debugging variable to all of my batch files that has the first letter of the procedure's name at the end of the 'DBG' variable name (ECHO %DBGA% OFF, for example). This naming convention goes a long way to assuring that only the batch file being debugged at the moment will sound off to the screen. Other routines that are called from the procedure being tested remain silent because their variable is not 'SET' to 'ON'. The simple naming convention also makes it easy to remember how to turn debugging on and off.

     Setting Breakpoints
    An extension to the previous idea leads to a simple way to include breakpoints in batch files. That is to use environment variables SET equal to the string PAUSE when a breakpoint is desired and SET equal to an empty string otherwise. For example,
    @ECHO %DBGB% OFF
     ECHO Start ...
     .
     .
     %BRKPT%
     ECHO Continuing ...
    To pause the batch file at the breakpoint type
    SET BRKPT=PAUSE
    at the command prompt. To clear it type
    SET BRKPT=
    Another use of this technique is to display a variable's value somewhere in the procedure while testing. For example, some of my later routines contain a variable named, For example. I use it to display the final result of utility procedures because in normally use the intention is to store the result into a variable for use elsewhere, but not display it. This can easily be coupled with a breakpoint in a FOR statement, something like ... for %%v in (%For Example%) do %%v Var: %Var% The SET statement to display an intermediate result is something like ... set for example=echo Or, to add a breakpoint as well ... set for example=echo pause This approach adds a lot of versitility with just a little overhead. I like the fact that I only need to set the condition once for an extended debugging session without having to edit the procedure or continually add a switch string to the command line.
     Minimalist Error Handlers and Mini Subroutines
    DOS has many peculiarities. Some are useless bits of trivia, while others turn out to be surprisingly useful. One of the peculiarities that I have made use of is that of the lowly colon (:). I have found that it works perfectly well as a delimiter in some situations and not in others. For example, a GOTO works just fine with a colon between the 'GOTO' part and the label part. This may seem like a real "so what", but it's a very crutial part of one of my favorite little tricks; using a FOR command to form a one line error handler.

    For example, the following line will explain that a batch file is missing an important command line input argument and then branch to the end of the routine.

    for %%v in (echo goto:End) do %%v Syntax: %0 InputArgument
    Another way to use this little "minisubroutine" is in collecting input arguments into a single environment variable or to CALL and then DELete a secondary batch file (one created for a single use within the calling routine). They might look like this ...
    :Loop if not [%1]==[] for %%v in (set shift goto:Loop) do %%v Var=%Var% %1
    or
     for %%v in (call del) do %%v {temp}.bat
     Peculiar Redirection
    If I'm known for anything within the circle of diehard batch programmers, it is for my placement of redirections in "places God never intended." Personally, I don't think God cares where I put them. But, more to the point, neither does DOS. (Please note that the 'DOS' in Windows NT is NOT DOS. It doesn't smell like a duck or quack like a duck or taste like a duck.) DOS (but not WinNT) handles redirections just as well at the beginning as at the end of a line. For example, the following three lines perform identically, though they look different. echo This is a test. > {test} echo> {test} This is a test. > {test} echo This is a test. So, if they act the same, why do I tend to use the latter, over the former? Good question!

    I like the way it looks.

    For example, when I redirect several commands in a row into a file, I find it easier to read when all the file name parts and command parts line up in neat columns.

    For example, I find this easier to follow

    > {temp} echo This is the first line. >>{temp} echo This is the second >>{temp} echo and this is the last one. than this echo This is the first line.> {temp} echo This is the second>>{temp} echo and this is the last one.>>{temp} When I want to change a redirection, I can scan the left margin for lines that are being redirected, -and be reasonably confident I have seen every line. Or when I want to trace the logic, I think it's easier to find the command part of the line when they're lined up this way.

    Whether you agree with me or not, at least now you know what I'm doing when you see the batch file listings.

      Useless(?) Redirections
    Some of my procedures appear to have some bizare redirections in them. For example, why would a sane person redirect the output of a 'SET Var=' instruction into a file? There is no output from such a command.

    Aha, you've discovered my secret! I'm not sane! Though, I prefer to think of it as being 'crazy as a fox' (but then again, maybe ...).

    Believe it or not, there is a rational reason. I use this approach to make sure a file is empty without adding a statement to the procedure. One use is before a FOR statement used to create a list of things in a file. Because of the way a FOR statement works, a simple redirection cannot create a list. The resulting file will only contain the last thing output from the FOR. However, a list is created when the output is appended to a file. So, the bogus redirection empties the file in anticipation of the list creation to follow. The one command does double duty.

    Another time this is useful is to create a zero byte flag file. That is, a file whose mere existence flags a condition, say an unfinished process or an error condition. The 'IF EXIST' test permits branching based on its presence or absence.

      Undefined Environment Variables as Comments
    Okay, while we're on the subject of useless definitions, lets talk about the use of environment variables that don't exist. I have started to use them in the past six months or so to provide 'inline' comments. The idea is to just insert the comment anywhere you want on the line, enclosed in percent signs. Further, if the first character after the percent is a space, these 'variables' cannot be created.

    This works because the command processor omits all of the text between the percent signs at run time, since no substitute string exists in the current definition of the environment. Thus, the text becomes a comment for maintenance, having no impact on the operation of the procedure.

    For example, in a recent discussion in the alt.msdos.batch newsgroup someone wanted to create a QBasic like IF - Then - Else construct. I suggested something like ...

    if not [%1]==[String] %Then% goto Else echo %1 equals String % This is where the If True clause goes % goto EndIf :Else echo %1 not equal to String % This is the ELSE clause % :Endif Some wag pointed out that by defining an environment variable 'THEN' equal to 'FORMAT C: /something', this construction would make someone very unhappy. He's right, but the solution is to simply add a space after the leading percent sign (and for esthetics before the trailing one, as well), as I did in the other two comments in the example. Used in this way, the variable just cannot be created (at least not by reasonable means) and nothing unexpected can happen.

    There is a little overhead in using such comments, as the command processor must parse the extra characters on the statement line, but it is not much. I think it is well worth the cost, adding significantly to the ability to document the procedures. Of course, I haven't gone through all of mine yet to add appropriate comments, though I know they need them. That's another issue.

      Recursion and the Double Colon (::)
    Recursion means a function calls itself. It is a very effective technique in a batch file. It is especially valuable in collecting data from DOS utilities for use in the running batch procedure. Nearly all of my procedures use it. If you see a %0 in a statement, it almost always indicates recursion is being used. However, there is an obvious need to keep the routine from calling itself over and over again. That's where the double colon comes in.

    A line beginning with a pair of colons is not acted on by DOS. It's treated, instead, as an unusable label. Everything after the second colon is ignored. Thus, it is commonly used to enter comments into batch procedures. It is processed much faster than the REM statement provided as the 'documented' comment specifier.

    A fellow netizen, John Savage, introduced me to the double colon's usefulness in flow control in a recursive batch file. In particular, any line can be converted to a comment line by inserting a pair of colons at the start of the line, using a command line replaceable argument.

      Fixes, Changes and Disclaimers
    I try to test every procedure and technique I post here, but like everyone I sometimes make a mistake. If you find what you believe is an error or problem, please drop me a line at my current address. I will definitely look into the issue, but cannot take responsibility for any problems my error might cause you.

    I am adding to the content and reserve the right to 'tweek' the routines. You may want to check back on occasion to see if there have been any changes made. Check here first for a summary of the fixes and updates.

    Changes, Updates and problems that have been fixed:

    Action
     Affected Page
    Date
    Logic bug Testdrv11 Nov 96
    New material Counting1 Mar 97
    Bug fix Random18 Mar 97
    LEFT.BAT revised CntLoop18 Mar 97
    Bug fixes to POKER.BAT & CARDS.BAT DEAL25 Mar 97
    Win 95 fix Once26 Aug 97
    Reworked, simplified and extended Alarm25 Nov 97
    Win NT caveat for INPUT.BAT added Input25 Nov 97
    New list processing article. DoList13 Apr 98
    Added link to new "Parsing Date String" article  TimeDate15 Apr 98
    Added link to ANSI.BAT article TimeDate15 Apr 98
    Corrected a broken link to PC Magazine article. Counting16 Apr 98
    Tweak FULL and FILL procedures. Wallpaper21 April 98
    Fix some broken links Resum‚10 Jun 98
    New material Real Math20 Jul 98
    I've MOVED! Everything29 Jul 98
    New content Input9513 Oct 98
    ANSIDEMO.BAT bug fix ANSI19 Oct 98
    New content IncrDecr26 Dec 98
    More edits and additions Genotes29 Dec 98
    Add Win NT reference to Time and Date article TimeDate27 Apr 99
    Extend UniPDate article (now has time, too) PDate30 Apr 99
    Added Bookmark Links Bookmarks11 Jun 99
    New content Datesift13 Aug 99
    Revised and Updated Testdrv16 Aug 99
    Revised and Updated Random18 Sep 99
    Revised and Updated Deal18 Sep 99
    Revised and Updated Games18 Sep 99
    Win NT time and date, updated NTDate14 May 2001
    Cosmetic Update Everything31 Jan 2003
    Remove Broken Links BookmarksFeb 2003
    Make Win 2000 compatible CompareFeb 2003
    Added some WSH VBScript examples  WSHIndexJul 2004
    Added MS-DOS console example to WSH page WSHIndexJul 2006
     



    Top | General Notes | Homepage