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
To redirect the output of a command to a file, type the command, specify the > or the >> operator, and then provide the path to a file you want to the output redirected to. For example, the ls command lists the files and folders in the current directory.
Pipe is used to combine two or more commands, and in this, the output of one command acts as input to another command, and this command's output may act as input to the next command and so on. It can also be visualized as a temporary connection between two or more commands/ programs/ processes.
Pipe shell commandThe | command is called a pipe. It is used to pipe, or transfer, the standard output from the command on its left into the standard input of the command on its right. # First, echo "Hello World" will send Hello World to the standard output.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With