【问题标题】:How do I get the IP address into a batch-file variable?如何将 IP 地址放入批处理文件变量中?
【发布时间】:2011-08-19 10:01:39
【问题描述】:

我有一个奇怪的问题,不确定是否可行。

我想写一个脚本,例如我将使用 ipconfig 作为我的命令。

现在,当您正常运行此命令时,会有大量输出。

例如,我想要一个只显示 IP 地址的脚本。

echo Network Connection Test
ipconfig <---This would run in the background
echo Your IP Address is: (INSERT IP ADDRESS HERE)

输出将是

Network Connection Test

Your IP Address is: 192.168.1.1

这可能吗?

【问题讨论】:

  • 你可以有多个 IP 地址,大多数机器甚至有多个。那你想要哪一个?

标签: batch-file ip


【解决方案1】:

以下代码适用于自 Windows XP 以来任何平台的任何语言环境,它会从(或多或少)随机的网卡中查找网络 IP。它永远不会超过几毫秒。

for /f "delims=[] tokens=2" %%a in ('ping -4 -n 1 %ComputerName% ^| findstr [') do set NetworkIP=%%a
echo Network IP: %NetworkIP%

以下是寻找您的公共 IP,并在 Windows 7 和更新的机器上运行。

for /f %%a in ('powershell Invoke-RestMethod api.ipify.org') do set PublicIP=%%a
echo Public IP: %PublicIP%  

你可以在my blog找到这些命令的详细解释。

【讨论】:

  • 它给了我一个错误:“%%a 在这个时候是意外的。”
  • 这只是批处理,你可能在命令行中运行它,对吧?
  • 我认为这取决于FOR 命令的工作方式,以及它如何威胁%%a 变量。我实际上无法解释为什么它不同,但是用%a 替换%%a 的两个出现将使它在命令行中工作。当然,这会阻止它批量工作。
  • 谢谢,我发现这非常有用,原因有以下三个:1)它选择了正确的本地网络接口 2)它适用于任何 Windows 版本,无论语言如何 3)它不会留空IP 地址开头的空格。
  • 如果您没有第二个本地接口,这很好。对我来说,它从以太网适配器 VirtualBox Host-Only Network #2 中选择 IP。当你禁用它时,没关系。
【解决方案2】:

这将在ipconfig 的输出中打印 IP 地址:

@echo off
set ip_address_string="IPv4 Address"
rem Uncomment the following line when using older versions of Windows without IPv6 support (by removing "rem")
rem set ip_address_string="IP Address"
echo Network Connection Test
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:%ip_address_string%`) do echo Your IP Address is: %%f

要仅打印第一个 IP 地址,只需在回显之后添加goto :eof(或另一个要跳转到的标签,而不是:eof),或者以更易读的形式:

set ip_address_string="IPv4 Address"
rem Uncomment the following line when using older versions of Windows without IPv6 support (by removing "rem")
rem set ip_address_string="IP Address"
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:%ip_address_string%`) do (
    echo Your IP Address is: %%f
    goto :eof
)

一种更可配置的方法是稍微解析ipconfig /all 的输出,这样您甚至可以指定所需IP 地址的适配器:

@echo off
setlocal enabledelayedexpansion
::just a sample adapter here:
set "adapter=Ethernet adapter VirtualBox Host-Only Network"
set adapterfound=false
echo Network Connection Test
for /f "usebackq tokens=1-2 delims=:" %%f in (`ipconfig /all`) do (
    set "item=%%f"
    if /i "!item!"=="!adapter!" (
        set adapterfound=true
    ) else if not "!item!"=="!item:IP Address=!" if "!adapterfound!"=="true" (
        echo Your IP Address is: %%g
        set adapterfound=false
    )
)

【讨论】:

  • 我认为您需要将“IP 地址”更改为“IP 地址”,或者将/I 传递给findstr 以进行不区分大小写的匹配。
  • @indiv: 正确(我有不同的语言环境,我手动更改了字符串);答案已更新……
  • 在我的 Win7 计算机上,要匹配的字符串是“IPv4 地址”。
  • @Vik:感谢您提及这一点,我希望它可以帮助其他用户。只需在脚本中更新适当的字符串:]
  • 您可以使用正则表达式和 findstr 来测试任一字符串:findstr /R /C:"^ *IP[v4]* Address"
