<http://www.netikka.net/tsneti/info/tscmd009.htm>
Copyright © 2003-2010 by Prof. Timo Salmi  
Last modified Sat 17-Apr-2010 15:15:36

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



9} How can I suppress script error messages altogether?

To introduce, let's take the example of finding out which drives are present and read, and which are not.
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%a in (A B C D E F G H I J K L M
              N O P Q R S T U V W X Y Z) do (
    dir %%a:\ 2>&1|findstr /b /i /r /c:" Volume in drive ">nul
    if !errorlevel! EQU 0 (
      echo Device %%a: found and ready
      ) else (
      echo Device %%a: not found or not ready)
    )
  endlocal & goto :EOF

  C:\_D\TEST>cmdfaq
  Device A: not found or not ready
  Device B: not found or not ready
  Device C: found and ready
  Device D: found and ready
  Device E: found and ready
  Device F: not found or not ready
  :
  Device Y: not found or not ready
  Device Z: found and ready

Compare that with what we would have with the two redirections 2>&1 and >nul omitted:
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%a in (A B C D E F G H I J K L M
              N O P Q R S T U V W X Y Z) do (
    dir %%a:\ |findstr /b /i /r /c:" Volume in drive "
    if !errorlevel! EQU 0 (
      echo Device %%a: found and ready
      ) else (
      echo Device %%a: not found or not ready)
    )
  endlocal & goto :EOF

  C:\_D\TEST>cmdfaq
  The device is not ready.
  Device A: not found or not ready
  The system cannot find the path specified.
  Device B: not found or not ready
   Volume in drive C is SUPU_C
  Device C: found and ready
   Volume in drive D is SALMI_1GB
  Device D: found and ready
   Volume in drive E has no label.
  Device E: found and ready
  The system cannot find the path specified.
  Device F: not found or not ready
  :
  The system cannot find the path specified.
  Device Y: not found or not ready
   Volume in drive Z is SupuZip20080315
  Device Z: found and ready

Having observed the above, let's start from the basics. This is a classic carryover from UNIX. First consider
  @echo off
  echo Customized pause, press the anykey ...
  pause>nul
The usual pause message goes to the nul bitbucket, and only the customized message appears (actually before the pause).


When you type
  dir *.tex > texlist.dir
you'll get the folder listing into texlist.dir but if there are any errors, then the error messages are forced on the standard output device (the screen), not to textlist.dir, while the rest of the output still goes there. You would have on the screen the message
  File Not Found

What if you do not wish to see that message, but redirect it to the bit bucket. This is the syntax then
  dir *.tex > texlist.dir 2>&1
Since the test folder has no *.tex file, a file "File Not Found" message is produced, but it is redirected to texlist.dir, not to the screen.

Consider the following cryptic-looking script
  @echo off   dir > nul 2>&1
It produces no output. Now why would one wish to do something like that? ... Because, some commands return an errorlevel, and that is what one really is after, as is seen from the example which this item started with.

For example XCOPY returns exit codes as shown by the demonstration below where "Y:" is a non-existent drive in the test. For example XCOPY returns exit codes as shown by the demonstration below where "Y:" is a non-existent drive in the test.
  @echo off
  xcopy /v *.* Y: > nul
  for %%L in (5 4 3 2 1 0) do if errorlevel==%%L (
    set level_=%%L
    goto _tell
    )
  :_tell
  echo The errorlevel of the operation was %level_%
  set level_=

The output produced will be
  Invalid drive specification
  The errorlevel of the operation was 4
However, change the second line to
  xcopy /v *.* Y: > nul 2>&1
and the only output will be just
  The errorlevel of the operation was 4

Another example. Assume that there is no disk in the A: drive.
  dir a:
will produce
  The device is not ready.
However
  dir a:>nul 2>&1
will only produce a blank line, but not the error message.

Why 2>&1? Because the numeric equivalent of the STDERR is 2 and the numeric equivalent of STDOUT handle is 1. This becomes more evident if you do the following in phases
  dir NoSuchFile 2>stderr.tmp
The error message will be directed to stderr.tmp while the rest will appear on the screen. Then enter
  dir NoSuchFile>out.tmp 2>&1
and all the output, the error message included, will go to out.tmp

This item was about suppressing error messages. Another way of thinking is avoiding the errors, at least in easily expected situations. Consider
  DIR "C:\_M\*.CMD"
which will produce
  File Not Found
if no *.CMD files are located in the folder C:\_M. This can be avoided by instead using either
  if exist "C:\_M\*.CMD" dir "C:\_M\*.CMD"
or e.g.
  for %%f in ("C:\_M\*.CMD") do echo %%~tf %%~zf "%%~ff"

Below is a demonstration how to play with stderr. The unraveling and customizing to one's own potential task is left to the reader
  @echo off & setlocal enableextensions
  for %%f in (stderr.tmp tmp$$$.cmd) do if exist %%f del %%f
  set var_=
  ::
  dir cmdfaq.cmd 2>stderr.tmp
  ::
  for /f "tokens=* delims=" %%r in ('
  type stderr.tmp') do echo @set var_=%%r>tmp$$$.cmd
  if exist tmp$$$.cmd call tmp$$$.cmd
  ::
  if defined var_ (
    echo var_=%var_%
    ) else (
    echo var_ is undefined. The DIR command was successful.
    )
  ::
  for %%f in (stderr.tmp tmp$$$.cmd) do if exist %%f del %%f
  endlocal & goto :EOF

The output (slightly condensed) will be
  C:\_D\TEST>cmdfaq
   Directory of C:\_D\TEST
  var_=File Not Found

Or, if you instead have in the script
  dir MyExisting.txt 2>stderr.tmp

the output (again slightly condensed) will be
  C:\_D\TEST>cmdfaq
   Directory of C:\_D\TEST
  16.04.2006  06:36               523 MyExisting.txt
                 1 File(s)            523 bytes
                 0 Dir(s)  27 814 150 144 bytes free
  var_ is undefined. The DIR command was successful.

Consider the following example code which demonstrates several special tricks of command line script programming
  @echo off & setlocal enableextensions
  copy "C:\_D\TEST\My file.txt" "C:\_M\TEMP\" >nul 2>&1^
    &&(echo The copying succeeded&goto _continue)^
      ||(echo The copying failed&echo Exiting&goto :EOF)
  :_continue
  echo Continuing whatever ...
  endlocal & goto :EOF
  1. Suppressing standard output
  2. Suppressing a potential error message
  3. Continuing a line
  4. Run a command if the preceding command is successful.
  5. Enclosing a set of commands in parentheses
  6. Run a command if the preceding command fails.
  7. Multiple commands on one line
The output could be e.g.
  C:\_D\TEST>cmdfaq
  The copying succeeded
  Continuing whatever ...
or
  C:\_D\TEST>cmdfaq
  The copying failed
  Exiting

References/Comments: (If a Google message link fails try the links within the brackets.)
  hh ntcmds.chm::/redirection.htm
  hh ntcmds.chm::/ntcmds_shelloverview.htm
  Google Groups Jan 26 2006, 9:29 pm [M]
  Command-line reference A-Z Windows XP TechCenter