1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Loop anomaly

Discussion in 'Support' started by Roedy, Nov 3, 2009.

  1. Roedy

    Joined:
    Jun 8, 2008
    Messages:
    120
    Likes Received:
    2
    Is this a bug or a gotcha?

    Code like this works:
    for /A:d %i in (*.*) do (
    if exist %i\jetpdb\ (
    del /FSEXY %i\jetpdb\
    )
    )

    for /A:d %i in (*.*) do (
    if exist %i\%i.exe (
    del /F %i\%i.exe
    )
    )

    But if I combine them into one loop. the second del code is %i.exe code is never executed.

    for /A:d %i in (*.*) do (
    if exist %i\jetpdb\ (
    del /FSEXY %i\jetpdb\
    )
    if exist %i\%i.exe (
    del /F %i\%i.exe
    )
    )

    What gives?
     
  2. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,277
    Likes Received:
    38
    Shouldn't there be a command separator between the two IF commands? And if that doesn't fix the problem, you might check for a DuplicateBugs=Yes directive in your .INI file; if you find it, change the value to No and restart Take Command.

    Finally, if this is in a batch file, it would be worthwhile to rewrite your loop using DO instead of FOR.
     
  3. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    Charles Dye wrote:
    | ---Quote (Originally by Roedy)---
    || Is this a bug or a gotcha?
    ||
    || Code like this works:
    || for /A:d %i in (*.*) do (
    || if exist %i\jetpdb\ (
    || del /FSEXY %i\jetpdb\
    || )
    || )
    ||
    || for /A:d %i in (*.*) do (
    || if exist %i\%i.exe (
    || del /F %i\%i.exe
    || )
    || )
    ||
    || But if I combine them into one loop. the second del code is %i.exe
    || code is never executed.
    ||
    || for /A:d %i in (*.*) do (
    || if exist %i\jetpdb\ (
    || del /FSEXY %i\jetpdb\
    || )
    || if exist %i\%i.exe (
    || del /F %i\%i.exe
    || )
    || )
    ||
    || What gives?
    || ---End Quote---
    | Shouldn't there be a command separator between the two IF commands?
    | And if that doesn't fix the problem, you might check for a
    | DuplicateBugs=Yes directive in your .INI file; if you find it,
    | change the value to No and restart Take Command.
    |
    | Finally, if this is in a batch file, it would be worthwhile to
    | rewrite your loop using DO instead of FOR.

    Some other simplifications:
    - use ISDIR or ISFILE instead of EXIST, as appropriate, but
    - it is not necessary to check whether or not the directory or file
    exists before attempting to delete it, just use the /NE option to
    suppress error reports if the object to be deleted did not exist:

    for /a:d %i in (*) ( del/f/s/ne/x/y %i\jetpdb %+ del/f/ne %i\%i.exe )

    --
    HTH, Steve
     
  4. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,784
    Likes Received:
    29
    On Tue, 03 Nov 2009 11:40:31 -0600, Roedy <> wrote:

    |But if I combine them into one loop. the second del code is %i.exe code is never executed.
    |
    |for /A:d %i in (*.*) do (
    |if exist %i\jetpdb\ (
    |del /FSEXY %i\jetpdb\
    |)
    |if exist %i\%i.exe (
    |del /F %i\%i.exe
    |)
    |)
    |
    |What gives?

    A simplified version of the construction works, both at the command line and in
    a batch file:

    Code:
    v:\> for /l %i in (1,1,2) do (
    More? if 1 == 1 (
    More? echo %i
    More? )
    More? if 1 == 1 (
    More? echo %i
    More? )
    More? )
    1
    1
    2
    2

    --
    - Vince
     
  5. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,784
    Likes Received:
    29
    On Tue, 03 Nov 2009 11:40:31 -0600, Roedy <> wrote:

    |But if I combine them into one loop. the second del code is %i.exe code is never executed.
    |
    |for /A:d %i in (*.*) do (
    |if exist %i\jetpdb\ (
    |del /FSEXY %i\jetpdb\
    |)
    |if exist %i\%i.exe (
    |del /F %i\%i.exe
    |)
    |)

    Worked here:

    Code:
    v:\> md foo
    
    v:\> touch /c foo\foo.exe
    2009-11-03 14:26:10.743  V:\foo\foo.exe
    
    v:\> for /A:d %i in (*.*) do (
    More? if exist %i\jetpdb\ (
    More? del /FSEXY %i\jetpdb\
    More? )
    More? if exist %i\%i.exe (
    More? del /F  %i\%i.exe
    More? )
    More? )
    Deleting V:\foo\foo.exe
         1 file deleted
    --
    - Vince
     
  6. thedave

    Joined:
    Nov 13, 2008
    Messages:
    254
    Likes Received:
    2
    I've bumped into this many times, I still prefer FOR loops out of habit
    although DO loops are preferred. Unfortunately I can't reproduce it on
    demand well enough to file a bug report.

    If you take the "for" loop out of the equation, or even just move the
    two "if" clauses into their own BTM and CALL it, then everything works.

    Whether or not the second IF will be tested may depend on the results of
    the first, it's almost like a failure on the first causes FOR loop to
    start on the next iteration.

    Switching to a DO loop instead of a FOR loop works around the problem,
    and/or you may have better luck with IFF instead of IF.
     
  7. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    1,177
    Likes Received:
    11
    When writing a batch script, DO loops are far superior to FOR loops. The
    debugging ease alone is worth it.

    FOR loops are by definition single line statements. So even if you broke
    up the statement using command grouping, that only influences the
    statement visually, not programatically.

    Second, CMD.EXE has many anomalies with regard to how it processes
    commands vs. how TCC does it. TCC has a "emulate CMD's aberrent behavior"
    mode called "Duplicate CMD.EXE Bugs."

    If "Duplicate CMD.EXE Bugs" is enabled (the default), the following
    command will display nothing, because the second ECHO command is discarded
    along with the first when the condition fails. If Duplicate CMD.EXE Bugs
    is disabled, it will display "hello":

    [c:\] if 1 == 2 echo Wrong! & echo hello


    The original code that was posted was:
    Code:
    for /A:d %i in (*.*) do (
            if exist %i\jetpdb\ (
                    del /FSEXY %i\jetpdb\
            )
            if exist %i\%i.exe (
                    del /F %i\%i.exe
            )
    )
    
    That simplifies down to:

    for %i in (*) do (if cond1 del A & if cond2 del B)

    The CMD.EXE behavior states that if cond1 is false, the 2nd IF statement
    will not be executed.

    -Scott

    thedave <> wrote on 11/06/2009 03:59:09 PM:


     

Share This Page