Search code examples
cmdenvironment-variableswindows-shell

Expanding env variables in runtime in windows shell


I got troubles with the following sample. I have a file with a list of filenames. I want to check if these files exist, e.g.:

%ProgramFiles%\Internet Explorer\iexplore.exe
%SystemRoot%\sdfsdfsd.exe
%SystemRoot%\explorer.exe

Every path contains envronment variable.

My example of bat file:

echo off  
for /f "tokens=*" %%a in (filelist.txt) do (  
  if exist "%%~a" (  
    echo %%~a exists  
  ) else (  
    echo %%~a doesn't exists  
  )  
)

Filenames are loaded correctly, but I cmd can't find all the files. I think that cmd processor doesn't expand env variables in paths...How I can do it? Or may be there is another problem.

Or how I can replace ! by % in variable and otherwise?


Solution

  • rojo already had the right idea, but there's no need to resort to a subroutine. call will also cause the expansion of nested variables when used in conjunction with e.g. the set command.

    @echo off
    
    setlocal EnableDelayedExpansion
    
    for /f "tokens=*" %%a in (filelist.txt) do (
      call set fname=%%~a
      if exist "!fname!" (
        echo %%~a exists.
      ) else (
        echo %%~a doesn't exist.
      )
    )
    
    endlocal
    

    Edit: As pointed out by @dbenham the delayed expansion in the above code will cause exclamation marks to vanish from filenames. This can be mitigated by moving the setlocal EnableDelayedExpansion instruction inside the loop and prepend the call set with a setlocal DisableDelayedExpansion to prevent %fname% from leaking out of the loop.

    @echo off
    
    for /f "tokens=*" %%a in (filelist.txt) do (
      setlocal DisableDelayedExpansion
      call set fname=%%~a
      setlocal EnableDelayedExpansion
      if exist "!fname!" (
        echo %%~a exists.
      ) else (
        echo %%~a doesn't exist.
      )
      endlocal
    )