批量嵌套 for 循环 returns 不正确的值
Batch nested for loops returns incorrect value
我的脚本中的问题是索引目录文件时的 return 值。
首先,我需要循环我的数组,其次是在目录中查找文件。 Return 值仍然没有变化,并显示所有变量中的最新值。
是的,我知道,这可能是因为我使用 setx 但只有 set 才行不通。
for /L %%G in (1,1,%i%) do (
if NOT {arch}=={32} (
setx DriverPath !DefaultPath!driver\!DriverPath64[%%G]! >nul 2>&1
) else (
setx DriverPath !DefaultPath!driver\!DriverPath32[%%G]! >nul 2>&1
)
:: looking for inf file
for /r "%DriverPath%\" %%f in (*.inf) do (
set PrinterDriverInf[%%G]=%%f
)
)
将 ::
评论更改为常规 rem
评论。
::
实际上是一个损坏的标签和标签(损坏或其他)导致代码块问题(带括号的语句序列)
另一件事(我猜)是您试图比较字符串 {arch}
和 {32}
.
这是命令解析器看到的内容:
if the string {arch} equals {32}, do something
我猜你想要这个:
if the content of arch variable equals 32, do something
如果是这样,这就是适合您的命令。
if "%arch%"=="32" echo your commands here
始终使用引号 "
而不是 {
和 }
,因为它们更安全。
- 为什么要使用
setx
?正常的 set
命令不够用吗?请注意,setx
不会更改当前 cmd
实例的变量。
if not
语句的计算结果始终为 True,因为您在 ==
的两边都声明了文字字符串。你是说 %arch%
而不是 arch
吗?
- 您需要延迟
!DriverPath!
的扩展。但是for /R
不能使用延迟展开变量,所以必须把for /R
循环移到子程序中才能使用立即%
-展开,或者你临时换个目录并让 for /R
默认为那个(已更改的)当前目录。
- 切勿在带括号的块中使用
::
注释,而应使用 rem
。
固定代码如下:
setlocal EnableDelayedExpansion
for /L %%G in (1,1,%i%) do (
if not "%arch%"=="32" (
setx DriverPath !DefaultPath!driver\!DriverPath64[%%G]! >nul 2>&1
set "DriverPath=!DefaultPath!driver\!DriverPath64[%%G]!"
) else (
setx DriverPath !DefaultPath!driver\!DriverPath32[%%G]! >nul 2>&1
set "DriverPath=!DefaultPath!driver\!DriverPath32[%%G]!"
)
rem looking for inf file
call :SUB PrinterDriverInf[%%G] "%DriverPath%"
)
endlocal
goto :EOF
:SUB
for /R "%~2" %%f in (*.inf) do (
set "%~1=%%f"
)
goto :EOF
您甚至可以像这样简化代码:
setlocal EnableDelayedExpansion
if not "%arch%"=="32" set "arch=64"
for /L %%G in (1,1,%i%) do (
setx DriverPath !DefaultPath!driver\!DriverPath%arch%[%%G]! >nul 2>&1
set "DriverPath=!DefaultPath!driver\!DriverPath%arch%[%%G]!"
rem looking for inf file
pushd "!DriverPath!" && (
for /R %%f in (*.inf) do (
set "PrinterDriverInf[%%G]=%%f"
)
popd
)
)
endlocal
我的脚本中的问题是索引目录文件时的 return 值。 首先,我需要循环我的数组,其次是在目录中查找文件。 Return 值仍然没有变化,并显示所有变量中的最新值。 是的,我知道,这可能是因为我使用 setx 但只有 set 才行不通。
for /L %%G in (1,1,%i%) do (
if NOT {arch}=={32} (
setx DriverPath !DefaultPath!driver\!DriverPath64[%%G]! >nul 2>&1
) else (
setx DriverPath !DefaultPath!driver\!DriverPath32[%%G]! >nul 2>&1
)
:: looking for inf file
for /r "%DriverPath%\" %%f in (*.inf) do (
set PrinterDriverInf[%%G]=%%f
)
)
将 ::
评论更改为常规 rem
评论。
::
实际上是一个损坏的标签和标签(损坏或其他)导致代码块问题(带括号的语句序列)
另一件事(我猜)是您试图比较字符串 {arch}
和 {32}
.
这是命令解析器看到的内容:
if the string {arch} equals {32}, do something
我猜你想要这个:
if the content of arch variable equals 32, do something
如果是这样,这就是适合您的命令。
if "%arch%"=="32" echo your commands here
始终使用引号 "
而不是 {
和 }
,因为它们更安全。
- 为什么要使用
setx
?正常的set
命令不够用吗?请注意,setx
不会更改当前cmd
实例的变量。 if not
语句的计算结果始终为 True,因为您在==
的两边都声明了文字字符串。你是说%arch%
而不是arch
吗?- 您需要延迟
!DriverPath!
的扩展。但是for /R
不能使用延迟展开变量,所以必须把for /R
循环移到子程序中才能使用立即%
-展开,或者你临时换个目录并让for /R
默认为那个(已更改的)当前目录。 - 切勿在带括号的块中使用
::
注释,而应使用rem
。
固定代码如下:
setlocal EnableDelayedExpansion
for /L %%G in (1,1,%i%) do (
if not "%arch%"=="32" (
setx DriverPath !DefaultPath!driver\!DriverPath64[%%G]! >nul 2>&1
set "DriverPath=!DefaultPath!driver\!DriverPath64[%%G]!"
) else (
setx DriverPath !DefaultPath!driver\!DriverPath32[%%G]! >nul 2>&1
set "DriverPath=!DefaultPath!driver\!DriverPath32[%%G]!"
)
rem looking for inf file
call :SUB PrinterDriverInf[%%G] "%DriverPath%"
)
endlocal
goto :EOF
:SUB
for /R "%~2" %%f in (*.inf) do (
set "%~1=%%f"
)
goto :EOF
您甚至可以像这样简化代码:
setlocal EnableDelayedExpansion
if not "%arch%"=="32" set "arch=64"
for /L %%G in (1,1,%i%) do (
setx DriverPath !DefaultPath!driver\!DriverPath%arch%[%%G]! >nul 2>&1
set "DriverPath=!DefaultPath!driver\!DriverPath%arch%[%%G]!"
rem looking for inf file
pushd "!DriverPath!" && (
for /R %%f in (*.inf) do (
set "PrinterDriverInf[%%G]=%%f"
)
popd
)
)
endlocal