具有.csv输出的常量ping批处理文件工作不正常



我遇到了互联网问题,想创建一个后台脚本,对我的路由器和互联网设置一个恒定的ping,这样我就可以跟踪连接断开的频率。

我所做的是创建一个批处理文件,它对我的路由器进行持续的ping;获取响应时间,然后在控制台中创建一个输出,以及一个具有多个字段的CSV文件,如状态(即成功ping或失败)ping时间、ping日期e.t.c.

我遇到的问题是,如果连接断开,我的代码就不会输出,我想这是因为我放入的%errorlevel%变量由于ping输出而不起作用,它被切碎并存储在一个变量中,但我可能错了,这就是我在这里解释我的问题的原因。

我尝试了多种不同的方法,但找不到一种可以将响应时间存储在变量中并让它提供正确的错误级别来输出正确的数据的方法,所有这些都来自同一个ping

现在看来我只能做其中一个:

@ECHO OFF
@SETLOCAL
set internetAddress=8.8.8.8
set routerAddress=192.168.1.0
set speed=2
set filename=C:PingTestPingResultsPingTest_%time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%.csv
echo Type, Status, Time, Date, ms >> %filename%
echo off
:internetstart
set currentTime=%time:~0,2%:%time:~3,2%:%time:~6,2%
set currentDate=%date:~-10,2%/%date:~-7,2%/%date:~-4,4%
for /F "tokens=7 delims==< " %%G in ('
ping -4 -n 1 %internetAddress%^|findstr /i "TTL="') do (
set ims=%%G 
if %errorlevel% == 0 goto :internetSuccess
if not %errorlevel% == 0 goto :internetFail
)
:internetSuccess
echo internet = success @ %ims% - %currentTime% %currentDate%
echo internet, success, %currentTime%, %currentDate%, %ims% >> %filename%
PING localhost -n %speed% >NUL
goto :routerstart
:internetFail
set ims=n/a
echo internet = failure @ %ims% - %currentTime% %currentDate%
echo internet, failure, %currentTime%, %currentDate%, %ims% >> %filename%
PING localhost -n %speed% >NUL
goto :routerstart
:routerstart
for /F "tokens=7 delims==< " %%A in ('
ping -4 -n 1 %routerAddress%^|findstr /i "TTL="') do (
set rms=%%A 
if %errorlevel% == 0 goto :routerSuccess
if not %errorlevel% == 0 goto :routerFail
)
:routerSuccess
echo router   = success @ %rms% - %currentTime% %currentDate%
echo router, success, %currentTime%, %currentDate%, %rms% >> %filename%
PING localhost -n %speed% >NUL
goto :internetstart
:routerFail
set rms=n/a
echo router   = failure @ %rms% - %currentTime% %currentDate%
echo router, failure, %currentTime%, %currentDate%, %rms% >> %filename%
PING localhost -n %speed% >NUL
goto :internetstart

CSV文件中的预期结果为:

如果ping成功:

|TYPE     | STATUS  |TIME      | DATE       | MS |
|internet | success | 00:00:00 | 31/12/9999 | 7ms|
|router   | success | 00:00:00 | 31/12/9999 | 1ms|

如果ping失败:

|TYPE     | STATUS  |TIME      | DATE       | MS |
|internet | failure | 00:00:00 | 31/12/9999 | n/a|
|router   | failure | 00:00:00 | 31/12/9999 | n/a|

当前结果:

如果ping成功:

|TYPE     | STATUS  |TIME      | DATE       | MS |
|internet | success | 00:00:00 | 31/12/9999 | 7ms|
|router   | success | 00:00:00 | 31/12/9999 | 1ms|

如果ping失败:

|TYPE     | STATUS  |TIME      | DATE       | MS |
|internet | success | 00:00:00 | 31/12/9999 | 7ms|
|router   | success | 00:00:00 | 31/12/9999 | 7ms|

在循环中使用变化变量时,必须使用delayedexpansion

在脚本开始时:

@echo off
setlocal enabledelayedexpansion

然后:

:routerstart
for /F "tokens=7 delims==< " %%A in ('
ping -4 -n 1 %routerAddress%^|findstr /i "TTL="') do (
set rms=%%A 
if !errorlevel! == 0 ( 
goto:routerSuccess
) else (
goto:routerFail )
)

