Я пытаюсь запустить команду ping и выполнить сортировку по критериям «онлайн», «офлайн» и «истек срок действия». Я пробовал использовать find
и findstr
, но, похоже, мне удалось отсортировать только 2 варианта.
На данный момент у меня есть это:
ping -n 1 %ip% | find "TTL"
if errorlevel 1 set error= offline
if errorlevel 0 | find "expired"
if errorlevel 0 set error=expired
else set error=online
Я предполагаю, что это не сработает, потому что третья строка не знает, где искать «истёк срок действия»? Любая помощь будет очень признательна.
Онлайн-компьютер возвращает это:
Pinging pcName [ip] with 32 bytes of data:
Reply from ip: bytes=32 time=1ms TTL=125
Reply from ip: bytes=32 time=1ms TTL=125
Reply from ip: bytes=32 time=1ms TTL=125
Reply from ip: bytes=32 time=1ms TTL=125
Ping statistics for ip:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 1ms, Maximum = 1ms, Average = 1ms
Автономный компьютер возвращает это:
Pinging pcName [ip] with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Ping statistics for ip:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
И компьютер с истекшим сроком действия возвращает это:
Pinging pcName [ip] with 32 bytes of data:
Reply from ip: TTL expired in transit.
Reply from ip: TTL expired in transit.
Reply from ip: TTL expired in transit.
Reply from ip: TTL expired in transit.
Ping statistics for ip:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Обновил вопрос.
Вы не можете фильтровать данные дважды (я имею в виду, что вы можете снова фильтровать отфильтрованный вывод (последовательный), но вы не можете использовать фильтры параллельно. Обходной путь: перенаправить в файл и обработать этот файл три раза (для работы с согласованными данными). .
@MatissePriem, я удалил твое последнее Редактировать. Нам не нужны обновления выбранного вами решения/обходного пути в самом вопросе. Однако вы можете предоставить ответ на свой вопрос.
@Стефан; Вы можете «повторно использовать» файл, перенаправленный в блок, с помощью нескольких команд find
(«параллельно»). Смотрите мой ответ ниже. Это не работает с findstr
@Aacini: интересно. Тем не менее: вам нужен файл (перенаправить из команды нельзя), но при использовании файла интуитивно понятнее читать всего три команды find
или findstr
.
Это не ответ, а просто очень важное замечание.
Ваш псевдокод содержит следующее:
if errorlevel 1 set error= offline
if errorlevel 0 | find "expired"
Нужно понимать, что возможны оба случая: вы запускаете ping-запрос, а уровень ошибки равен 1. В результате переменная error
получит значение offline
.
Затем вы снова проверяете, что уровень ошибки равен нулю, и вполне возможно, что это правда, потому что на этот раз это будет не уровень ошибки запроса «ping», а уровень ошибки присваивания переменной set error=offline
!
также if errorlevel n
работает как «Если уровень ошибки равен n или выше», поэтому второй if
все равно выполняется. Просто |find
здесь не имеет никакого смысла. Это недействительная команда, и вывод ping
(который, я думаю, ОП пытается «перефильтровать») на данный момент давно пропал.
У вас это почти есть! ;)
ping -n 1 %ip% > ping.txt
< ping.txt (
find "TTL"
if errorlevel 1 (
set error=offline
) else (
find "expired"
if not errorlevel 1 (
set error=expired
) else (
set error=online
)
)
) > NUL
Ответ @Aacini работает и технически верен, но его трудно читать и устранять неполадки без большого опыта работы с cmd/batch. И что еще более важно: это зависит от языка.
ping
зависит от языка, и я всегда стараюсь найти независимое от языка решение (хотя это не всегда возможно). Как и в случае с ping
, константой во всех языках является строка TTL
(никогда не переводится).
Три строки примера можно легко отличить:
Request timed out. none of the search strings = status = "offline" (as default)
Reply from ip: bytes=32 time=1ms TTL=125 searchstring "TTL = " = overwrite status with "online"
Reply from ip: TTL expired in transit. searchstring "TTL " = overwrite status with "expired"
Код довольно интуитивно понятен и легко читается:
@echo off
setlocal
ping -4 -n 1 %ip% >ping.txt
set "status=offline"
>nul find "TTL " ping.txt && set "status=expired"
>nul find "TTL = " ping.txt && set "status=online"
echo %ip% is %status%
Я никогда не сталкивался с сообщением «истек срок действия», но, судя по результатам вашего вопроса, мое решение должно работать нормально.
И что более важно: это не зависит от языка.
(Я добавил -4
, потому что вывод при использовании IPv6 отличается — это не важно, если вы используете адрес IPv4, но будет кусать вас при использовании чего-то вроде «google.com», когда включены как IPv4, так и IPv6)
Это отлично работает, большое спасибо!
Пожалуйста, начните с запуска примеров
ping
, которые выводят строки, на которые вы пытаетесь настроить таргетинг (содержащиеexpired
иTTL
), а затем скопируйте и вставьте этот вывод в поля кода внутри вашего вопроса.