Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Windows CMD pipe( | ) feature with CALL :Label command option?

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
    
like image 794
will Avatar asked Nov 21 '10 07:11

will


People also ask

How do you pipe the output of a command to a file in Windows?

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.

How does pipe work in CMD?

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.

Does CMD support pipe?

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.


1 Answers

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
like image 101
jeb Avatar answered Nov 02 '22 04:11

jeb