Assorted Batch Tricks Thu 6-Aug-1992 ===================== By prof. Timo Salmi Moderating at garbo.uwasa.fi anonymous FTP archives 128.214.87.1 Faculty of Accounting & Industrial Management; University of Vaasa Internet: ts@uwasa.fi Bitnet: salmi@finfun ; SF-65101, Finland .................................................................. Introduction ============ This file contains assorted batch tricks. Many, but not all, have been used in the TSBAT*.ZIP collection of batches. Likewise, there are many useful tricks not documented here to be found in the TSBAT batches. INDEX ===== Making "@echo off" general Appending a new directory to the path Comparing two files Deleting All Files Nested Loops Checking whether a directory exists Checking that a program is available at the current directory or at path Using subroutines and recursion in batches Convert a parameter to uppercase Appending a new directory to the path Comparing two files Writing an empty line Customizing the pause message Complicate renaming with for Checking for wildcards Preventing breaking the batch Making "@echo off" general ========================== If you want to turn the echo off, and do not wish to show that line on the screen, you can easily do this by applying @echo off There is a catch, however, since this only works since MsDos version 3.30. So if you want to make it general, put the following line in your autoexec.bat file if you are using MsDos 3.30 or higher set _echo=@ Then use the following format in your batches, which will then work for any MsDos version %_echo%echo off Deleting All Files ================== One of the most Frequently Asked Questions (FAQs) about batches is how to suppress the "Are you sure (Y/N)?" confirmation requirement for del *.*. Use the following: echo y| del *.* If you wish to suppress the message too, use echo y| del *.* > nul Whether or not it is sensible to suppress the confirmation can be debated, but this is the trick anyway. Nested Loops ============ It is possible to have nested loops of a kind in batch programming. Consider the following two batches, and try it out by calling test.bat. echo off rem TEST.BAT for %%f in (a b c d e f) do %comspec% /c test2 %%f echo off rem TEST2.BAT for %%g in (1 2 3) do echo %1%%g Checking whether a directory exists =================================== It is sometimes useful to be able to test whether a particular directory exists. The following test is true if the %1 directory does not exist. if not exist %1\nul if not exist %1nul echo Directory %1 does not exist Checking that a program is available at the current directory or at path ======================================================================== When you call a program from a batch, and do not give the explicit path to it, it is advisable to test that the program is available either at the current directory or the default path. set _found= if exist %1 set _found=yes for %%d in (%path%) do if exist %%d\%1 set _found=yes for %%d in (%path%) do if exist %%d%1 set _found=yes if "%_found%"=="yes" goto _continue echo %1 is not at path or the current directory goto _out :_continue echo %1 found at path or in the current directory :_out Using subroutines and recursion in batches ========================================== It is possible to use subroutines within batches. The crucial trick is setting an environment variable (eg _return) to point to a label where to return after the subroutine has been performed. For an example see UNPACK.BAT, and BOOT.BAT, the sections :_common and :_subru. Another somewhat similar trick is having a batch to call itself (a recursive batch call). You can find an example of this in SHOW.BAT which provides a wild-carded TYPE command. Convert a parameter to uppercase ================================ This example shows how to ensure that the parameter %1 given to the batch is in uppercase. This utilizes the fact that MsDos converts the path to uppercase. The result is stored in upcase_ and then the original path is restored. set tmp_=%path% path=%1 set upcase_=%path% path=%tmp_% Appending a new directory to the path ===================================== This often needed trick is basically very simple. For example to add directory %1 to path use path=%path%;%1 Note that you can only use this trick in a batch. It will not work at the MsDos prompt because the environment variables are expanded (%path%) only within batches. For a full treatment with safeguards against appending non-existing directories, or appending twice, see ADDPATH.BAT. Comparing two files =================== It is possible in batch programming to test whether or not two files have identical contents. This trick utilizes th external MsDos programs fc.exe and find.exe. (An external MsDos program means, of course, a program that comes with the standard MsDos releases. Most often the MsDos external support files are located in a c:\dos directory.) fc %1 %2 > tmp$$$ type tmp$$$ | find /i "fc: no differences encountered" > diffe$$$ if exist notsame$ del notsame$$$ copy diffe$$$ notsame$ > nul if not exist notsame$ echo Files %1 and %2 are different if exist notsame$ echo Files %1 and %2 are identical if exist tmp$$$ del tmp$$$ if exist notsame$ del notsame$ if exist diffe$$$ del diffe$$$ If you think about, this idea can be used for other useful purposes, too, because it establishes whether a given string is found in a text file. Writing an empty line ===================== This is a simple, but an often needed, useful trick. Just use echo with (for example) a point (.) after it. As you can see, I have utilized this batch feature extensively in my batch collection. echo. Customizing the pause message ============================= You can easily customize the message given by pause by giving your own with echo and directing the pause message to nul. to nul. echo Break to quit, any other key to remove the tmp directory pause > nul Complicate renaming with for ============================ Although this is basically trivial, one does not necessarily come to thing of it. The for statement is quite useful for involved renaming of files. An example delineates. For example I have the following files (Turbo Pascal units for TP 4.0, 5.0, 5.5 and 6.0). Say that I wish to rename them to be version 29 instead of 28. tspa2840.zip tspa2850.zip tspa2855.zip tspa2860.zip The following for-statement does that conveniently. for %f in (40 50 55 60) do ren tspa28%f.zip tspa29%f.zip Naturally, renaming is not the only task that can utilize this trick. I am sure you can readily think of others. Checking for wildcards ====================== This example shows how you can test whether a parameter (%1) of a batch contains wildcards. @echo off for %%f in (%1) do if "%%f"=="%1" goto _nowilds echo Parameter %1 contains wildcards (or is missing) :_nowilds Preventing breaking the batch ============================= It is possible to prevent user interrupt of a batch by using the ctty command to reassign the input (and the output) device. Here is an example (an elementrary password batch requiring inputting an e). Note the < and > redirections which are needed while the ctty has been assigned to nul. The ask batch enhancer is included in the TSBAT collection. @echo off ctty nul echo Now you cannot break the batch with ^C or ^Break > con :_ask echo Use e to break > con ask /b /d < con if errorlevel==101 if not errorlevel==102 goto _out goto _ask :_out ctty con echo Back to normal. Now you can break the batch with ^C or ^Break.