将参数中的“,<,>,>>或|等字符转义到batch file中

试图做到:

fake-command.bat "ping -n 4 -w 1 127.0.0.1 >NUL" 

 fake-command.bat ping -n 4 -w 1 127.0.0.1 

batch file可能如下所示:

 @echo %* 

它应该返回:

 ping -n 4 -w 1 127.0.0.1 >NUL 

 ping -n 4 -w 1 127.0.0.1 

这里有一个解决方法:

 @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 

问题在于: mystring "ping -n 1 127.0.0.1 >NUL"

它返回:

 My String = Arguments = 

之后: mystring ping -n 1 127.0.0.1

它返回:

 My String = ping -n 1 127.0.0.1 Arguments = ping 

更新:我使用下面的代码更新了问题 获取Windows批处理脚本(.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! 

有了这段代码,我可以得到转义字符,但是不带引号输出的参数被破坏了

什么工作?

 mystring "# % $ ` ' ( ) < << >> > >NUL && & || | { } \ / - + = , . : ; ^ " &REM OK mystring "ping -n 4 -w 1 127.0.0.1 >NUL" &REM OK 

它返回:

 My string is = # % $ ` ' ( ) < << >> > >NUL && & || | { } \ / - + = , . : ; ^ My string is = ping -n 4 -w 1 127.0.0.1 >NUL 

什么不行?

 mystring ping -n 4 -w 1 127.0.0.1 &REM NOK mystring "*" &REM NOK 

它返回:

 My string is = ping The system can not find the file param.txt. My string is = * 

我不明白在这个代码中如何添加来自Mofi的技巧 。

用于参数"ping -n 4 -w 1 127.0.0.1 >NUL"的批处理代码是:

 @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 

开始时的IF条件是非常重要的。

批处理文件被调用时

 fake-command.bat ping -n 4 -w 1 127.0.0.1 

它被称为6个参数,因此%*是将所有参数分配给变量MYSTRING的正确方法。

但是调用批处理文件

 fake-command.bat "ping -n 4 -w 1 127.0.0.1 >NUL" 

意味着只有一个用双引号括起来的参数被传递给批处理文件。

该线

 SET "MYSTRING=%*" 

导致分配给变量MYSTRING的字符串

 "ping -n 4 -w 1 127.0.0.1 >NUL" 

与包含在字符串中的引号。 其余的报价导致进一步处理错误的结果。

目前还不清楚应该为变量ARGS分配什么。 如果所有传递给批处理文件的参数都应该分配给这个变量,那么必须包含!MYSTRING! 也可以在调用子例程的双引号中将批处理文件的所有参数作为1参数传递给子例程。

命令FOR可以用来将分配给MYSTRING的字符串分成命令(ping)及其参数(使用重定向器操作符)。


更新 (问题更新后):

根本不清楚什么是任务。 这个批处理代码被设计成只获得传递给批处理文件的第一个参数,这是#%1#在第二个内部FOR循环中的原因。 确实,这是批处理代码所做的,尽管它包含一个小错误,但对结果没有影响。

set "prompt="不起作用,因为不可能把提示文字改成空白。 所以文件params.txt仍然包含提示文本。 更好的方法是使用prompt $_set "prompt=$_" ,它定义的提示文本只是回车符+换行符,因此只产生一个空行,后面用FOR命令读取所产生的文件params.txt 。 先前的提示定义在第一个外部FOR循环后用endlocal恢复。

保罗 ,你只是用('%*')替换了两个(1) ,这只有传递给批处理文件的每个参数的第一个参数,只有第一个参数被写入文本文件params.txt ,然后再读入几个倍。 只要看一下params.txt ,看看它包含了什么,然后用各种参数运行批处理文件。 这当然不是很有用。

这里是修改后的批处理代码,以输出传递给批处理文件的所有参数。

 @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 

使用以下三个字符串依次调用批处理文件三次

 "# % $ ` ' ( ) < << >> > >NUL && & || | { } \ / - + = , . : ; ^ " "ping -n 4 -w 1 127.0.0.1 >NUL" ping -n 4 -w 1 127.0.0.1 

导致以下三个输出

 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 

调用具有"*"的批处理文件现在将得到当前目录中所有非隐藏文件的参数1至n。 所以这个批处理文件的修改版本不适用于有效文件名模式的参数。