For /L - MORE and @ECHO OFF

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
einstein1969
Expert
Posts: 976
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

For /L - MORE and @ECHO OFF

#1 Post by einstein1969 » 01 Mar 2014 01:41

hi to all,

i have few questions for this code:

Code: Select all

@echo off

echo(|more|(

  for /l %%k in (1,1,100000) do (
    (if %%k==5 exit)
    echo %%k
  )

)

echo end


seem that execute the for /L without count to 100000 and not exit from current context.

It is safe?

Why the @echo off don't work?

einstein1969

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: For /L - MORE and @ECHO OFF

#2 Post by foxidrive » 01 Mar 2014 02:31

It leaves me wondering what you hope to gain from that code?


TTBOMK Piping through a for loop is undocumented and unsupported,
and I've seen erratic behaviour from doing so in the past too.

jeb
Expert
Posts: 1063
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: For /L - MORE and @ECHO OFF

#3 Post by jeb » 01 Mar 2014 07:18

foxidrive wrote:Piping through a for loop is undocumented and unsupported

Why this should be undocumented or unsupported?

It's simply a pipe, so both sides of the pipe are executed in a new cmd context (instead of a batch context).

That's also the cause why the echo off seems not to work.

Effectivly you execute

Code: Select all

  for /l %k in (1,1,100000) do (
    (if %k==5 exit)
    echo %k
  )

In a cmd context, so the exit only leaves that context.

jeb

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: For /L - MORE and @ECHO OFF

#4 Post by foxidrive » 01 Mar 2014 10:08

jeb wrote:
foxidrive wrote:Piping through a for loop is undocumented and unsupported

Why this should be undocumented or unsupported?

It's simply a pipe, so both sides of the pipe are executed in a new cmd context (instead of a batch context).


It fails in spectacular ways though. Put a pipe or two in a for /f command and pipe something into the for.

I haven't seen a single instance of that in any microsoft documentation and have never seen anyone use it in decades.

A fellow posted his quest to do that last month I think and it was fubar - not sure where the thread was.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: For /L - MORE and @ECHO OFF

#5 Post by dbenham » 01 Mar 2014 10:33

foxidrive wrote:It fails in spectacular ways though. Put a pipe or two in a for /f command and pipe something into the for.

I don't see the problem.

Code: Select all

@echo off
echo hello|for /f %%A in ('"echo world|findstr ."') do @(
  findstr .
  echo %%A
)

echo goodbye|for /f %%A in ('"findstr .|findstr ."') do @echo %%A
--OUTPUT--

Code: Select all

hello
world
goodbye

I also don't see what it is good for :wink:

Dave Benham

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: For /L - MORE and @ECHO OFF

#6 Post by foxidrive » 01 Mar 2014 10:42

dbenham wrote:
foxidrive wrote:It fails in spectacular ways though. Put a pipe or two in a for /f command and pipe something into the for.

I don't see the problem.
I also don't see what it is good for :wink:

Dave Benham


:)

I can't be arsed looking for the thread - and I don't know which forum is was on - it worked fine for one pipe inside the for /f but when a second pipe was added it failed.
I tested it here and confirmed it in his test case, but I don't have the interest to devise multiple tests for it now. :)

jeb
Expert
Posts: 1063
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: For /L - MORE and @ECHO OFF

#7 Post by jeb » 01 Mar 2014 10:47

dbenham wrote:I also don't see what it is good for :wink:


From a tee.bat

Code: Select all

@echo off
setlocal enableDelayedExpansion
if "%~1" equ ":tee" goto :tee

:lock
....
    for /f %%A in ("!yes!") do (
      find /n /v ""
      echo :END
      echo %%A
    ) >"%teeTemp%.tmp" | <"%teeTemp%.tmp" "%~f0" :tee %* 7>&1 >nul


There are many for loops here inside of pipe executions :wink:

I can't remember the full name of the author, but I suppose it begans with Dave B. :D

jeb

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: For /L - MORE and @ECHO OFF

#8 Post by dbenham » 01 Mar 2014 10:59

foxidrive wrote:it worked fine for one pipe inside the for /f but when a second pipe was added it failed.
I tested it here and confirmed it in his test case, but I don't have the interest to devise multiple tests for it now. :)
:?:

I'm don't quite follow the point you are making. But the number of pipes should not matter.

Code: Select all

@echo off
echo goodbye|for /f %%A in ('"findstr .|findstr .|findstr .|findstr .|findstr ."') do @echo %%A
--OUTPUT--

Code: Select all

goodbye

What I can see being difficult to work with is quoting and escape sequences given that there are three levels of implicit CMD /C : 1 level for the outer pipe, 1 level for the FOR /F command IN() clause, and 1 level for the inner pipes within the IN() clause.

But I agree with jeb, there is no inherent reason why a piped FOR F cannot contain its own pipes. Nor do I see any reason to expect special documentation for such a situation.


Dave Benham

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: For /L - MORE and @ECHO OFF

