脚本忽略退出命令并中断函数 BATCH/CMD

Script ignoring exit command and breaking out of function BATCH/CMD

我写的这个脚本应该解析 IP 信息并将其从 WMIC 中提取出来。问题是当它在只输入 1 个 DNS 服务器的计算机上使用时,脚本会失败。 运行 :remove 函数似乎即使未设置变量 DNS2,然后 :remove 函数以某种我不熟悉的方式失败并忽略退出命令并跳出函数并进入部分我不想要它的脚本。这是有问题的代码,通过设置你的 dns 服务器和索引来测试它。脚本适用于定义的 2 个 DNS 服务器,而不是仅适用于 1 个。

@echo off
setlocal enabledelayedexpansion
SETLOCAL ENABLEEXTENSIONS
wmic NICCONFIG where "Index = 1" get /Value | more > storage.txt

for /f "tokens=1-9 delims=,}{=" %%f in (storage.txt) do (
    set cat=%%f
    IF /i !cat!==IPAddress (set IP=%%g)
    IF /i !cat!==IPSubnet (set SUB=%%g)
    IF /i !cat!==DefaultIPGateway (set GW=%%g)
    IF /i !cat!==DNSServerSearchOrder (
        set DNS=%%g
        set DNS2=%%h
    )
    IF /i !cat!==IPEnabled (set enabled=%%g)
    IF /i !cat!==Description (set desc=%%g)
)
if /i %enabled%==True (
if defined IP (
    set item=IP
    CALL :remove
        )
if defined SUB (
    set item=SUB
    CALL :remove
        )
if defined GW (
    set item=GW
    CALL :remove
        )
if defined DNS (
    set item=DNS
    CALL :remove
        )
if defined DNS2 (
    set item=DNS2
    CALL :remove
        )
)
goto :menu
echo SHOULDN'T BE HERE
pause
:::::::::Function to remove quotes::::::::::::::
:remove
for /f tokens^=1^ delims^=^" %%p in (!%item%!) do (
    set !item!=%%p
    rem echo !%item%!
    EXIT /b
    )
echo I BROKE OUT OF THE FUNCTION
pause
:menu
echo I worked!
echo %IP%
echo %SUB%
echo %GW%
echo %DNS1%
if defined DNS2 ( echo %DNS2% )
pause

这里是另一个使用LotPings返工的例子,注意即使没有DNS2,它仍然执行底部"if defined"

@echo off
SETLOCAL ENABLEEXTENSIONS enabledelayedexpansion
Set Prop=IPAddress IPSubnet DefaultIPGateway DNSServerSearchOrder IPEnabled Description
for /f "tokens=1-9 delims=,}{=" %%f in (
  'wmic NICCONFIG where "Index = 1" get /Value^|findstr /i /B "%Prop%"'
) do (IF /i %%f==IPAddress set "IP=%%~g"
      IF /i %%f==IPSubnet  set "SUB=%%~g"
      IF /i %%f==DefaultIPGateway  set "GW=%%~g"
      IF /i %%f==DNSServerSearchOrder (
        set "DNS=%%~g"
        set "DNS2=%%~h"
      )
      IF /i %%f==IPEnabled   set "enabled=%%~g"
      IF /i %%f==Description set "desc=%%~g"
)
set|Findstr /i /B "IP SUB GW DNS Ena Desc"
echo I worked!
echo %DNS%
echo %DNS2%
if defined DNS2 ( echo DNS2 found, shouldn't have found this)
pause

编辑 没有临时文件的批处理的完整返工:

@echo off
SETLOCAL ENABLEEXTENSIONS enabledelayedexpansion
Set Prop=IPAddress IPSubnet DefaultIPGateway DNSServerSearchOrder IPEnabled Description
for /f "tokens=1-9 delims=,}{=" %%f in (
  'wmic NICCONFIG where "Index = 1" get /Value^|findstr /i /B "%Prop%"'
) do (IF /i %%f==IPAddress set "IP=%%~g"
      IF /i %%f==IPSubnet  set "SUB=%%~g"
      IF /i %%f==DefaultIPGateway  set "GW=%%~g"
      IF /i %%f==DNSServerSearchOrder (
        set "DNS=%%~g"
        set "DNS2=%%~h"
      )
      IF /i %%f==IPEnabled   set "enabled=%%~g"
      IF /i %%f==Description set "desc=%%~g"
)
If "%DNS2:~3%" EQU "" Set "DNS2="
set|Findstr /i /B "IP SUB GW DNS Ena Desc"
echo I worked!
pause

当您遇到此类问题时,您应该在任何相关点添加调试信息。
在你的情况下添加一些 echo's

IF /i %%f==DNSServerSearchOrder (
        set "DNS=%%~g"
        set "DNS2=%%~h"
        echo #1 "%%~g"
        echo #2 "%%~h"
        if defined dns echo DNS defined
        if defined dns2 echo DNS2 defined
      )

我得到了这样的东西

> #1 "10.51.16.9"
> "2 "
> DNS defined
> DNS2 defined

如您所见,已定义 DNS2,echo #2 "%%~h" 显示已损坏的行!
原因就在这里,wmic 的行尾是 \r\r\n 而不是 \r\n.
因此在 DNS2 中现在是单个 \r 字符。

您可以使用清理功能从变量中删除所有 \r
这是因为所有 \r 在一个变量被百分号扩展后被删除(但当它被感叹号扩展或者如果它是一个 %%p 参数时则不会)

:sanitize
set "var=!%1!"
set "%1=%var%"
exit /b

并被

使用
IF /i %%f==DNSServerSearchOrder (
        set "DNS=%%~g"
        set "DNS2=%%~h"
        call :sanitize DNS
        call :sanitize DNS2
        echo #1 "!DNS!"
        echo #2 "!DNS2!"
        if defined dns echo DNS defined
        if defined dns2 echo DNS2 defined
      )

就这些了...

在解析 wmic 输出的循环周围再包装一个 for /F 循环:

rem // Code before the loop
for /F "delims=" %%e in ('
    wmic NICCONFIG where "Index = 1" get /Value ^| findstr /I /B "%Prop%"
') do (
    for /F "tokens=1-9 delims=,}{=" %%f in ("%%e") do (
        rem // Code inside of the loop...
    )
)
rem // Code after the loop...

wmic 命令生成了 Unicode 输出,for /F 循环未将其正确转换为 ANSI 文本,留下了一些孤立的 carriage-return 字符,这会干扰解析。附加的 for /F 循环以一种通用且可靠的方式删除了这些人工制品。