批处理文件 IF 条件

Posted

技术标签:

【中文标题】批处理文件 IF 条件【英文标题】:batch file IF condition 【发布时间】:2021-01-31 11:32:04 【问题描述】:

我正在尝试使用以下代码获取与 netsh 的当前活动连接(我宁愿不使用 wmic)。

@echo off

FOR /F "tokens=3,*" %%A IN ('netsh interface show interface^|findstr /i "\<connected\>"') DO (

if %%B == .........
)

我只想说明默认连接名称:

Wi-Fi、以太网、无线网络连接、局域网连接并以此为基础做一些事情。

例如:如果 %%B = WiFi 或以太网或....(

::在这里做点什么 )

我只希望“某事”执行一次,因为在任何给定时间只有其中一个连接处于活动状态。

【问题讨论】:

我必须说,我有点困惑,因为如果你“只有一个活动连接”,它的接口名称有什么区别?你真正想确定什么?或者换一种说法,根据返回的接口名称,您的if 命令到底要做什么? 出于某种奇怪的原因,netsh 将其他“虚拟”适配器显示为活动/已连接。所以我基本上需要过滤以获取物理连接(它们具有 if 语句中使用的默认名称) 【参考方案1】:

我认为这样的事情应该可以解决问题:

@echo off

SETLOCAL ENABLEDELAYEDEXPANSION

for /f "tokens=3,*" %%a in ('netsh interface show interface ^| findstr /i "\<connected\>"') do (
    set ifname=%%b
    if "!ifname:~0,8!"=="Ethernet" goto execute
    if "!ifname:~0,21!"=="Local Area Connection" goto execute
    if "!ifname:~0,5!"=="Wi-Fi" goto execute
    if "!ifname:~0,27!"=="Wireless Network Connection" goto execute
)
echo No connected interface found, exiting...
goto :EOF

:execute
echo Found connected interface (%ifname%), executing...
:: do whatever you need

基本上这个想法是寻找以这四个不同字符串开头的接口,然后跳转到执行任何你想要的标签。

[如果我没有指出现在在 PowerShell 中这样做可能会更好,那我就失职了,但是……]

【讨论】:

是的,这里没有 powershell .....代码无法运行。好吧,它只是退出......没有错误或任何东西 您使用的什么操作系统没有 PowerShell?甚至 XP 也有 PowerShell。我写的代码在这里工作(Windows 10)......我没有任何不受支持的操作系统(WinXP、Win7 等)可以方便地进行测试。我建议您在其中添加一些echo 声明,看看它在哪里偏离了轨道。 在这里也使用 Windows 10...我会玩弄它,看看我是否可以让它执行 所做的更改:插入所需的 setlocal enabledelayedexpansion 以允许在循环中解释 ifname 的更改值。将 % 更改为 ! 以允许访问更改后的而不是 ifname 的原始值。 替代方案:嵌套第三个循环 for %%c in ("Ethernet" "Wi-Fi" ...) do echo %%b|find %%c &gt;nul&amp;if not errorlevel 1 goto execute 将任何其他目标字符串添加到列表中,但“引用每个字符串”。这将尝试匹配 %%b,如果找到字符串 is,则将 errorlevel 设置为 0,因此为 NOT(1 或更大)并触发 GOTO【参考方案2】:

这是一个未经测试的示例,它应该只是告诉您与您唯一分配的 IP 地址关联的设备的接口名称。

@Echo Off
SetLocal EnableExtensions
For /F "Delims==" %%G In ('"(Set Interface) 2> NUL"') Do Set "%%G="
For /F Tokens^=4 %%G In ('%__APPDIR__%ROUTE.EXE -4 PRINT 0.0.0.0 ^
 ^| %__APPDIR__%findstr.exe /RC:"0.0.0.0 *0.0.0.0"') Do (Set "InterfaceIP=%%G"
    For /F Tokens^=5* %%H In ('%__APPDIR__%netsh.exe interface IP show route^
 ^|%__APPDIR__%find.exe "%%G"') Do Set "InterfaceName=%%I")
If Not Defined InterfaceIP GoTo :EOF
Set Interface & Pause

[编辑/]

这是我的 cmets 示例的略微修改版本,它使用 ping.exe 而不是 ROUTE.EXE 返回用于确定接口名称的 IP 地址。

@Echo Off
SetLocal EnableExtensions
For /F "Delims==" %%G In ('"(Set Interface) 2> NUL"') Do Set "%%G="
For /F "Tokens=2 Delims=[]" %%G In ('^"%__APPDIR__%ping.exe "%COMPUTERNAME%" ^
 -n 1 -4 2^> NUL ^| %__APPDIR__%find.exe /I "%COMPUTERNAME%"^"') Do (
    Set "InterfaceIP=%%G" & For /F Tokens^=5* %%H In ('%__APPDIR__%netsh.exe ^
     interface IP show route ^| %__APPDIR__%find.exe "%%G"'
    ) Do Set "InterfaceName=%%I")
If Not Defined InterfaceIP GoTo :EOF
Set Interface & Pause

两个示例中的最后一行仅显示两个变量,以便您查看它们。你显然会用你的其余代码替换那些。

【讨论】:

漂亮的解决方案,但是在有静态 ip 集的情况下它不起作用,只有 DHCP。我需要考虑两者。我喜欢这种方法。如果它只适用于静态 IP 情况。 您的问题@james 不仅提到或暗示了这一点,因此不是回答要求;你能解释一下排除WMI的具体原因是什么吗?还是您对 WMI 满意,只是对 WMIC 不满意?如果是,为什么? 每当我在 Windows 10 上运行 wmic 时,都会收到拒绝访问错误。我希望该解决方案至少可以跨 Windows 7 和 Windows 10 移植,而无需对操作系统进行任何更改。 好吧@james,wmic 默认情况下不受windows-10 或其以下的限制,因此这必须是特定于您的限制。您希望我们如何确定一种适用于任何可能存在限制的机器的方法。什么是阻止管理策略限制 netsh.exe?这项任务的实际目的是什么?不是你的脚本应该做什么? 没有态度,我在向你解释,你的限制是少数,(它不是用户环境中的默认值),那么什么是阻止其他少数人限制阻止您的脚本工作?另外请注意,检查与if== 的连接不太可能在使用相同区域设置/语言的PC 以外的任何设备上移植,因为我非常怀疑所有语言都使用相同的英文字符串。

以上是关于批处理文件 IF 条件的主要内容,如果未能解决你的问题,请参考以下文章

cmd中if条件“and”/“or”的批处理文件问题

在批处理文件中,如果满足一个条件而不是周围的 for 循环,如何突破嵌套的 if 语句?

BATCH 文件中多个文件名的条件 IF EXIST 语句

第三章三元运算文件处理函数

如果...或如果...在 Windows 批处理文件中

DOS/BAT批处理if exist else 语句的几种用法