I have a frustrating problem when I want to use the pipe(|) feature with the Window's CMD shell's CALL :Label option. I have a very small example (below): call-test.cmd and sample output.
The nub of the issue was/is to pipe the output of a CMD script to another program, for example the tee utility, or find command. For example:
@call :Label-02 param | tee call-test.log
Which would start the current command file at the label Label-02 and pipe the output to tee. Unfortunately using the pipe character(|) on the line with "call :label" option gives an error:
Invalid attempt to call batch label outside of batch script.
Whereas, "call example.cmd | tee example.log", works just fine.
The other IO redirection > works OK. It is just the one case when "call :label pipe(|)" is used that fails. To me it just looks like a windows bug.
Does anyone have a workaround and/or know of an explanation?
Thanks, Will
call-test output
c:\> call-test
[start]
label 03 :: p1
Invalid attempt to call batch label outside of batch script.
Invalid attempt to call batch label outside of batch script.
[done]
Press any key to continue . . .
call-test
@echo off
@rem call-test.cmd
@rem _________________________________________________
@rem Test :label call option for .cmd files.
@rem
@echo ^ [start]
@call :Label-03 p1
@call :Label-02 second | find " "
@call :Label-02 second | tee call-test.log
@goto Done
@rem _________________________________________________
:Label-01
@echo ^ label 01 :: %1
@goto Exit
@rem _________________________________________________
:Label-02
@echo ^ label 02 :: %1
@goto Exit
@rem _________________________________________________
:Label-03
@echo ^ label 03 :: %1
@goto Exit
@rem _________________________________________________
:Done
@echo ^ [done]
@pause
@rem _________________________________________________
:Exit
@exit /b
The cause is, that a pipe starts both sides in a cmd context (both run parallel in one cmd-box), and each side is interpreted as a real command line argument, and on the cmd line labels aren't allowed.
But you can call your function, if you restart your batch.
if not "%1"=="" goto %1
@call "%~0" :Label-02 param | tee call-test.log
EDIT: The complete sample
@echo off
if not "%~1"=="START" goto :normalStart
shift
shift
call %0 %1 %2 %3 %4 %5 %6 %7 %8
exit /b
:normalStart
rem call-test.cmd
rem _________________________________________________
rem Test :label call option for .cmd files.
rem
echo ^ [start]
rem call :Label-03 p1
rem call :Label-02 second | find " "
call "%~dpf0" "START" :Label-02 second | tee call-test.log
goto Done
rem _________________________________________________
:Label-01
echo ^ label 01 :: %1
goto Exit
rem _________________________________________________
:Label-02
echo ^ label 02 :: %1
goto Exit
rem _________________________________________________
:Label-03
echo ^ label 03 :: %1
goto Exit
rem _________________________________________________
:Done
echo ^ [done]
pause
rem _________________________________________________
:Exit
exit /b