1

我一直在将一些 shell 代码翻译成 MS-DOS Batch。在我的代码中,我有示例:

for %%i in (%*) do set "clargs=!clargs! %%i"

如果我输入参数“-?” (不带引号),它不会添加到 clargs。我想这是因为'?是一个通配符。由于问号位于论点中,我能做些什么来确保 for 不会做特殊的事情吗?

4

2 回答 2

2

你是对的,通配符*并且?在 FOR IN() 子句中使用时总是被扩展。不幸的是,没有办法阻止通配符扩展。

如果参数包含通配符,则不能使用 FOR 循环访问所有参数。相反,您应该使用 GOTO 循环和 SHIFT 命令。

set clargs=%1
:parmLoop
if "%~1" neq "" (
  set clargs=%clargs% %1
  shift /1
  goto :parmLoop
)

尽管您的示例非常愚蠢,因为结果clargs变量最终包含相同的一组值,这些值已经存在于%*. 如果您只想设置一个包含所有值的变量,只需使用set clargs=%*

更典型地,创建参数变量的“数组”。

set argCnt=0
:parmLoop
if "%~1" equ "" goto :parmsDone
set /a argCnt+=1
set arg%argCnt%=%1
shift /1
goto :parmLoop
:parmsDone

:: Working with the "array" of arguments is best done with delayed expansion
setlocal enableDelayedExpansion
for /l %%N in (1 1 %argCnt%) do echo arg%%N = !arg%%N!

有关处理传递给 Windows 批处理脚本的 unix 样式参数的可靠方法,请参阅Windows Bat 文件可选参数解析。

于 2013-05-26T15:57:05.853 回答
0
@ECHO OFF
SETLOCAL
SET dummy=%*
FOR /f "tokens=1*delims==" %%f IN ('set dummy') DO CALL :addme %%g
ECHO %clargs%
GOTO :eof

:addme
IF "%~1"=="" GOTO :EOF 
IF DEFINED clargs SET clargs=%clargs% %1
IF NOT DEFINED clargs SET clargs=%1
SHIFT
GOTO addme

我非常怀疑你会得到一个完全防弹的解决方案。例如,上述解决方案将删除分隔符(逗号、分号、等号)。其他解决方案可能存在右括号问题;有永恒的%问题^- 但它会处理-?

但是出于您的目的,从您所展示的内容来看,有什么问题

set clargs=%clargs% %*

(毫无疑问,你会想要进一步处理,但我还是不行......)

于 2013-05-26T15:56:50.417 回答