【问题标题】:Variable setting exhibits unexpected behavior when set inside for loop变量设置在 for 循环内设置时表现出意外行为
【发布时间】:2015-08-22 12:00:12
【问题描述】:

我正在修改批处理脚本以将文件位置传递给 makefile(使用 nmake 运行)。 for 循环应该循环可用驱动器并搜索文件(如果之前没有设置)。批处理不是我有太多经验的东西,所以希望有人能发现发生了什么。

当我在遍历驱动器的 for 循环之外设置 winbison 时,变量将设置为 win_bison.exe 的路径。当我在 for 循环中设置它时,我得到“ECHO 开启”。我认为这是批处理如何处理解析/扩展的一个症状。我设置了 EnableDelayedExpansion 但得到了相同的结果。

这是我的代码。

@ECHO OFF
setlocal EnableDelayedExpansion
set currentDir=%cd%
set winbison=
set winflex=

set drives=
for /f "delims=" %%a in ('fsutil fsinfo drives') do @set drives=%%a

REM :~8 is to slice off "Drives: " returned by fsutil
for %%i in (%drives:~8%) do (
    chdir /d %%i
    if not defined [%winbison%] (
        set winbison=
        for /f "delims=" %%a in ('dir win_bison.exe /s /b 2^>nul') do @set winbison=%%a
    @ECHO ON
        echo test
        echo %winbison%
    @ECHO OFF
    )

    if not defined [%winflex%] (
        set winflex=
        for /f "delims=" %%a in ('dir win_flex.exe /s /b 2^>nul') do @set winflex=%%a
    )
)

chdir /d %currentDir%

@ECHO ON
echo %winbison%
... stuff gets passed to nmake.

【问题讨论】:

  • 也许this可以帮助你

标签: batch-file


【解决方案1】:

下一个脚本可以运行:

@ECHO OFF
setlocal enableextensions EnableDelayedExpansion
set "currentDir=%cd%"
set "winbison="
set "winflex="

set "drives="
for /f "delims=" %%a in ('fsutil fsinfo drives') do @set "drives=%%a"

REM :~8 is to slice off "Drives: " returned by fsutil
for %%i in (%drives:~8%) do (
  if exist %%iNUL (
    pushd %%i
    if not defined winbison (
      for /f "delims=" %%a in (
        'dir win_bison.exe /s /b 2^>nul') do @set "winbison=%%a"
      echo [debug] %%i winbison=!winbison!
    )

    if not defined winflex (
      for /f "delims=" %%a in (
        'dir win_flex.exe /s /b 2^>nul') do @set "winflex=%%a"
      echo [debug] %%i winflex=!winflex!
    )
    popd
  )
)

echo [debug] winbison=%winbison%
echo [debug] winflex=%winflex%

rem ... stuff gets passed to nmake

在上面的代码sn-p中:

  • 在所有set "variable=value" 中加上引号以避免(意外忘记)尾随空格;
  • if exist %%iNUL 避免可能出现的The device is not ready 错误消息;
  • 正确的语法if not defined winbison等;
  • 必要时!variable! 而不是%variable%(阅读EnableDelayedExpansion);
  • 使用pushd ... popd 对而不是cd /D

【讨论】:

  • 今晚我会在家里试试这个,然后转回来告诉你它是否有效。感谢您的回复!
  • 我标记为答案,因为您的回复对我有用。最佳实践有很大帮助。唯一没有立即意义的是,我发现很难搜索“如果存在 %%iNUL”如何帮助防止“设备未准备好”错误消息。谢谢!
  • @JRSmith 尝试pushd X:cd /d X: 如果X: 是未插入光盘的CD/DVD 驱动器,则您会得到The device is not ready,或者The system cannot find the drive specified如果您的系统中不存在X:。或公然无效的路径名,例如在dir c:\::: 给出"c:\:::" is not a recognized device 错误。但是,if exist anything\nul echo present 将不管 anything 拼写如何工作。那是因为NUL 是一个存在于任何现有文件夹中的 file(或 类似文件的设备)...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-20
相关资源
最近更新 更多