在windows shell中扩展运行时的env变量

时间:2013-02-27 12:01:45

标签: cmd environment-variables windows-shell

我遇到以下样本的麻烦。我有一个文件列表的文件。我想检查这些文件是否存在,例如:

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

每个路径都包含envronment变量。

我的bat文件示例:

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

文件名已正确加载,但我cmd无法找到所有文件。我认为cmd处理器不会在路径中扩展env变量......我怎么能这样做?或者可能还有另一个问题。

或者我如何在变量中替换! {/ 1}}?

2 个答案:

答案 0 :(得分:2)

尝试使用call强制评估文本文件中的变量。

@echo off
setlocal
for /f "tokens=*" %%a in (filelist.txt) do (
    call :checkExists "%%~a"
)
goto :EOF

:checkExists <filename>
if exist %1 (
    echo %~1 exists
) else (
    echo %~1 doesn't exists
)
goto :EOF

答案 1 :(得分:2)

rojo已经有了正确的想法,但没有必要求助于子程序。 call与嵌套变量结合使用时也会导致嵌套变量的扩展。 set命令。

@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

编辑:正如@dbenham所指出的,上述代码中的延迟扩展将导致感叹号从文件名中消失。这可以通过在循环中移动setlocal EnableDelayedExpansion指令并在call set前加setlocal DisableDelayedExpansion来缓解,以防止%fname%泄漏出循环。

@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
)