我想连续ping服务器并在响应时看到一个消息框,即服务器当前已关闭。我想通过批处理文件来完成。
我可以在此处显示一个消息框Show a popup/message box from a Windows batch file
可以通过
连续pingping <servername> -t
但我该如何检查是否有回应?
答案 0 :(得分:28)
问题是看ping是否响应了这个脚本的作用。
但是,如果您收到Host Unreachable消息,则此操作无效,因为这会返回ERRORLEVEL 0并传递此脚本中使用的Received = 1的检查,并返回脚本中的Link is UP。当ping被传递到目标notwork但无法找到远程主机时,会发生Host Unreachable。
如果我记得检查ping是否成功的正确方法是使用Find查找字符串'TTL'。
@echo off
cls
set ip=%1
ping -n 1 %ip% | find "TTL"
if not errorlevel 1 set error=win
if errorlevel 1 set error=fail
cls
echo Result: %error%
这不适用于IPv6网络,因为在接收来自IPv6地址的回复时ping不会列出TTL。
答案 1 :(得分:19)
以下checklink.cmd
计划是一个很好的起点。它依赖于你可以进行单次ping的事实,如果成功,输出将包含该行:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
通过提取代币5和7并分别检查它们"Received"
和"1,"
,您可以检测到成功。
@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
:loop
set state=down
for /f "tokens=5,6,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%b"=="xunreachable." goto :endloop
if "x%%a"=="xReceived" if "x%%c"=="x1," set state=up
)
:endloop
echo.Link is !state!
ping -n 6 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal
使用您要测试的名称(或IP地址)调用它:
checklink 127.0.0.1
checklink localhost
checklink nosuchaddress
请注意,如果您的语言区域不是英语,则必须将Received
替换为您语言环境中的相应关键字,例如recibidos
替换为西班牙语。执行测试ping以发现您的语言环境中使用的关键字。
要仅在状态更改时通知您,您可以使用:
@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=down
for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%a"=="xReceived" if "x%%b"=="x1," set state=up
)
if not !state!==!oldstate! (
echo.Link is !state!
set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal
但是,正如Gabe在评论中指出的那样,您可以使用ERRORLEVEL
,因此上面第二个脚本的等效内容变为:
@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=up
ping -n 1 !ipaddr! >nul: 2>nul:
if not !errorlevel!==0 set state=down
if not !state!==!oldstate! (
echo.Link is !state!
set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal
答案 2 :(得分:5)
我知道这是一个旧线程,但我想测试一台机器是否在我的系统上,除非我误解了,如果我的路由器报告地址无法访问,则上述任何一个都无效。我使用批处理文件而不是脚本,因为我想&#34; KISS&#34;在几乎任何WIN机器上。所以我使用的方法是做多个ping并测试&#34; Lost = 0&#34;如下
ping -n 2 %pingAddr% | find /I "Lost = 0"
if %errorlevel% == 0 goto OK
我还没有经过严格的测试,但到目前为止,它确实为我做了工作
答案 3 :(得分:1)
我根据paxdiablo的帖子
制作了变体解决方案将以下代码放在Waitlink.cmd
中@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
:loop
set state=up
ping -n 1 !ipaddr! >nul: 2>nul:
if not !errorlevel!==0 set state=down
echo.Link is !state!
if "!state!"=="up" (
goto :endloop
)
ping -n 6 127.0.0.1 >nul: 2>nul:
goto :loop
:endloop
endlocal
例如,从另一个批处理文件中使用它,如
call Waitlink someurl.com
net use o: \\someurl.com\myshare
只有在ping成功时才会返回对waitlink的调用。感谢paxdiablo和Gabe。希望这有助于其他人。
答案 4 :(得分:0)
您可以ping不使用“-t”并检查ping的退出代码。它会在没有答案时报告失败。
答案 5 :(得分:0)
简单版本:
for /F "delims==, tokens=4" %a IN ('ping -n 2 127.0.0.1 ^| findstr /R "^Packets: Sent =.$"') DO (
if %a EQU 2 (
echo Success
) ELSE (
echo FAIL
)
)
但有时候第一次ping失败而第二次失败(反之亦然)对吗?因此,当成功返回至少一个ICMP回复时,我们希望获得成功:
for /F "delims==, tokens=4" %a IN ('ping -n 2 192.168.1.1 ^| findstr /R "^Packets: Sent =.$"') DO (
if %a EQU 2 (
echo Success
) ELSE (
if %a EQU 1 (
echo Success
) ELSE (
echo FAIL
)
)
)
答案 6 :(得分:0)
这是我找到的东西:
:pingtheserver
ping %input% | find "Reply" > nul
if not errorlevel 1 (
echo server is online, up and running.
) else (
echo host has been taken down wait 3 seconds to refresh
ping 1.1.1.1 -n 1 -w 3000 >NUL
goto :pingtheserver
)
请注意,ping 1.1.1.1 -n -w 1000 >NUL
将等待1秒,但仅在连接到网络时才有效
答案 7 :(得分:0)
我希望这有助于某人。在检查各个路径之前,我使用这一点逻辑来验证网络共享是否响应。它应该处理DNS名称和IP地址
文本文件中的有效路径是 \ 192.168.1.2 \&#39;夹&#39;或\ NAS \&#39;文件夹&#39;
int
答案 8 :(得分:0)
我稍微修改了 PaxDiablo 的代码,以更好地适应我正在做的事情,并认为我会分享。我的目标是遍历 IP 地址列表以查看是否有任何剩余,并且此代码将在周末的最后一个班次结束时运行,以检查是否每个人都按照说明关闭所有 PC 之前他们回家了。
由于在 for 循环中使用 goto 会跳出所有 for 循环,而不仅仅是最底层的嵌套 for 循环,PaxDiablo 的代码在到达无法访问的 IP 地址时停止处理更多 IP 地址。我发现我可以添加第二个变量来跟踪它是不可达的,而不是退出循环,现在这段代码对我来说运行得很好。
我将文件保存为 CheckPCs.bat,虽然我猜这不是正确的编码实践,但我确实在代码下方列出了 IP 地址以及描述,在我的情况下是 PC 的物理位置。正如其他人提到的,您将不得不为其他本地化和 IPV6 进一步修改代码。
@setlocal enableextensions enabledelayedexpansion
@echo off
for /f "tokens=2,3 delims=/ skip=16" %%i in (CheckPCs.bat) do (
set ipaddr=%%i
set state=shut down
set skip=0
for /f "tokens=5,6,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%b"=="xunreachable." set skip=1
if !skip!==0 if "x%%a"=="xReceived" if "x%%c"=="x1," set state=still on
)
echo %%i %%j is !state!
)
pause
endlocal
rem /IP ADDRESS0/COMPUTER NAME0
rem /IP ADDRESS1/COMPUTER NAME1
如果您确实需要修改此代码,请注意:
for /f "tokens=2,3 delims=/ skip=16" %%i in (CheckPCs.bat) do (
for 循环一次处理一行 CheckPCs.bat。 Skip 告诉它忽略前 16 行并直接访问 IP 地址。我没有特殊原因使用 / 作为分隔符,但请注意,如果您要 ping 网址而不是 IP,则必须更改分隔符。像管道字符这样的东西|会工作。当然,由于该行用 rem 注释掉,因此 rem 成为第一个标记,这意味着我只想使用标记 2 和 3,它们将是 IP 地址和 PC 描述。后一个字段是可选的,您只需修改代码即可将其删除。
您可能应该修改用于状态和回显的术语 %%i %%j 是 !state!以便术语对您来说清晰简洁。如果您想在某处记录状态,您可以通过将 >> file.txt 附加到该行将其输入到文本文件中。在这种情况下,您可能还想添加日期/时间。
最后,受过适当编码培训的人可能知道,带有标记的批处理 for 循环的工作方式(简单来说)是文本的每个部分在每个分隔符处拆分,默认为空格,然后它被分配给一个 %% 变量,其名称以您指定的任何字符开头,然后在 ascii 字符列表中递增。这意味着如果我指定从 %%i 开始,下一个标记将是 %%j,然后是 %%k,依此类推。如果我使用 %%B,接下来是 %%C,然后是 %%D 等等。我读到的关于该主题的每个线程最多可以有 31 个标记。
答案 9 :(得分:-1)
我已经看到了ping的三个结果 - 我们想要的那个&#34;知识产权回复的地方,&#34; Host Unreachable&#34;并且&#34;超时&#34; (不确定准确的措辞)。
前两个返回ERRORLEVEL为0。
超时返回ERRORLEVEL为1。
是否可能返回其他结果和错误级别? (除了使用一个无效的开关,它返回允许的开关,错误级别为1.)
显然无法访问的主机可以使用以前发布的方法之一(尽管很难弄清楚当有人回复他们正在编写代码的情况时)但是超时会以类似的方式返回它可以被解析吗?
一般来说,如何知道可以解析ping的哪一部分结果? (即,为什么发送和/或接收和/或TTL可以解析,但主机无法访问?
哦,还有iSid,也许没有多少赞成票,因为阅读此内容的人没有足够的积分。所以他们回答(或不回答)他们的问题并离开。
我没有将上述内容作为答案发布。它应该是一个评论,但我没有看到这个选择。
答案 10 :(得分:-1)
#!/bin/bash
logPath="pinglog.txt"
while(true)
do
# refresh the timestamp before each ping attempt
theTime=$(date -Iseconds)
# refresh the ping variable
ping google.com -n 1
if [ $? -eq 0 ]
then
echo $theTime + '| connection is up' >> $logPath
else
echo $theTime + '| connection is down' >> $logPath
fi
Sleep 1
echo ' '
done