【解决方案3】:

在 Windows 7 中:

for /f "tokens=1-2 delims=:" %%a in ('ipconfig^|find "IPv4"') do set ip=%%b
set ip=%ip:~1%
echo %ip%
pause

【讨论】:

  • 感谢set ip=%ip:~1% 摆脱前面的额外空间。 :)
【解决方案4】:
@echo off

FOR /F "tokens=4 delims= " %%i in ('route print ^| find " 0.0.0.0"') do set localIp=%%i

echo Your IP Address is: %localIp%

【讨论】:

  • 可以限制接口吗?
  • 如果您有多个适配器,例如 VirtualBox、VMWare,最好的解决方案
  • 在安装了 docker 的机器上工作
  • 实际上在一台机器上它在另一台机器上工作它返回默认值,因此它实际上并不能可靠地工作。知道如何解决这个问题吗?
  • 当有多个(虚拟)接口绑定到/使用 0.0.0.0 时,此解决方案可能会产生意外的结果/值。
【解决方案5】:

单独提取地址有点困难,但您可以轻松获取整个 IP 地址行。

在任何英语 Windows 操作系统上显示所有 IP 地址:

ipconfig | findstr /R /C:"IP.* Address"

在 Windows 7+ 上仅显示 IPv4 或 IPv6 地址:

ipconfig | findstr /R /C:"IPv4 Address"

ipconfig | findstr /R /C:"IPv6 Address"

以下是带有 3 个网络适配器的 XP 机器的一些示例输出。

        IP Address. . . . . . . . . . . . : 192.168.1.10
        IP Address. . . . . . . . . . . . : 10.6.102.205
        IP Address. . . . . . . . . . . . : 192.168.56.1

【讨论】:

  • 在 >= Windows 7 上,您应该找到字符串“IPv4 地址”(而不是“IP 地址”),因此正确的命令如下所示:ipconfig | findstr /R /C:"IPv4 Address.*:"。我认为您应该将其添加到您的帖子中。 :) 我赞成它,因为这是另一个好主意。 :)
  • @Sk8erPeter:谢谢!我已经用新的正则表达式更新了答案。
  • 不客气!并感谢您更新它。您刚刚写的ipconfig | findstr /R /C:"IP.* Address" 是一个更好的主意:)
  • ipconfig | findstr /R /C:"IP.*" 如果语言与英语不同会更好
  • Win7 或 XP 上仅 IPv4 地址:ipconfig | findstr /R /C:"^ *IP[v4]* Address"
【解决方案6】:

即使您有虚拟网络适配器或 VPN 连接也可以使用:

FOR /F "tokens=4 delims= " %%i in ('route print ^| find " 0.0.0.0"') do set localIp=%%i
echo Your IP Address is: %localIp%

【讨论】:

  • route print 似乎是 Windows 系统更可靠、更优雅的选择。这应该是公认的答案。
  • 它非常接近最理想的解决方案。只是当有多个(虚拟)接口使用 0.0.0.0 时,它只存储它找到的最后一个值。根据使用结果数据的方式(以及特定目的),它可能是另一个值,而不是人们预期的值。
【解决方案7】:

tldr;

我无法在我的用例中使用上述任何答案,因此我使用以下命令获取我的以太网网络适配器的 IP 地址并按照上述问题中的说明回显它。

在命令行中:

for /f "tokens=3 delims=: " %i  in ('netsh interface ip show config name^="Ethernet" ^| findstr "IP Address"') do echo Your IP Address is: %i

或者在批处理文件中:

for /f "tokens=3 delims=: " %%i  in ('netsh interface ip show config name^="Wi-Fi" ^| findstr "IP Address" ^| findstr [0-9]') do set IP=%%i

对于那些想知道这一切意味着什么的人,请继续阅读

例如,大多数使用ipconfig 的命令只是打印出您的所有 IP 地址,而我需要一个特定的 IP 地址,在我的情况下是用于我的以太网网络适配器。

