如何接收最奇怪的命令行参数?

jeb*_*jeb 15 escaping batch-file

正如在另一个线程中所讨论的如何避免cmd.exe解释shell特殊字符,如<> ^ 从命令行获取所有参数并不容易.

一个简单的

set var=%1
set "var=%~1"
Run Code Online (Sandbox Code Playgroud)

如果你有这样的要求,还不够

myBatch.bat abc"&"^&def
Run Code Online (Sandbox Code Playgroud)

我有一个解决方案,但它需要一个临时文件,它也不是防弹.

@echo off
setlocal DisableDelayedExpansion
set "prompt=X"
(
    @echo on
    for %%a in (4) do (
        rem #%1#
    ) 
) > XY.txt
@echo off
for /F "delims=" %%a in (xy.txt) DO (
  set "param=%%a"
)
setlocal EnableDelayedExpansion
set param=!param:~7,-4!
echo param='!param!'
Run Code Online (Sandbox Code Playgroud)

它失败了像myBatch.bat%a,它显示4而不是%a

在这种情况下,简单的回声%1将起作用.
这显然是for循环,但我不知道如何改变它.
也许存在另一个简单的解决方案

我不需要这个来解决实际问题,但我喜欢在每种情况下都是防弹的解决方案,而不仅仅是在大多数情况下.

dbe*_*ham 9

我认为没有人发现任何漏洞,除了无法读取参数中的换行符:

@echo off
setlocal enableDelayedExpansion
set argCnt=1
:getArgs
>"%temp%\getArg.txt" <"%temp%\getArg.txt" (
  setlocal disableExtensions
  set prompt=#
  echo on
  for %%a in (%%a) do rem . %1.
  echo off
  endlocal
  set /p "arg%argCnt%="
  set /p "arg%argCnt%="
  set "arg%argCnt%=!arg%argCnt%:~7,-2!"
  if defined arg%argCnt% (
    set /a argCnt+=1
    shift /1
    goto :getArgs
  ) else set /a argCnt-=1
)
del "%temp%\getArg.txt"
set arg
Run Code Online (Sandbox Code Playgroud)

以上内容来自一个生动的DosTips讨论 - http://www.dostips.com/forum/viewtopic.php?p=13002#p13002.DosTips用户Liviu提出了关键SETLOCAL DisableExtensions部分.