[comp.sys.ibm.pc.misc] 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 !!

stevek@hp-ptp.HP.COM (Steve_Kite) (10/16/90)

To echo a blank line in a batch file, use echo ALT-255.  ALT-255
a non-printable character, but your batch file doesn't know
that, so it will print a blank line.

If you are doing a lot of batch files, you might consider switching
to 4DOS.  It has some nice features for use in them, such as:

if/then
iff/else iff/else iff/...

and several more.  I also have heard that the next versiont will
enhance these and add a couple of more commands for batch
files.



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~  If a jimbuck stands alone by the sea, on a night when the    ~
~  dark moon sings, how many grains on sand in a single one of  ~
~  his footprints?                                              ~
~                                                               ~         
~  steve kite     -   hp-ptp!stevek   -   stevek@hp-ptp.HP.COM  ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

jkenyon@us.cc.umich.edu (Jim Kenyon) (10/19/90)

To get the date (and time and DOW) without a prompt, 4DOS provides
environment variables -- you can also extract pieces of them as well.
Like, just the hours, or just the seconds.....

--
Jim Kenyon -- jkenyon@css.itd.umich.edu
University of Michigan, 401 Washtenaw Ave
Division of Kinsesiology, Motor Behavior Lab
Ann Arbor, MI 48109 -- (313) 763-0498

se00@terre.DMI.USherb.CA (Systemes d'exploitation II) (10/19/90)

In article <1990Oct18.032359.14406@csun.edu> abcscnuk@Twg-S5.uucp (Naoto Kimura (ACM)) writes:
>Actually, to be nit-picky, using ASCII 255 doesn't make ECHO output a
>blank line...  Nor is that character an 'unprintable'...  it just
>happens to be an INVISIBLE character -- like ASCII 0.  The unfortunate
>thing about these invisible characters is that that sometimes I've run
>into situations where they become visible, especially if you try to use
>a terminal as the console.
>
>One other annoying thing with the command processor is that there was no
>means by which you can get the date and time w/o getting a prompt.  Of
>course I've done things like make a file with only a newline (note you
>CAN'T create one by doing echo.>newline since it contains a space before
>the newline!) in a text editor and doing the following date<newline.
>
>]~  steve kite     -   hp-ptp!stevek   -   stevek@hp-ptp.HP.COM  ~
>]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>                //-n-\\			 Naoto Kimura
>        _____---=======---_____		 (abcscnuk@csuna.csun.edu)
>    ====____\   /.. ..\   /____====
>  //         ---\__O__/---         \\	Enterprise... Surrender or we'll
>  \_\                             /_/	send back your *&^$% tribbles !!

 MAAALTZ!! JOOL-YI CHOO!  (Klingon for "Maltz! Beam me Up!" - Kirk, ST III)


Blank lines in a .BAT? No problem....

ECHO:

...printing the date:

ECHO:|DATE 
 

Putting the date on a file :

ECHO:|DATE >> DATE.LOG

-- 
==== Etienne Tasse ====  |Internet:          |-"Why?"
Universite de Sherbrooke |se00@dmi.usherb.ca |-"Y is a letter, it won't
Quebec, Canada           |FidoNet:           |  respond."
(819) 820-0241           |1:167/116          |

stevek@hp-ptp.HP.COM (Steve_Kite) (10/19/90)

You're evidently not familiar with 4DOS, a command.com replacement.
It allows you to read the date and/or time and set them up as
enviornment variables.  This way they are accessible from any
program.

It also lets you parse out any part of the string that you want.
My autoexec.bat file reads the date, parses out the day, and
sets the prompt accordingly, so I can have a different prompt 
for each day of the week.  It also takes the date, parses
out the year, figures out which anniversary, etc. it is, and
reminds me of it.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~  If a jimbuck stands alone by the sea, on a night when the    ~
~  dark moon sings, how many grains on sand in a single one of  ~
~  his footprints?                                              ~
~                                                               ~         
~  steve kite     -   hp-ptp!stevek   -   stevek@hp-ptp.HP.COM  ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

marshall@wind55.seri.gov (Marshall L. Buhl) (10/20/90)

stevek@hp-ptp.HP.COM (Steve_Kite) writes:

>To echo a blank line in a batch file, use echo ALT-255.  ALT-255
>a non-printable character, but your batch file doesn't know
>that, so it will print a blank line.

Why not just say:

ECHO.

That prints a blank line (no period) for me.  It's real easy too.
--
Marshall L. Buhl, Jr.                EMAIL: marshall@seri.gov
Senior Computer Missionary           VOICE: (303)231-1014
Wind Research Branch                 1617 Cole Blvd., Golden, CO  80401-3393
Solar Energy Research Institute      Solar - safe energy for a healthy future

robl@idca.tds.PHILIPS.nl (R. Luursema) (10/22/90)

In article <1400055@hp-ptp.HP.COM> stevek@hp-ptp.HP.COM (Steve_Kite) writes:
>To echo a blank line in a batch file, use echo ALT-255.  ALT-255
>a non-printable character, but your batch file doesn't know
>that, so it will print a blank line.

You can print blank lines in batchfiles quite easily:

	ECHO.

Just put a non-interpreting character after echo, with no space.
Also characters  - + ; : / \ , " [ ] will work.

I dont know if this works on other batchfile connand interpreters like 4DOS
and MKS SH korn-shell.


Rob.