您可以使用netsh interface ipv4 show interfaces 命令查看您的网络适配器列表。大多数人需要 Wi-Fi 或以太网。

您会在命令提示符的输出中看到类似的表格:

Idx     Met         MTU          State                Name
---  ----------  ----------  ------------  ---------------------------
  1          75  4294967295  connected     Loopback Pseudo-Interface 1
 15          25        1500  connected     Ethernet
 17        5000        1500  connected     vEthernet (Default Switch)
 32          15        1500  connected     vEthernet (DockerNAT)

在名称列中,您应该找到所需的网络适配器(即以太网、Wi-Fi 等)。

如前所述,我对 Ethernet 感兴趣。

要获取该适配器的 IP,我们可以使用 netsh 命令:

netsh interface ip show config name="Ethernet"

这给了我们这个输出:

Configuration for interface "Ethernet"
    DHCP enabled:                         Yes
    IP Address:                           169.252.27.59
    Subnet Prefix:                        169.252.0.0/16 (mask 255.255.0.0)
    InterfaceMetric:                      25
    DNS servers configured through DHCP:  None
    Register with which suffix:           Primary only
    WINS servers configured through DHCP: None

(出于安全原因,我伪造了上面的实际 IP 号码?)

我可以在 ms-dos 命令提示符中使用findstr 命令进一步指定我想要的行。 这里我想要包含字符串IP Address的行。

netsh interface ip show config name="Ethernet" | findstr "IP Address"

这给出了以下输出:

 IP Address:                           169.252.27.59

然后我可以使用for 命令解析文件(或在本例中为多行字符串)并根据分隔符和我感兴趣的项目编号拆分字符串的内容。

请注意,我正在寻找第三项 (tokens=3),并且我使用空格字符和 : 作为分隔符 (delims=: )。

for /f "tokens=3 delims=: " %i  in ('netsh interface ip show config name^="Ethernet" ^| findstr "IP Address"') do echo Your IP Address is: %i

循环中的每个值或标记都作为变量 %i 打印出来,但我只对第三个“标记”或项目感兴趣(因此 tokens=3)。请注意,我必须使用 ^ 转义 |=

for 命令的末尾,您可以指定一个命令来运行返回的内容。在这种情况下,我使用 echo 将其与其他文本一起打印出来,但您也可以使用 do set IP=%i 或任何您喜欢的方式将值分配给环境变量。

很整洁吧?

如果您有任何改进的想法,请发表评论。我很想听听 :) 或者你可以直接编辑。

【讨论】:

  • 批处理文件对变量使用稍微不同的语法:for /f "tokens=3 delims=: " %%i in ('netsh interface ip show config name^="Wi-Fi" ^| findstr "IP Address" ^| findstr [0-9]') do set IP=%%i 注意变量使用双百分号。
【解决方案8】:

这是对@mousio 答案的修改。我的网络连接不是持久的,因此如果 ipconfig 中缺少字符串“IPv4 地址”,则会显示下一个适配器的 IP 地址。 ipconfig 的结果在适配器之间有 2 个空格。在找到适配器并且在“IPv4 地址”文本之前出现 2 个空行后,它假定它丢失了。仅在 64 位 Windows 7 上测试。

处理@dbenham 回答中的空白行: DOS batch FOR loop with FIND.exe is stripping out blank lines?

@echo off

rem --- complete adapter name to find without the ending ":" ---
set adapter=Wireless LAN adapter Wireless Network Connection

rem --- token under an adapter to extract IP address from ---
set IPAddrToken=IPv4 Address

setlocal enableextensions enabledelayedexpansion
set adapterfound=false
set emptylines=0
set ipaddress=

for /f "usebackq tokens=1-3 delims=:" %%e in (`ipconfig ^| findstr /n "^"`) do (

    set "item=%%f"

    if /i "!item!"=="!adapter!" (
        set adapterfound=true
        set emptylines=0
    ) else if not "!item!"=="" if not "!item!"=="!item:%IPAddrToken%=!" if "!adapterfound!"=="true" (
        @rem "!item:%IPAddrToken%=!" --> item with "IPv4 Address" removed
        set ipaddress=%%g
        goto :result
    )
    if "%%f-%%g-!adapterfound!-!emptylines!"=="--true-1" (
        @rem 2nd blank line after adapter found
        goto :result
    )
    if "%%f-%%g-!adapterfound!-!emptylines!"=="--true-0" (
        @rem 1st blank line after adapter found
        set emptylines=1
    )
)

