Trying to do:
fake-command.bat "ping -n 4 -w 1 127.0.0.1 >NUL"
and
fake-command.bat ping -n 4 -w 1 127.0.0.1
The batch file could look like:
@echo %*
It should return:
ping -n 4 -w 1 127.0.0.1 >NUL
and
ping -n 4 -w 1 127.0.0.1
Here a workaround:
@echo off
goto start
------------------------------------------------------
Usage : mystring <command>
Quotes around the command are required only when the
command involves redirection via <, >, >>, or |, etc.
Quotes ensure that the redirection is applied to the
command, rather than the bat command itself.
Examples :
mystring ping -n 4 -w 1 127.0.0.1
mystring "ping -n 4 -w 1 127.0.0.1 >NUL"
------------------------------------------------------
:start
SETLOCAL ENABLEDELAYEDEXPANSION
SET "MYSTRING=%*"
ECHO My String = !MYSTRING!
SET !MYSTRING=MYSTRING:>=^>!
CALL :BATCH_FUNCTION !MYSTRING!
GOTO :EOF
:BATCH_FUNCTION
SET "ARGS=%~1"
ECHO Arguments = !ARGS!
endlocal
GOTO :EOF
the problem is, after: mystring "ping -n 1 127.0.0.1 >NUL"
It returns:
My String =
Arguments =
and after: mystring ping -n 1 127.0.0.1
It returns:
My String = ping -n 1 127.0.0.1
Arguments = ping
UPDATE:
I updated the question with the following code from Get list of passed arguments in Windows batch script (.bat)
@echo off
SETLOCAL DisableDelayedExpansion
SETLOCAL
if exist param.txt (del param.txt)
for %%a in ('%*') do (
set "prompt="
echo on
for %%b in ('%*') do rem * #%~1#
@echo off
) > param.txt
ENDLOCAL
for /F "delims=" %%L in (param.txt) do (
set "param1=%%L"
)
SETLOCAL EnableDelayedExpansion
set "param1=!param1:*#=!"
set "param1=!param1:~0,-2!"
echo My string is = !param1!
With this code, I can get escape characters, but with arguments not in quotes output is broken
What works?
mystring "# % $ ` ' ( ) < << >> > >NUL && & || | { } \ / - + = , . : ; ^ " &REM OK
mystring "ping -n 4 -w 1 127.0.0.1 >NUL" &REM OK
It returns:
My string is = # % $ ` ' ( ) < << >> > >NUL && & || | { } \ / - + = , . : ; ^
My string is = ping -n 4 -w 1 127.0.0.1 >NUL
What does not work?
mystring ping -n 4 -w 1 127.0.0.1 &REM NOK
mystring "*" &REM NOK
It returns:
My string is = ping
The system can not find the file param.txt.
My string is = *
I do not see how in this code add the trick from Mofi.
The batch code working also for single argument "ping -n 4 -w 1 127.0.0.1 >NUL"
is:
@echo off
goto start
------------------------------------------------------
Usage : mystring <command>
Quotes around the command are required only when the
command involves redirection via <, >, >>, or |, etc.
Quotes ensure that the redirection is applied to the
command, rather than the bat command itself.
Examples :
mystring ping -n 4 -w 1 127.0.0.1
mystring "ping -n 4 -w 1 127.0.0.1 >NUL"
------------------------------------------------------
:start
SETLOCAL ENABLEDELAYEDEXPANSION
if "%~2" == "" (SET "MYSTRING=%~1") else (SET "MYSTRING=%*")
ECHO My String = !MYSTRING!
SET "!MYSTRING=MYSTRING:>=^>!"
CALL :BATCH_FUNCTION "!MYSTRING!"
GOTO :EOF
:BATCH_FUNCTION
SET "ARGS=%~1"
ECHO Arguments = !ARGS!
endlocal
GOTO :EOF
The IF condition at beginning makes the important difference.
When the batch file is called with
fake-command.bat ping -n 4 -w 1 127.0.0.1
it is called with 6 arguments and therefore %*
is the right method to assign all arguments to the variable MYSTRING
.
But calling the batch file with
fake-command.bat "ping -n 4 -w 1 127.0.0.1 >NUL"
means just 1 argument enclosed in double quotes is passed to the batch file.
The line
SET "MYSTRING=%*"
resulted in assigning to variable MYSTRING
the string
"ping -n 4 -w 1 127.0.0.1 >NUL"
with the quotes included in string. The remaining quotes causes the wrong result on further processing.
It is not clear what should be assigned to variable ARGS
. If all arguments passed to batch file should be assigned to this variable, it is necessary to enclose !MYSTRING!
also in double quotes on calling the subroutine to pass all arguments of the batch file as 1 argument to the subroutine.
The command FOR could be used to split up the string assigned to MYSTRING
into command (ping) and its arguments (with redirector operators).
UPDATE (after question was updated):
It is not really clear what is the task at all. This batch code is designed to get just first parameter passed to the batch file which is the reason for #%1#
in second, inner FOR loop. Exactly this is what the batch code does although it contains a small mistake with no effect on result.
set "prompt="
has no effect as it is impossible to change prompt text to nothing. So the file params.txt
still contains the prompt text. Better is using prompt $_
or set "prompt=$_"
which defines prompt text being only carriage return + line-feed and therefore producing just an empty line ignored by later used command FOR on reading in the produced file params.txt
. The previous prompt definition is restored with endlocal
after the first outer FOR loop.
Paul, you just replaced both (1)
by ('%*')
which has only the effect that for each parameter passed to the batch file the first and only the first parameter is written to text file params.txt
and next read in several times. Just look on params.txt
to see what it contains after running the batch file with the various parameters. This is of course not really useful.
Here is the batch code modified to output all parameters passed to the batch file.
@echo off
setlocal DisableDelayedExpansion
del param.txt 2>nul
for %%a in (1) do (
set "prompt=$_"
echo on
for %%b in (%*) do rem * #%%~b#
@echo off
) > param.txt
endlocal
setlocal EnableDelayedExpansion
set "ParaNumber=1"
set "AllParameters="
for /F "delims=" %%L in (param.txt) do (
set "Parameter=%%L"
set "Parameter=!Parameter:*#=!"
set "Parameter=!Parameter:~0,-2!"
set "AllParameters=!AllParameters! !Parameter!"
echo Parameter !ParaNumber! = !Parameter!
set /A ParaNumber+=1
)
set "AllParameters=!AllParameters:~1!"
echo All parameters: !AllParameters!
endlocal
Calling the batch file three times with the following three strings one after the other
"# % $ ` ' ( ) < << >> > >NUL && & || | { } \ / - + = , . : ; ^ "
"ping -n 4 -w 1 127.0.0.1 >NUL"
ping -n 4 -w 1 127.0.0.1
results in the following three outputs
Parameter 1 = # % $ ` ' ( ) < << >> > >NUL && & || | { } \ / - + = , . : ; ^
All parameters: # % $ ` ' ( ) < << >> > >NUL && & || | { } \ / - + = , . : ; ^
Parameter 1 = ping -n 4 -w 1 127.0.0.1 >NUL
All parameters: ping -n 4 -w 1 127.0.0.1 >NUL
Parameter 1 = ping
Parameter 2 = -n
Parameter 3 = 4
Parameter 4 = -w
Parameter 5 = 1
Parameter 6 = 127.0.0.1
All parameters: ping -n 4 -w 1 127.0.0.1 >NUL
Calling the batch file with "*"
results now in getting listed as parameters 1 to n all non hidden files in current directory. So this modified version of the batch file does not work for parameters which are valid file name patterns.