【问题标题】:Cannot set argument value to a variable resulting empty in Windows batch script无法将参数值设置为导致 Windows 批处理脚本为空的变量
【发布时间】:2015-02-19 15:04:16
【问题描述】:

我正在使用SHIFT 遍历所有命令行参数。我得到ECHO is off. 的结果。它可能会打印空变量。

:argLoopStart
    SET paramName=
    SET arg=%1
    IF -%arg%-==-- GOTO argLoopEnd
    IF %arg:~0,2%==-- (
        SET paramName=%arg%
        ECHO %arg%
        ECHO %paramName%
    ) 
    SHIFT
    GOTO argLoopStart
:argLoopEnd

通过运行命令fake-command --dbs=mydbname,我得到了这个:

--dbs
ECHO is off.

根据上面的代码,ECHO %arg% 打印 --dbsECHO %paramName% 打印 ECHO is offSET paramName=%arg% 的行没有按我的预期工作。 %parameName% 也应该打印 --dbs。但是,它似乎打印了一个空变量。

【问题讨论】:

  • 您为什么期望 %paramName%--dbs 而不是 --dbs=mydbname
  • --dbs=mydbname 等于 --dbs mydbname= 被编译器忽略。如您所见,%paramName% 应该与打印--dbs%arg% 相同,因为SET paramName=%arg% 行。

标签: windows batch-file arguments command-line-arguments


【解决方案1】:

您需要在脚本顶部使用SETLOCAL EnableDelayedExpansion 启用延迟扩展:

延迟扩展会导致变量在执行时被扩展 时间而不是解析时间,此选项与 SETLOCAL 命令。当延迟扩展生效时,变量可能是 使用 !variable_name! 引用! (除了正常的 %variable_name%)

@echo off
setlocal enabledelayedexpansion

:argLoopStart
set paramName=
set arg=%1
if -!arg!-==-- goto argLoopEnd
if %arg:~0,2%==-- (
    set paramName=!arg!
    echo !arg!
    echo !paramName!
)
shift
goto argLoopStart

:argLoopEnd

【讨论】:

  • EnableDelayedExpansion 已经在我的脚本顶部。我提到的代码只是整个脚本的一部分。无论如何,你能解释一下为什么需要它吗?
  • 您仍然需要将% 替换为! 才能使其正常工作。至于 为什么 它起作用,我不完全确定,因为我不太熟悉批处理的内部工作原理。也就是说,您的代码的行为方式类似于 for 循环,它需要为其中的变量值启用延迟扩展,以便在每次循环迭代时更新。
  • @sithu:请发布脚本的所有重要部分。猜谜游戏在大约五千次之后变得无聊。请在 SO 中搜索 delayed expansion 以获取数百篇解释为什么需要使用 !var!call %%var%% 语法的文章。如果您显然不知道为什么要使用 enabledelayedexpansion,为什么还要调用它?
  • @Magoo 在这段代码之前只有几行(3 或 4 行)SET 用于其他变量。我正在尽可能地对这些参数处理进行编码。在答案中添加关于EnableDelayedExpansion 的解释会提高答案的质量,对吗?很遗憾你没有那样想。
  • @Sithu 我一直在寻找为什么需要延迟扩展的解释,这比“因为否则它将无法工作”更好,我发现 Jeb 的 this answer 表明 @ 987654335@ 括号块内的命令需要它才能在正确的时间进行处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
  • 2012-07-07
  • 2014-02-04
  • 2014-10-10
  • 1970-01-01
相关资源
最近更新 更多