0

I am modifying a batch script to pass a file location to a makefile (run with nmake). The for loop is supposed to loop over available drives and search for the file if it hasn't been previously set. Batch isn't something I have much experience with, so hopefully someone can spot what's going on.

When I set winbison outside of the for loop that iterates over the drives, the variables get set with the path to win_bison.exe. When I set it inside the for loop, I get "ECHO is on". I thought that was a sympton of how batch handles parsing/expansion. I set EnableDelayedExpansion but got the same result.

Here is my code.

@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.
JR Smith
  • 1,186
  • 15
  • 20

1 Answers1

2

Next script could work:

@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

In above code snippet:

  • quotes in all set "variable=value" to avoid (accidentally forgotten) trailing spaces;
  • if exist %%iNUL to avoid possible The device is not ready error message;
  • right syntax if not defined winbison etc.;
  • !variable! instead of %variable% where necessary (read EnableDelayedExpansion);
  • pushd ... popd pair used instead of cd /D.
JosefZ
  • 28,460
  • 5
  • 44
  • 83
  • I will try this at home tonight and circle back to let you know if it works. Thanks for the response! – JR Smith Jun 08 '15 at 14:51
  • I marked as answer since your response got it working for me. The best practices were a big help. The only one that doesn't make immediate sense is that I found it difficult to search for how "if exist %%iNUL" helps prevent "The device is not ready" error messages. Thanks! – JR Smith Jun 08 '15 at 23:11
  • 1
    @JRSmith Try `pushd X:` or `cd /d X:` Then you get `The device is not ready` if `X:` is a _CD/DVD_ drive with no disc inserted, or `The system cannot find the drive specified` if `X:` does not exist in your system. Or flagrantly invalid pathname, e.g. in `dir c:\:::` gives `"c:\:::" is not a recognized device` error. However, `if exist anything\nul echo present` will work regardless of _anything_ spelling. That's for `NUL` is a _file_ (or _file-like device_ rather) which is present in any existing folder... – JosefZ Jun 09 '15 at 00:26