home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / t / tsbat.zip / TSBAT.EXE / BATRICKS.TXT < prev    next >
Text File  |  1992-10-22  |  14KB  |  387 lines

  1. Assorted Batch Tricks                        Thu 22-October-1992
  2. =====================
  3.  
  4. By prof. Timo Salmi
  5. Moderating at garbo.uwasa.fi anonymous FTP archives 128.214.87.1
  6. Faculty of Accounting & Industrial Management; University of Vaasa
  7. Internet: ts@uwasa.fi Bitnet: salmi@finfun   ; SF-65101, Finland
  8. ..................................................................
  9.   ┌────────────────────────────────────────────────────────────┐
  10.   │ This file belongs to TSBAT*.ZIP.  Please do not distribute │
  11.   │ this batricks.txt file separately.                         │
  12.   └────────────────────────────────────────────────────────────┘
  13.  
  14. Introduction
  15. ============
  16.  
  17. This file contains assorted batch tricks. Many, but not all, have
  18. been used in the TSBAT*.ZIP collection of batches. Likewise, there
  19. are some useful further tricks, not documented here, to be found in
  20. the TSBAT batches.
  21.  
  22.  
  23. INDEX
  24. =====
  25.  
  26. 1)  Making "@echo off" general
  27. 2)  Deleting All Files
  28. 3)  Nested Loops
  29. 4)  Checking whether a directory exists
  30. 5)  Checking that a program is available at the current directory or at path
  31. 6)  Using subroutines in batches
  32. 7)  Convert a parameter to uppercase
  33. 8)  Appending a new directory to the path
  34. 9)  Comparing two files
  35. 10) Writing an empty line
  36. 11) Customizing the pause message
  37. 12) Complicate renaming with for
  38. 13) Checking for wildcards
  39. 14) Preventing breaking the batch
  40. 15) Prevent a break from bypassing your autoexec.bat
  41. 16) Getting the extension
  42. 17) The quote character %
  43. 18) Eliminating auxiliary batches
  44. 19) Utilizing the subst command in paths
  45. 20) How to run a batch once a week (testing for the weekday)
  46.  
  47.  
  48. 1. Making "@echo off" general
  49. =============================
  50.  
  51. If you want to turn the echo off, and do not wish to show that line
  52. on the screen, you can easily do this by applying
  53.  @echo off
  54.  
  55. There is a catch, however, because this only works since MsDos
  56. version 3.30.  So if you want to make it general, put the following
  57. line in your autoexec.bat file if you are using MsDos 3.30 or higher
  58.  set _echo=@
  59. Then use the following format in your batches, which will then work
  60. for any MsDos version
  61.  %_echo%echo off
  62.  
  63.  
  64. 2. Deleting All Files
  65. =====================
  66.  
  67. One of the most Frequently Asked Questions (FAQs) about batches is
  68. how to suppress the "Are you sure (Y/N)?" confirmation requirement
  69. for del *.*.  Use the following:
  70.  echo y| del *.*
  71. If you wish to suppress the message too, use
  72.  echo y| del *.* > nul
  73. Whether or not it is sensible to suppress the confirmation can be
  74. debated, but this is the trick anyway.
  75.  
  76.  
  77. 3. Nested Loops
  78. ===============
  79.  
  80. It is possible to have nested loops of a kind in batch programming.
  81. Consider the following two batches, and try it out by calling
  82. test.bat.
  83.   echo off
  84.   rem TEST.BAT
  85.   for %%f in (a b c d e f) do %comspec% /c test2 %%f
  86.  
  87.   echo off
  88.   rem TEST2.BAT
  89.   for %%g in (1 2 3) do echo %1%%g
  90.  
  91.  
  92. 4. Checking whether a directory exists
  93. ======================================
  94.  
  95. It is sometimes useful to be able to test whether a particular
  96. directory exists. The following test is true if the %1 directory
  97. does not exist.
  98.  if not exist %1\nul if not exist %1nul echo Directory %1 does not exist
  99.  
  100.  
  101. 5. Checking that a program is available at the current directory or at path
  102. ===========================================================================
  103.  
  104. When you call a program from a batch, and do not give the explicit
  105. path to it, it is advisable to test that the program is available
  106. either at the current directory or the default path.
  107.   set _found=
  108.   if exist %1 set _found=yes
  109.   for %%d in (%path%) do if exist %%d\%1 set _found=yes
  110.   for %%d in (%path%) do if exist %%d%1 set _found=yes
  111.   if "%_found%"=="yes" goto _continue
  112.   echo %1 is not at path or the current directory
  113.   goto _out
  114.   :_continue
  115.   echo %1 found at path or in the current directory
  116.   :_out
  117.  
  118.  
  119. 6. Using subroutines and recursion in batches
  120. =============================================
  121.  
  122. It is possible to use subroutines within batches. The crucial trick
  123. is setting an environment variable (eg _return) to point to a label
  124. where to return after the subroutine has been performed. For an
  125. example see UNPACK.BAT, and BOOT.BAT, the sections :_common and
  126. :_subru.
  127.  
  128.  
  129. 7. Convert a parameter to uppercase
  130. ===================================
  131.  
  132. This example shows how to ensure that the parameter %1 given to the
  133. batch is in uppercase. This utilizes the fact that MsDos converts
  134. the path to uppercase. The result is stored in upcase_ and then the
  135. original path is restored.
  136.   set tmp_=%path%
  137.   path=%1
  138.   set upcase_=%path%
  139.   path=%tmp_%
  140.  
  141.  
  142. 8. Appending a new directory to the path
  143. ========================================
  144.  
  145. This often needed trick is basically very simple. For example
  146. to add directory %1 to path use
  147.  path=%path%;%1
  148. Note that you can only use this trick in a batch. It will not work
  149. at the MsDos prompt because the environment variables are expanded
  150. (%path%) only within batches.
  151.  
  152. For a full treatment with safeguards against appending non-existing
  153. directories, or appending twice, see ADDPATH.BAT.
  154.  
  155.  
  156. 9. Comparing two files
  157. ======================
  158.  
  159. It is possible in batch programming to test whether or not two files
  160. have identical contents. This trick utilizes th external MsDos
  161. programs fc.exe and find.exe.  (An external MsDos program means, of
  162. course, a program that comes with the standard MsDos releases. Most
  163. often the MsDos external support files are located in a c:\dos
  164. directory.)
  165.   fc %1 %2 > tmp$$$
  166.   type tmp$$$ | find /i "fc: no differences encountered" > diffe$$$
  167.   if exist notsame$ del notsame$$$
  168.   copy diffe$$$ notsame$ > nul
  169.   if not exist notsame$ echo Files %1 and %2 are different
  170.   if exist notsame$ echo Files %1 and %2 are identical
  171.   if exist tmp$$$ del tmp$$$
  172.   if exist notsame$ del notsame$
  173.   if exist diffe$$$ del diffe$$$
  174. If you think about, this idea can be used for other useful purposes,
  175. too, because it establishes whether a given string is found in a
  176. text file.
  177.  
  178.  
  179. 10. Writing an empty line
  180. =========================
  181.  
  182. This is a simple, but an often needed, useful trick.  Just use echo
  183. with (for example) a point (.) after it. As you can see, I have
  184. utilized this batch feature extensively in my batch collection.
  185.  echo.
  186.  
  187.  
  188. 11. Customizing the pause message
  189. =================================
  190.  
  191. You can easily customize the message given by pause by giving your
  192. own with echo and directing the pause message to nul.
  193. to nul.
  194.  echo Break to quit, any other key to remove the tmp directory
  195.  pause > nul
  196.  
  197.  
  198. 12. Complicate renaming with for
  199. ================================
  200.  
  201. Although this is basically trivial, one does not necessarily come to
  202. thing of it. The for statement is quite useful for involved renaming
  203. of files. An example delineates. For example I have the following
  204. files (Turbo Pascal units for TP 4.0, 5.0, 5.5 and 6.0).  Say that I
  205. wish to rename them to be version 30 instead of 29.
  206.   tspa2940.zip
  207.   tspa2950.zip
  208.   tspa2955.zip
  209.   tspa2960.zip
  210. The following for-statement does that conveniently.
  211.  for %f in (40 50 55 60) do ren tspa29%f.zip tspa30%f.zip
  212. Naturally, renaming is not the only task that can utilize this
  213. trick. I am sure you can readily think of others, like
  214.   for %d in (a b) do format %d:
  215.  
  216.  
  217. 13. Checking for wildcards
  218. ==========================
  219.  
  220. This example shows how you can test whether a parameter (%1) of a
  221. batch contains wildcards.
  222.   @echo off
  223.   for %%f in (%1) do if "%%f"=="%1" goto _nowilds
  224.   echo Parameter %1 contains wildcards (or is missing)
  225.   :_nowilds
  226.  
  227.  
  228. 14. Preventing breaking the batch
  229. =================================
  230.  
  231. It is possible to prevent user interrupt of a batch by using the
  232. ctty command to reassign the input (and the output) device. Here is
  233. an example (an elementary password batch requiring inputting an e).
  234. Note the < and > redirections which are needed while the ctty has
  235. been assigned to nul. The ask batch enhancer is included in the
  236. TSBAT collection.
  237.   @echo off
  238.   ctty nul
  239.   echo Now you cannot break the batch with ^C or ^Break > con
  240.   :_ask
  241.   echo Use e to break > con
  242.   ask /b /d < con
  243.   if errorlevel==101 if not errorlevel==102 goto _out
  244.   goto _ask
  245.   :_out
  246.   ctty con
  247.   echo Back to normal. Now you can break the batch with ^C or ^Break.
  248. Note that this trick does not prevent you from rebooting with
  249. alt-crtl-del while the batch is running. For that you need an
  250. external program like noboot.exe from garbo.uwasa.fi:/pc/ts/
  251. tstsr13.zip (os whichever version number is current).
  252.  
  253.  
  254. 15. Prevent a break from bypassing your autoexec.bat
  255. ====================================================
  256.  
  257. You can actually prevent a quick tapping of the break from bypassing
  258. your autoexec.bat by a variation of the trick in the item above. Put
  259. for example
  260.   shell=c:\command.com /p nul
  261. in your config.sys. Before you do, make sure to have a floppy to
  262. boot from in case something goes wrong. I first saw trick when it
  263. was posted in the UseNet comp.os.msdos.programmer newsgroup by
  264. Joseph Gil yogi@cs.ubc.ca.
  265.  
  266. This is not, however, quite all there is to it.  You should put
  267.   ctty con
  268. as the last line to your autoexec.bat.  If you don't, the keyboard
  269. will not be responding, and you must boot from the floppy you so
  270. sensibly had prepared :-).
  271.  
  272.  
  273. 16. Getting the extension
  274. =========================
  275.  
  276. It would be quite useful to be able to extract the extension of a
  277. given file name into an environment variable. Or to be able just to
  278. test whether there is an extension. Here is how to do that. The
  279. batch is based on the information in PC-Magazine July 1992, Vol 11,
  280. No. 13, page 528. It gives the crucial information that if one
  281. precedes the argument of a for loop with a slash (/), then the
  282. argument is interpreted in two parts. The first part is the first
  283. character of the argument, the second part all the rest. Neat,
  284. indeed.
  285.    The problem with my solution below is that it will not recognize
  286. .* or .??? as extensions. But, of course, one can first test for
  287. wildcards as shown in a previous item "Checking for wildcards". See
  288. e.g. UNPACK.BAT for the utilization of this method.
  289.      @echo off
  290.      set exten_=%1
  291.      :_next
  292.      set prev_=%exten_%
  293.      for %%f in (/%exten_%) do set exten_=%%f
  294.      if ".%exten_%"=="%prev_%" goto _extfound
  295.      if not "%exten_%"=="%prev_%" goto _next
  296.      goto _noext
  297.      :_extfound
  298.      echo The filename %1 has an extension %exten_%
  299.      goto _out
  300.      :_noext
  301.      echo The filename %1 has no extension
  302.      :_out
  303.      set exten_=
  304.      set prev_=
  305.  
  306.  
  307. 17. The quote character %
  308. =========================
  309.  
  310. As we know %1 indicates the first parameter given to a batch. Thus
  311. for example echo %1 echoes that parameter.  But what if you ant to
  312. echo the actual string %1 instead.  The % character acts as a quote
  313. character. Thus echo %%1 will indeed be a "%1" instead of its usual
  314. interpretation. Try the following simple test
  315.   @echo off
  316.   if "%1"=="" goto _out
  317.   echo %1
  318.   echo %%1
  319.   :_out
  320. See the item on "Eliminating auxiliary batches" for utilizing this
  321. feature. A good example of utilizing this feature is given by
  322. DELPATH.BAT.
  323.  
  324.  
  325. 18. Eliminating auxiliary batches
  326. =================================
  327.  
  328. Quite a number of batch programming tasks require an auxiliary batch
  329. which the primary batch has to call. Many of these cases can be
  330. eliminated by making the batch call itself (a kind of recursion).
  331. The auxiliary code is put in the batch itself. The trick is best
  332. illustrated by looking at the SHOW.BAT, which provides a wild-carded
  333. TYPE command, and would normally need an auxiliary file to type each
  334. of the individual files. Another example is given by the SAFEDEL.BAT
  335. batch.
  336.    There is also an another trick for a similar purpose. The primary
  337. batch creates and auxiliary batch or batches, which it then calls.
  338. See DELPATH.BAT for an example of this method.
  339.    There was an inventive twist of this method in PC-Magazine August
  340. 1992, Vol. 11, No. 14, p. 527 for getting the volume label of a
  341. disk.  Here is my own example using the same techniques. It sets the
  342. current directory in an environment variable getdir_. I have
  343. utilized this technique in PUSHDIRE.BAT.
  344.   @echo off
  345.   echo @echo off> director.bat
  346.   echo set getdir_=%%2>> director.bat
  347.   echo echo %%getdir_%%>> director.bat
  348.   dir | find "Directory"> go.bat
  349.   call go
  350.   if exist director.bat del director.bat
  351.   if exist go.bat del go.bat
  352.  
  353.  
  354. 19. Utilizing the subst command in paths
  355. ========================================
  356.  
  357. I use the following kind of a simple batch to make some of my
  358. directories easy to reach. The way this simple batch is written it
  359. avoids unnecessary errors if the substitution already has been made.
  360. As a last measure it shows the current substitution status.
  361.   @echo off
  362.   if exist m:\nul echo The substitution has already been made
  363.   if not exist m:\nul subst m: c:\math
  364.   if not exist s:\nul subst s: c:\support
  365.   subst
  366.  
  367.  
  368. 20. How to run a batch once a week (testing for the weekday)
  369. ============================================================
  370.  
  371. The crucial trick is to be able to put the weekday into an
  372. environment variable. For the full treatment see WEEKLY.BAT. The
  373. essential trick needed is below, that is capturing the weekday into
  374. a weekday_ environment variable. No auxiliary programs outside the
  375. normal MsDos commands are needed.
  376.   @echo off
  377.   echo.| date | find "Current" > tmp$$$.bat
  378.   echo set weekday_=%%3> current.bat
  379.   call tmp$$$
  380.   echo %weekday_%
  381.   if "%weekday_%"=="Fri" echo Thank God it's Friday
  382.   if exist tmp$$$.bat del tmp$$$.bat
  383.   if exist current.bat del current.bat
  384.   set weekday_=
  385. In fact, if you substitute %%4 for the %%3 in the above, you'll
  386. capture today's date. Neat, eh?
  387.