Вот подпрограмма (:getData
) и пример ее использования.
Нет простого способа получить все нужные данные в одном цикле for
(возможно, выполнимо каким-то образом, но не стоит проблем), поэтому я решил это с помощью двух отдельных пингов.
localhost
и google
должны вернуться успешно, hp
работает, но не отвечает на ping
, а xxxxxxx.zzz
не существует (пока)
@echo off
setlocal
for %%h in (localhost www.google.com www.hp.com xxxxxxx.zzz) do call :getData %%h
goto :eof
:getData
set "ip=unresolved"
set "ms=unreachable"
for /f "tokens=2 delims=[]" %%a in ('ping -4 -n 1 %1') do set "ip=%%a"
for /f "tokens=3 delims==<" %%a in ('ping -4 -n 4 %1^|find "TTL="') do set "ms=%%a"
set "result=%1^|%ip%^|%ms%"
set "result=%result: TTL=%"
set "result=%result:||=|unknown|%
echo %result%
Выход:
localhost|127.0.0.1|1ms
www.google.com|172.217.22.100|13ms
www.hp.com|15.73.200.24|unreachable
xxxxxxx.zzz|unresolved|unreachable
Так как вы упомянули, это займет некоторое время с 200 хостами. Мы можем ускорить его, запустив разные хосты одновременно (это самое большое изменение, а также самый большой эффект). Я также сократил время ожидания со стандартных 1000 мс до 200 мс и количество пингов с 4 до 2 (я бы не стал уменьшать это далее, потому что иногда пакет теряется и приводит к ложному отрицанию). Также с таким количеством хостов вы достигнете максимальной длины строки этим методом. Лучше хранить имена хостов в файле (по одному на строку) (hostnames.txt
):
@echo off
setlocal
if not "%~1" == "" goto :getData
for /f %%h in (hostnames.txt) do start /min "pinging %%~h" /min "%~f0" %%~h
echo waiting for result.csv to fill...
REM because some of the started processes are still running
timeout 5
goto :eof
:getData
set "ip=unresolved"
set "ms=unreachable"
for /f "tokens=2 delims=[]" %%a in ('ping -4 -n 1 -w 200 %~1') do set "ip=%%a"
for /f "tokens=3 delims==<" %%a in ('ping -4 -n 2 -w 200 %~1^|find "TTL="') do set "ms=%%a"
set "result=%~1^|%ip%^|%ms%"
set "result=%result: TTL=%"
echo %result%>>"%~dp0result.csv"
exit