Home > Software design >  Is it possible to pass unprocessed parameters in a CALL command?
Is it possible to pass unprocessed parameters in a CALL command?

Time:10-01

Take for instance the following example files a.bat and b.bat:

a.bat

@echo off
echo in a: %*
call b %*

b.bat

@echo off
echo in b: %*

and consider this invocation and output:

c:\>a 1 2 3 %% %%%%
in a: 1 2 3 %% %%%%
in b: 1 2 3 % %%

Is there a way to pass the parameters from the command line to b.bat such that it sees the same parameters that a.bat saw? Is it possible to prevent the system from processing the parameters, i.e. removing the escaping % character?

CodePudding user response:

Because this looks so simple, I assume that I must have missed something, but from what you've posted, this looks like all you should need:

C:\a.cmd

@Echo In %~n0: %*
@Call "b.cmd" %%*

C:\b.cmd

@Echo In %~n0: %*

Example:

C:\>a 1 2 3 %% %%%%
In a: 1 2 3 %% %%%%
In b: 1 2 3 %% %%%%

CodePudding user response:

Yes you can do that, but instead of removing a character, you need to add more escape characters.

@echo off
REM *** Fetch all arguments
goto :init :initCallBack
:initCallBack

REM *** Prepare the arguments for a secure CALL
call :prepareArgument allArgs arg

REM *** b.bat will see the same arguments like this file
call b.bat %%allArgs%%
exit /b

:init
::: Get all arguments with minimal interference
::: Only linefeeds and carriage returns can't be fetched
::: Only linefeeds can create a syntax error
::: return arg=All arguments, arg1..arg<n>=A single argument
setlocal EnableDelayedExpansion
set "argCnt="
:getArgs
>"%temp%\getArg.txt" <"%temp%\getArg.txt" (
  setlocal DisableExtensions
  (set prompt=#)
  echo on
  if defined argCnt (
    for %%a in (%%a) do rem . %1.
  ) ELSE (
    for %%a in (%%a) do rem . %*.
  )
  echo off
  endlocal

  set /p "arg%argCnt%="
  set /p "arg%argCnt%="
  set "arg%argCnt%=!arg%argCnt%:~7,-2!"
  if defined arg%argCnt% (
    if defined argCnt (
        shift /1
    )
    set /a argCnt =1
    goto :getArgs
  ) else set /a argCnt-=1
)
del "%temp%\getArg.txt"
goto :initCallBack

:prepareArgument
::: Convert a string, so it can be used as an argument for calling a program
set "var=!%~2!"
if defined var (
    set "var=!var:^=^^!"
    set "var=!var:&=^&!"
    set "var=!var:|=^|!"
    set "var=!var:>=^>!"
    set "var=!var:<=^<!"
    set "var=%var%"
)
set "%~1=!var!"
exit /b
  • Related