LEAVE in a DO /S fileset loop only leaves one subdirectory

May 23, 2010
60
1
Seattle
According to the documentation, "LEAVE exits from the current DO loop and continues with the command following its ENDDO." However, these commands:
Code:
  do file in /d"d:\" /a:-d /s "*"
    echo file is %_cwd\%file
    leave
    echo after the leave
  enddo
show that that is not true when processing subdirectories. In that case, processing of the loop is performed once (for the first file!) in each subdirectory. In each case, the LEAVE is executed, but sends control back to the top of the loop. Control goes to the line after the ENDDO only when one file in each of all the subdirectories has been processed. Adding a number to the LEAVE will produce varying results.

Here's a .btm file you can use to test in a smaller environment than your total disk drive. It builds a test area, runs the do loop, then cleans up after itself. If you already have a directory D:\A, change the code to use a different root directory.
Code:
@ echo off
  :: Pick a root directory name.
  set dr=d
  set dirname=a
  cdd %dr:\
  iff exist %dirname then
    echo There is already a file or directory named %dr:\%dirname.
    echo Change this code to create a root directory that you don't have.
    quit
  endiff

  :: Set up a test environment.
  mkdir /s %dirname\b\c %dirname\bb\cc
  cd %dirname
  touch /s file1 file2  >& NUL

  echo.
  echo Testing this construct:
  echo do file in /d"%dr:\%dirname" /a:-d /s "*"
  echo   echo file is %%_cwd\%%file
  echo   leave
  echo   echo after the leave
  echo enddo
  echo.

  echo Testing with this fileset:
  tree /f
  echo.

  :: Run the test.
  do file in /d"%dr:\%dirname" /a:-d /s "*"
    echo file is %_cwd\%file
    leave
    echo after the leave
  enddo

  :: Clean up afterwards.
  cd \
  del /s /x /y /z %dirname >& NUL
 
Last edited:
May 20, 2008
11,853
121
Syracuse, NY, USA
Here's a simpler one. I reckon it should process only one file but it processes one in each directory.

Code:
v:\> do x in /s * ( echo %x & leave )
age2dhms.btm
vefatica.tgz
10000lines.txt
ipv4-hex.txt
4CONSOLE64.DAT
ScreenToGif
Recording
allservices.txt
Campbell.seq
 
May 23, 2010
60
1
Seattle
The GOTO command will serve as a workable replacement for LEAVE. And the current behavior of the LEAVE does offer some advantages, if you are really looking to process the first file found in each directory. (Otherwise, it would take a bit of coding to accomplish that objective.) But that's not what the documentation says.
 

rconn

Administrator
Staff member
May 14, 2008
12,426
153
LEAVE is working as intended in DO. The documentation is incomplete in the case of a DO /S - if you specify /S, a LEAVE will terminate processing that directory and continue with the next one. LEAVE has always behaved that way (by user request); if you want to cancel a DO /S operation you can use GOTO or LEAVE n (LEAVE n isn't recommended if you're nesting DO's and only want to leave the current nesting level).
 

Similar threads