Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 批处理命令以捕获所有可能的ping问题_Batch File - Fatal编程技术网

Batch file 批处理命令以捕获所有可能的ping问题

Batch file 批处理命令以捕获所有可能的ping问题,batch-file,Batch File,我有一个关于验证批处理命令中ping是否正确返回的问题。目前,我必须通过3种不同的方式检查ping,才能知道服务器实际上已启动。我想将这些组合成一个ping命令。我尝试过使用不同的错误级别,或者不使用错误级别0等。没有一个能够捕获所有可能的场景。以下是我一直在使用的: Set /p domain=Enter IP address: set state=up @ping.exe -n 1 %domain% | find "unreachable" > null && set

我有一个关于验证批处理命令中ping是否正确返回的问题。目前,我必须通过3种不同的方式检查ping,才能知道服务器实际上已启动。我想将这些组合成一个ping命令。我尝试过使用不同的错误级别,或者不使用错误级别0等。没有一个能够捕获所有可能的场景。以下是我一直在使用的:

Set /p domain=Enter IP address:
set state=up

@ping.exe -n 1 %domain% | find "unreachable" > null && set state=down
if "%state%" == "down" goto :NoServer

@ping.exe -n 1 %domain% | find "TTL expired" > null && set state=down
if "%state%" == "down" goto :NoServer

@ping.exe -n 1 %domain%
if errorlevel 1 goto :NoServer
应该使用单个ping复制您的测试。我不确定是
ping
为所有错误条件返回errorlevel非零,还是可能返回一个目标字符串和errorlevel 0。您需要指定


应该使用单个ping复制您的测试。我不确定是
ping
为所有错误条件返回errorlevel非零,还是可能返回一个目标字符串和errorlevel 0。您需要指定

有两种方法可以检查ping命令的成功或失败:执行后测试errorlevel或测试命令的输出。对于这两种情况,检查ipv4或ipv6地址是不同的

问题是:
ping
的行为如何?它的输出是什么?
errorlevel
何时设置

错误级别
errorlevel

如果我们正在使用ipv6,那么规则是

  • errorlevel
    在所有发送的数据包都没有应答时设置(所有数据包都丢失)

  • 如果对任何发送的数据包都有回复,则不会设置
    errorlevel

ipv6具有一致的行为,检查errorlevel是了解机器是否在线的可靠方法

在ipv4中,规则是不同的

  • errorlevel
    在至少一个发送的数据包没有应答时设置

  • 当对所有发送的数据包都有回复(无数据包丢失)时,不设置
    errorlevel

但是,在ipv4中,ping同一子网上不可用的机器不会设置
错误级别
,您会得到一个“不可访问”的答案,当
发送了n个数据包,接收了n个打包数据包,丢失了0个数据包时
,所有数据包都会从发送数据包的同一台机器得到回复

当计算机位于同一子网时,ipv4中的这种行为会导致errorlevel检查失败

如何解决ipv4中的问题?输出检查

可以检查
ping
命令的输出,如果输出中存在字符串
TTL=
,则目标机器处于联机状态

ping-n110.0.0.1 |查找“TTL=“>nul
如果错误级别为1(
离线回声
)否则(
在线回声
)
但这种在ipv4中工作的方法将在ipv6中失败,因为此字段未包含在ping输出中(并重命名为,在ipv6中称为hop limit)


对于“通用”解决方案,可以使用这个(根据前面的答案改编)方法(似乎有很多代码,但几乎都是注释)。
ping
操作和输出处理被包装在一个子例程中,该子例程使用作为批处理文件的第一个参数传递的地址/主机名进行调用

@echo关闭
setlocal enableextensions disabledelayedexpansion
如果“%~1”==”转到:eof
调用:isOnline“%~1”
如果不是错误级别1(联机回显)否则(脱机回显)
端部
退出/b
:isOnline地址pingCount
setlocal enableextensions disabledelayedexpansion
::仅发送一个打包的ping,除非指示发送多个ping
设置/a“pingCount=0”、“pingCount+=%~2”>nul 2>nul
如果%pingCount%lss 1设置为“pingCount=1”
::需要一个临时文件来捕获ping输出以供以后处理
设置“tempFile=%temp%\%~nx0.%random%.tmp”
::ping指示的地址获取命令输出和错误级别
ping-w 1000-n%pingCount%“%~1”>%tempFile%&&set“pingError=“| | set”pingError=1”
::
::ping时,ipv4和ipv6的行为不同
::
::当
::ipv4-当至少一个数据包丢失时。发送多个数据包时
::检查回复的最简单方法是搜索字符串“TTL=”in
::命令的输出。
::ipv6-当所有数据包丢失时。
::
::当
::ipv4-接收所有数据包。但是ping同一台主机上的非活动主机
::子网不会导致数据包丢失。有必要检查“TTL=”
::ping命令输出中的字符串
::ipv6-至少有一个数据包到达主机
::
::我们可以尝试确定输入地址(或主机名)是否会导致
::ipv4或ipv6 ping,但更容易检查命令的结果
::
::                          +--------------+-------------+
::| TTL=存在|无TTL |
::  +-----------------------+--------------+-------------+
::| ipv4错误级别0 |正常|错误|
::|错误级别1 |正常|错误|
::  +-----------------------+--------------+-------------+ 
::| ipv6错误级别0 | |正常|
::|错误级别1 | |错误|
::  +-----------------------+----------------------------+
::
::所以,如果输出中存在TTL=,则主机处于联机状态。如果TTL=不存在,
::errorlevel为0,地址为ipv6,则主机处于联机状态。其余的
::主机处于脱机状态的案例数。
::
::要确定ip版本,请使用与ipv6地址匹配的常规表达式
::与findstr一起使用。因为只有在无错误级别的情况下才会进行测试,
::ip地址将出现在ping命令输出中。
设置“exitCode=1”
>nul 2>nul(
查找“TTL=”“%tempFile%”&&(设置“exitCode=0”)||(
如果未定义,则为pingError(
findstr/r/c:“[a-f0-9:[a-f
ping.exe -n 1 %domain% >tempfile
if not errorlevel 1 (
 findstr /i /c"unreachable" /c:"TTL expired" > null
 if errorlevel 1 goto :OK
)

:Noserver