endlocal

:result
    echo %adapter%
    echo.
    if not "%ipaddress%"=="" (
        echo    %IPAddrToken% =%ipaddress%
    ) else (
        if "%adapterfound%"=="true" (
            echo    %IPAddrToken% Not Found
        ) else (
            echo    Adapter Not Found
        )
    )
    echo.

pause

【讨论】:

    【解决方案9】:

    使用IPCONFIG 很好,除非您想灵活地获取除本地主机之外的远程主机的 IP。要使用 PING 从 www.google.com 之类的网站获取它,请尝试:

    for /f "tokens=2 delims=[]" %%f in ('ping -4 -n 1 www.google.com ^|find /i "pinging"') do echo IP=%%f
    

    该示例的结果是:

    IP=173.194.73.106
    

    要获取本地主机的第一个 IP,请将“www.google.com”替换为“%computername%”,不带引号。请注意,前面的“-4”将始终获得 IPv4 地址,而不是可能的 IPv6 地址。根据需要省略。另请注意,此技术不能获得多个 IP 地址。如果这是您的目标,则需要使用 NSLOOKUP 和一些额外的代码。

    请注意,如果您使用 NSLOOKUP 而不是 PING,并且主机有多个 IP 地址,那么您的变量末尾将有一个逗号,因为每个地址都将用逗号分隔。

    【讨论】:

    • ping localhost 会给你127.0.0.1。请改用ping %computername%
    • 对我来说最好的答案。恕我直言,使用 delims=[] 过滤“pinging”似乎是最强大的。
    【解决方案10】:

    我知道这是一篇较旧的帖子,但我在尝试解决 vbscript 中的相同问题时遇到了这个问题。我还没有使用多个网络适配器对此进行测试,但希望它仍然有用。

    for /f "delims=: tokens=2" %%a in ('ipconfig ^| findstr /R /C:"IPv4 Address"') do (set tempip=%%a)  
    set tempip=%tempip: =%  
    echo %tempip%
    

    这假设 Win7。对于 XP,请将 IPv4 Address 替换为 IP Address

    【讨论】:

      【解决方案11】:

      Windows 中的一行命令获取 IP 地址。

      for /F "tokens=14" %%i in ('"ipconfig | findstr IPv4"') do SET LOCAL_IP=%%i
      

      此命令后echo %LOCAL_IP% 将打印IP 地址。或者您可以在批处理脚本中使用%LOCAL_IP% 作为参考变量

      【讨论】:

        【解决方案12】:

        假设你提到我是一个 Windows 操作系统 p 配置

        如果您愿意安装一些 Unixy 实用程序,例如 grep 和 cut 的 windows-port,您可以这样做。但是,在像您使用 ipconfig 的示例这样的情况下,在具有多个 NIC 或例如 VMWare 的机器中将是一团糟。

        Powershell 可能是您想要的工具,例如 here

        【讨论】:

        • 非常感谢,我一直在寻找一种非常简单的方法来执行此操作,但感谢您提供的信息
        【解决方案13】:

        试试这样的

        echo "yours ip addresses are:"
        ifconfig | grep "inet addr" | cut -d':' -f2 | cut -d' ' -f1
        

        类似linux的系统

        【讨论】:

          【解决方案14】:

          以下都是在 Windows XP 机器上的 cygwin 中完成的。

          这将获取您的 IP 地址。请注意,hostname 命令周围有反引号,而不是单引号。

          ping -n 1 `hostname` | grep "Reply from " | cut -f 3 -d " " | cut -f 1 -d ":"
          

          这将获得您的子网。

          ping -n 1 `hostname` | grep "Reply from " | cut -f 3 -d " " | cut -f "1 2 3" -d "."
          

          以下将列出您本地网络上的所有主机(将其放入名为“netmap”的脚本中)。我将上面的子网线放入一个名为“getsubnet”的可执行文件中,然后我从以下脚本中调用它。

          MINADDR=0
          MAXADDR=255
          SUBNET=`getsubnet`
          
          hostcnt=0
          
          echo Pinging all addresses in ${SUBNET}.${MINADDR}-${MAXADDR}
          
          for i in `seq $MINADDR $MAXADDR`; do
          addr=${SUBNET}.$i
          ping -n 1 -w 0 $addr > /dev/null
          
          if [ $? -ne 1 ]    
          then    
          echo $addr UP    
          hostcnt=$((hostcnt+1))    
          fi
          
          done
          
          echo Found $hostcnt hosts on subnet ${SUBNET}.${MINADDR}-${MAXADDR}
          

          【讨论】:

            【解决方案15】:

            下面的脚本会将ip地址存储到变量ip_address中

            @echo off
            
            call :get_ip_address
            echo %ip_address%
            
            goto :eof
            
            REM
            REM get the ip address
            REM
            :get_ip_address
            FOR /f "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') do (FOR /F "tokens=3 delims= " %%g IN ("%%d") DO set ip_address=%%g)
            
            goto :eof
            

            来自this blog post的想法。

            【讨论】:

              【解决方案16】:

              linux环境下:

              ip="$(ifconfig eth0 | grep "inet addr:" | awk '{print $2}' | cut -d ':' -f 2)"
              

              ip="$(ifconfig eth0 | grep "inet addr:" | awk '{print $2}' | cut -d ':' -f 2)" | echo $ip
              

              FreeBSD 中的示例:

              ifconfig re0 | grep -v "inet6" | grep -i "inet" | awk '{print $2}'
              

              如果您配置了多个 IP 地址,则 stdout 中将有多个 IP 地址。

              【讨论】:

                【解决方案17】:

                对于我的系统,我有许多 IPv4 地址,其中只有一个是正确的。一个简单的整理和检查方法如下:

                for /f "tokens=1,2* delims=:" %%A in ('ipconfig ^| find "IPv4 Address"') do (
                    set "tempip=%%~B"
                    set "tempip=!tempip: =!"
                    ping !tempip! -n 1 -w 50
                    if !errorlevel!==0 (
                        set localip=!tempip!
                        goto foundlocal
                    )
                )
                :foundlocal
                

                【讨论】:

                  【解决方案18】:

                  如果你想要 PowerShell 或 WSL2 bash:

                  我只是在构建 this answer on superuser
                  但我发现以下选项可以更清晰地获取我的 LAN IP 地址:

                  1. 找到您想了解的接口名称
                    对我来说,是Configuration for interface "Wi-Fi",
                    所以对我来说这个名字是Wi-Fi
                    (将下面命令中的"Wi-Fi"替换为您的接口名称)

                  2. PowerShell:

                    $myip = netsh interface ip show address "Wi-Fi" `
                      | where { $_ -match "IP Address"} `
                      | %{ $_ -replace "^.*IP Address:\W*", ""}
                    
                    echo $myip
                    

                    输出:192.168.1.10

                  3. 或者,我的边缘情况,在 WSL2 中执行命令:

                    netsh.exe interface ip show address "Wi-Fi" \
                       | grep 'IP Address' \
                       | sed -r 's/^.*IP Address:\W*//'
                    
                    # e.g.
                    export REACT_NATIVE_PACKAGER_HOSTNAME=$(netsh.exe interface ip show address "Wi-Fi" \
                       | grep 'IP Address' \
                       | sed -r 's/^.*IP Address:\W*//')
                    

                  【讨论】:

                    【解决方案19】:

                    如果你只想要IP地址试试这个:

                    #Variable to store ip address
                    ipaddr=$(hostname -I)
                    
                    echo "$ipaddr"
                    

                    【讨论】:

                    • 问题是关于windows批处理文件,你为linux bash给出了答案
                    猜你喜欢
                    • 2013-01-25
                    • 2018-08-06
                    • 2012-12-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-08-21
                    • 1970-01-01
                    • 2010-10-23
                    相关资源
                    最近更新 更多