[alt.msdos.programmer] DOS batch quirks and environment variable weirdness.

abcscnuk@csunb.csun.edu (Naoto Kimura) (10/15/90)

After spending a number of times going through trying to figure out what
went wrong with batch files and several pieces of software that used
environment variables, I decided to perform some experiments...  I'm
sure that there have been many people who have performed similar
experiments, but I think that for those who haven't tried them it would
benefit greatly...

The problem arises in how the DOS command processor handles many
constructs.  I ended up spending quite a long time trying to figure out
why some of my software stopped working on a system where it used to
work fine.  It turned out that someone edited the AUTOEXEC.BAT file and
changed the SET statements that assigned the environment variables.
The only thing that changed within the SET statements were extra spaces
around the '=', which at first doesn't seem to change the statement.

Here is a batch file that can be used to illustrate some of the things
I've discovered:

   ] @echo off
   ] echo off
   ] rem
   ] rem .---------------------------------------------------------------.
   ] rem ! This is a batch file to show how DOS handles some constructs. !
   ] rem ! DOS handles environment variables in weird ways...  It also   !
   ] rem ! uses the = as a token separator, which gets eaten up in the   !
   ] rem ! command parser in some cases, and not in others.              !
   ] rem `---------------------------------------------------------------'
   ] rem
   ] echo.
   ] echo ECHOing blank lines is sometimes difficult.
   ] echo.
   ] echo The = character has special meaning to the command processor.
   ] echo.=============================================================
   ] echo The above line gives expected results,
   ] echo however the following line does not:
   ] echo =============================================================
   ] echo.
   ] echo.
   ] echo.============
   ] echo == Before ==
   ] echo.============
   ] set
   ] set Test=Test#1
   ] set Test =Test#2
   ] set Test ] 1 [ =I am brain-dead
   ] set Test] 1 [ =DOS is truly brain-dead
   ] set Neato=ECHO ---- This is really neat eh ? ----
   ] echo.
   ] echo.===========
   ] echo == After ==
   ] echo.===========
   ] set
   ] echo 0 [%Test%] 1 [ %Test% ] 2
   ] echo 0 [%Test %] 1 [ %Test % ] 2
   ] echo 0 [%Test ] 1 [ %Test ] 2
   ] echo 0 [%Test] 1 [ %Test ] 2
   ] %Neato%
   ] set Test=
   ] set Test =
   ] set Test ] 1 [ =
   ] set Test] 1 [ =
   ] set Neato=

If you notice, some of the echo statements contain a period ('.')
immediately after ECHO.  Placing the period there allows one to echo a
blank line without generating the annoying 'ECHO is ON' or 'ECHO is OFF'
message.  As far as I've tested, this technique has worked on most
versions (2.0 and later) of DOS, though I have encountered versions in
which this did not work.  Because of the way the command parser parses
out tokens, you might get some unexpected results -- especially if
you're used to using the UNIX shell languages.

The following is the output generated by the previously listed batch
file (as with the batch program, I've prepended ' ] ' to the lines so
that I can somehow hilight the lines):

   ] 
   ] ECHOing blank lines is sometimes difficult.
   ] 
   ] The = character has special meaning to the command processor.
   ] =============================================================
   ] The above line gives expected results,
   ] however the following line does not:
   ] ECHO is off
   ] 
   ] 
   ] ============
   ] == Before ==
   ] ============
   ] COMSPEC=Y:COMMAND.COM
   ] PROMPT=$P$G
   ] PATH=Y:.;X:.
   ] 
   ] 
   ] ===========
   ] == After ==
   ] ===========
   ] COMSPEC=Y:COMMAND.COM
   ] PROMPT=$P$G
   ] PATH=Y:.;X:.
   ] TEST=Test#1
   ] TEST =Test#2
   ] TEST ] 1 [ =I am brain-dead
   ] TEST] 1 [ =DOS is truly brain-dead
   ] NEATO=ECHO ---- This is really neat eh ? ----
   ] 0 [Test#1] 1 [ Test#1 ] 2
   ] 0 [Test#2] 1 [ Test#2 ] 2
   ] 0 [I am brain-deadTest ] 2
   ] 0 [DOS is truly brain-deadTest ] 2
   ] ---- This is really neat eh ? ----

Anyway, there are a few lessons to be learned from the seemingly
bizarre behavior of this batch script.

 o When it comes to spaces, DOS considers them to be important,
   especially in the case of environment variables -- you can even have
   imbedded spaces in the environment variable assignments.
 o The '=' character has special significance, and so it can't be used
   in some places.  One surprise to me was when I found out that I
   couldn't echo a line containing just '='s and spaces, but if you
   follow the example of the ECHO command that echos a blank lines,
   you'll see a method by which you should be able to ECHO such a line.
 o The '.' character has also significance in parsing of commands one
   way you can use them is with the ECHO command to trick it into doing
   things it doesn't normally do.
 o When referencing environment variables, make sure that you fully
   enclose the environment variable reference with the % character,
   since environment variables may contain some characters that are
   special symbols (parenthesis, square braces) in most other languages.
 o It might be good idea to make sure that your library routines to
   handle environment variables can handle spaces that appear before and
   after the '=' in the environment.  This way we can make sure that
   there aren't any surprises if you do have them.  I've been bitten by
   this problem way too many times in several of my own programs that
   worked fine under UNIX, but wouldn't work reliably under MS-DOS
   because of the fact that sometimes there were spaces around the = in
   the SET commands in a batch file, while other times there were none.
 * I'm probably wasting my time trying to figure out ways in which I can
   work around the bugs in the command processor and I should be
   spending my time writing a more reasonable one (and probably make
   lots of money selling one).  Either that or just dump IBM-PC's and
   MS/PC-DOS altogether for a REAL computer with a REAL operating
   system...  Like a TRS-80 model I with TRSDOS ;-) ;-) ;-) ;-) ;-)

If anybody has any comments or corrections to what I've said, please
feel free to respond.  And please take note that I'm posting this at
about 4 a.m. so I'm probably not thinking straight -- and so I might
actually be spewing nonsense and wasting $$$ clogging up the bandwith
with this useless babbling...

                //-n-\\			 Naoto Kimura
        _____---=======---_____		 (abcscnuk@csuna.csun.edu)
    ====____\   /.. ..\   /____====
  //         ---\__O__/---         \\	Enterprise... Surrender or we'll
  \_\                             /_/	send back your *&^$% tribbles !!