具有.csv输出的恒定ping批处理文件无法正常工作

时间:2019-02-08 23:00:33

标签: batch-file

我遇到Internet问题,想创建一个后台脚本,对我的路由器和Internet进行持续的ping操作,以便我跟踪连接断开的频率。

我设法做的是创建一个批处理文件,该文件对我的路由器和Internet进行恒定的ping操作,获取响应时间,然后在控制台中创建输出以及包含多个字段(例如status)的CSV文件(即成功ping或失败)ping时间,ping日期等

我遇到的问题是,如果连接断开,我没有的代码将不输出,我认为这是因为由于ping输出被切碎并存储在a中,所以我输入的%errorlevel%变量不起作用变量,但是我可能错了,这就是为什么我在这里解释我的问题。

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

现在看来,我只能执行其中之一:

@ECHO OFF
@SETLOCAL

set internetAddress=8.8.8.8
set routerAddress=192.168.1.0
set speed=2
set filename=C:\PingTest\PingResults\PingTest_%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|

3 个答案:

答案 0 :(得分:2)

在循环中使用变化的变量时,您必须使用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 )
)

答案 1 :(得分:1)

请谨慎使用%errorlevel%,因为destination host unreachable将返回errorlevel 0。相反,让我们使用if defined只是因为findstr仅在发现ims的情况下才会设置rmsTTL=。我们也不需要所有标签,我们只需要使用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:\PingTest\PingResults\PingTest_%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

答案 2 :(得分:0)

对于该任务,我建议使用以下代码:

@echo off

set "internetAddress=8.8.8.8"
set "routerAddress=192.168.1.1"
set "speed=2"
set "filename=C:\PingTest\PingResults\PingTest_%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循环(无循环;忽略空行)。

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