注意此处的%errorlevel%,因为destination host unreachable将返回errorlevel 0。相反,让我们使用if defined,因为findstr只有在找到TTL=时才会设置imsrms。我们也不需要所有的标签,我们只需要用做代码块if defined语句,第一个for循环将一直到下一个,除了最后一个goto start,其他的都可以去,最后也不需要delayedexpansion

@echo off
set "internetAddress=8.8.8.8"
set "routerAddress=192.168.1.1"
set speed=2
set filename=C:PingTestPingResultsPingTest_%time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%.csv
echo %filename%
echo Type, Status, Time, Date, ms>>%filename%
:start
set ims=
set rms=
set "currentTime=%time:~0,2%:%time:~3,2%:%time:~6,2%"
set "currentDate=%date:~-10,2%/%date:~-7,2%/%date:~-4,4%"
for /F "tokens=7 delims==< " %%G in ('ping -4 -n 1 %internetAddress% ^| findstr /i "TTL="') do set "ims=%%G"
if defined ims ( 
echo internet = success @ %ims% - %currentTime% %currentDate%
echo internet, success, %currentTime%, %currentDate%, %ims%>>%filename%
timeout 2 /nobreak>nul
) else (
echo internet = failure @ N/A - %currentTime% %currentDate%
echo internet, failure, %currentTime%, %currentDate%, N/A>>%filename%
timeout 2 /nobreak>nul
)
for /F "tokens=7 delims==< " %%A in ('ping -4 -n 1 %routerAddress%^|findstr /i "TTL="') do set "rms=%%A"
if defined rms (
echo router = success @ %rms% - %currentTime% %currentDate%
echo router, success, %currentTime%, %currentDate%, %rms%>>%filename%
timeout 2 /nobreak>nul
) else (
echo router   = failure @ N/A - %currentTime% %currentDate%
echo router, failure, %currentTime%, %currentDate%, N/A>>%filename%
timeout 2 /nobreak>nul
)
goto start

我建议任务使用以下代码:

@echo off
set "internetAddress=8.8.8.8"
set "routerAddress=192.168.1.1"
set "speed=2"
set "filename=C:PingTestPingResultsPingTest_%time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%.csv"
(echo Type, Status, Time, Date, ms)>>%filename%
:internetstart
set "currentTime=%time:~0,2%:%time:~3,2%:%time:~6,2%"
set "currentDate=%date:~-10,2%/%date:~-7,2%/%date:~-4,4%"
(ping -4 -n 1 %internetAddress% | findstr /i "TTL=")>nul 2>&1
if %errorlevel% NEQ 0 (
goto :internetfail
) else (
for /F "tokens=7 delims==< " %%A in ('ping -4 -n 1 %internetAddress% ^| findstr /i "TTL="') do (
set "ims=%%A"
)
goto :internetSuccess
)
:internetSuccess
echo internet = success @ %ims% - %currentTime% %currentDate%
(echo internet, success, %currentTime%, %currentDate%, %ims%)>>%filename%
(ping localhost -n %speed%)>nul 2>&1
goto :routerstart
:internetFail
set "ims=n/a"
echo internet = failure @ %ims% - %currentTime% %currentDate%
(echo internet, failure, %currentTime%, %currentDate%, %ims%)>>%filename%
(ping localhost -n %speed%)>nul 2>&1
goto :routerstart
:routerstart
(ping -4 -n 1 %routerAddress% | findstr /i "TTL=")>nul 2>&1
if %errorlevel% NEQ 0 (
goto :routerFail
) else (
for /F "tokens=7 delims==< " %%B in ('ping -4 -n 1 %routerAddress% ^| findstr /i "TTL="') do (
set "rms=%%B"
)
goto :routerSuccess
)
:routerSuccess
echo router   = success @ %rms% - %currentTime% %currentDate%
(echo router, success, %currentTime%, %currentDate%, %rms%)>>%filename%
(ping localhost -n %speed%)>nul 2>&1
goto :internetstart
:routerFail
set "rms=n/a"
echo router   = failure @ %rms% - %currentTime% %currentDate%
(echo router, failure, %currentTime%, %currentDate%, %rms%)>>%filename%
(ping localhost -n %speed%)>nul 2>&1
goto :internetstart

这里的主要问题是您的%errorlevel%变量处理不正确。循环执行命令时,如果没有输出,则整个for循环将被跳过。因此,当命令失败时,for循环被跳过(没有要循环的内容;忽略空行)。

其他一些技术细节已经确定;只是为了避免意外的行为。

最新更新