Сортировка результата команды ping по трем категориям с помощью пакетного скрипта

Я пытаюсь запустить команду 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),

Пожалуйста, начните с запуска примеров ping, которые выводят строки, на которые вы пытаетесь настроить таргетинг (содержащие expired и TTL), а затем скопируйте и вставьте этот вывод в поля кода внутри вашего вопроса.

Compo 28.08.2024 10:34

Обновил вопрос.

MatissePriem 28.08.2024 10:51

Вы не можете фильтровать данные дважды (я имею в виду, что вы можете снова фильтровать отфильтрованный вывод (последовательный), но вы не можете использовать фильтры параллельно. Обходной путь: перенаправить в файл и обработать этот файл три раза (для работы с согласованными данными). .

Stephan 28.08.2024 11:10

@MatissePriem, я удалил твое последнее Редактировать. Нам не нужны обновления выбранного вами решения/обходного пути в самом вопросе. Однако вы можете предоставить ответ на свой вопрос.

Compo 28.08.2024 14:51

@Стефан; Вы можете «повторно использовать» файл, перенаправленный в блок, с помощью нескольких команд find («параллельно»). Смотрите мой ответ ниже. Это не работает с findstr

Aacini 28.08.2024 16:52

@Aacini: интересно. Тем не менее: вам нужен файл (перенаправить из команды нельзя), но при использовании файла интуитивно понятнее читать всего три команды find или findstr.

Stephan 28.08.2024 20:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
51
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это не ответ, а просто очень важное замечание.
Ваш псевдокод содержит следующее:

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 (который, я думаю, ОП пытается «перефильтровать») на данный момент давно пропал.

Stephan 28.08.2024 11:27

У вас это почти есть! ;)

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)

Это отлично работает, большое спасибо!

MatissePriem 29.08.2024 16:09

Другие вопросы по теме