Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The ^ gets doubled when sending string as parameter to function in batch script

This is my code:

set var1="`netsh int ipv4 show interface ^| findstr /I Network`"

call:GetEles %var1%
goto:eof

:GetEles
for /F "tokens=1 usebackq" %%F IN (%~1) do echo %%F
goto:eof

When I check the command while it is running, the ^ becomes doubled inside function :GetEles:

for /F "token=1 usebackq" %%F IN (`netsh int ipv4 show interface ^^| findstr /I Network`) do echo %%F

That doubled ^ makes my script failing, how can I solve it?

like image 703
lee Avatar asked Jan 05 '23 16:01

lee


2 Answers

As others already described, this is a nasty "feature" of the call command.

There are several options to work around that:

  1. Simply undo the caret doubling in the sub-routine:

    @echo off
    set "VAR=caret^symbol"
    call :SUB "%VAR%"
    exit /B
    
    :SUB
        set "ARG=%~1"
        echo Argument: "%ARG:^^=^%"
        exit /B
    
  2. call introduces a second parsing phase, so let the second one expand the variable:

    @echo off
    set "VAR=caret^symbol"
    call :SUB "%%VAR%%"
    exit /B
    
    :SUB
        echo Argument: "%~1"
        exit /B
    
  3. Pass the value by reference (so the variable name) rather than by value:

    @echo off
    set "VAR=caret^symbol"
    call :SUB VAR
    exit /B
    
    :SUB
        setlocal EnableDelayedExpansion
        echo Argument: "!%~1!"
        endlocal
        exit /B
    
  4. Do not pass the variable value to the sub-routine, read the (global) variable there instead:

    @echo off
    set "VAR=caret^symbol"
    call :SUB
    exit /B
    
    :SUB
        echo Argument: "%VAR%"
        exit /B
    
like image 64
aschipfl Avatar answered Jan 14 '23 13:01

aschipfl


Read Buggy behaviour when using CALL:

Redirection with & | <> does not work as expected.

If the CALL command contains a caret character within a quoted string "test^ing", the carets will be doubled.

Try following code snippet:

@echo off
SETLOCAL EnableExtensions

set "var1=`netsh int ipv4 show interface ^| findstr /I "Network"`"

call:GetEles "%var1%"
goto:eof

:GetEles
echo variable  "%var1%"
echo parameter "%~1"
for /F "tokens=1 usebackq" %%F IN (%var1%) do echo %%F
goto:eof

Output:

d:\bat> D:\bat\SO\41769803.bat

variable  "`netsh int ipv4 show interface ^| findstr /I "Network"`"
parameter "`netsh int ipv4 show interface ^^| findstr /I "Network"`"
like image 41
JosefZ Avatar answered Jan 14 '23 11:01

JosefZ