#9 Post by foxidrive » 01 Mar 2014 11:12

dbenham wrote:I'm don't quite follow the point you are making. But the number of pipes should not matter.

Nor do I see any reason to expect special documentation for such a situation.


It does make a difference though.

Before I saw this person trying it, I had never seen any person try it - and I've followed many clever people for decades.
That doesn't mean that it doesn't work, in theory, but in practice there are issues that arose.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: For /L - MORE and @ECHO OFF

#10 Post by foxidrive » 01 Mar 2014 11:35

I found the test case that doesn't work. The first dir line shows the files (with echo on curiously) but the second fails.

Code: Select all

@echo off
dir /b /a-d | for /F "delims=" %%a in (' findstr "a" ') do echo %%a
pause
dir /b /a-d | for /F "delims=" %%a in (' findstr "a" ^| findstr "a" ') do echo %%a
pause

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: For /L - MORE and @ECHO OFF

#11 Post by Liviu » 01 Mar 2014 11:52

This seems to have got overlooked in the ensuing discussion about pipes, but...
einstein1969 wrote:this code [...] seem that execute the for /L without count to 100000 and not exit from current context.
...I don't see that. Tried it in both XP and Win7, and the loop executes 5 times as expected, then exits right before "echo 5".

foxidrive wrote:I can't be arsed looking for the thread - and I don't know which forum is was on - it worked fine for one pipe inside the for /f but when a second pipe was added it failed.

Would you recall some context or keywords? I don't remember the issue, and a quick search finds nothing relevant. Several collectors of cmd oddities around here are curious and will be eternally grateful ;-)

Liviu

Aacini
Expert
Posts: 1932
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: For /L - MORE and @ECHO OFF

#12 Post by Aacini » 01 Mar 2014 12:03

einstein1969 wrote:hi to all,

i have few questions for this code:

Code: Select all

@echo off

echo(|more|(

  for /l %%k in (1,1,100000) do (
    (if %%k==5 exit)
    echo %%k
  )

)

echo end


seem that execute the for /L without count to 100000 and not exit from current context.

It is safe?

Why the @echo off don't work?

einstein1969


When I saw this code I thought it may be used to implement a simpler while loop, so I made several tests. For example:

Code: Select all

@echo off
setlocal

set /A index=0, sum=0
echo/|(@echo off
   for /L %%? in (1,0,1) do (
      set /A index+=1, sum+=index > NUL
      echo !index!
      if !index! == 10 exit !sum!
   )
)
echo Returned value: %errorlevel%


There is, however, a point that can not be solved in this code: to programatically enable Delayed Expansion in the FOR loop in order to access modified values. If the "FOR /L" is executed via "CMD /V:ON", then the EXIT command also terminate the original command-line window. The only way to achieve this is using REGEDIT.EXE to modify this value in the registry:

Code: Select all

HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion = 0x1


After that, previous code run correctly:

Code: Select all

C:\> While.bat
1
2
3
4
5
6
7
8
9
10
Returned value: 55


A last point: if I used "EQU" instead of "==" in the IF command, an error about "10 unexpected at this time" is issued. I don't understand why this happen, because Extensions are enabled by default even in the command-line context!

Antonio
Last edited by Aacini on 01 Mar 2014 12:10, edited 2 times in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: For /L - MORE and @ECHO OFF

#13 Post by foxidrive » 01 Mar 2014 12:04

Liviu wrote:Would you recall some context or keywords? I don't remember the issue, and a quick search finds nothing relevant. Several collectors of cmd oddities around here are curious and will be eternally grateful ;-)

Liviu


I posted the issue in the message above yours.

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: For /L - MORE and @ECHO OFF

#14 Post by Liviu » 01 Mar 2014 12:12

foxidrive wrote:I posted the issue in the message above yours.

Duh. I mean, thanks ;-) Wasn't paying attention, but then I thought the forum was supposed to warn me if a new message had posted while I was logged in and editing mine.

Liviu

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: For /L - MORE and @ECHO OFF

#15 Post by Ed Dyreen » 01 Mar 2014 12:37

foxidrive wrote:I found the test case that doesn't work. The first dir line shows the files (with echo on curiously) but the second fails.

Code: Select all

@echo off
dir /b /a-d | for /F "delims=" %%a in (' findstr "a" ') do echo %%a
pause
dir /b /a-d | for /F "delims=" %%a in (' findstr "a" ^| findstr "a" ') do echo %%a
pause

Is that not just like a quoting/escaping problem ? If I adjust the syntax error it works

Code: Select all

dir /b /a-d | for /F "delims=" %%a in ('" findstr "a" | findstr "a" "') do @echo.a=%%a_
dir /b /a-d | for /F "delims=" %%a in (' findstr "a" ^^^| findstr "a" ') do @echo.a=%%a_
The @ is more strange to me, must be some bug :S

The escaping it twice has to do with the cmd context running another cmd context, I guess, not sure, euh probably not :P lol

Post Reply