LINUX.ORG.RU
решено ФорумAdmin

Как curl'ом отловить искомое слово, чтобы при наличии его, срабатывал условный оператор?

 ,


0

1

Хочу раз в минуту, по крону, проверять курлом доступность узла.
При доступности, в выхлопе нет упоминания слова error, а при отсутствии доступа - есть.
Дальше в тот же крон оформить скрипт типа

#!/bin/bash
HOST="yandex.ru"
curl -v $HOST > /dev/null
if [ !встречается совпадение 'error' ]; then
    echo "Работаем дальше"
else
    Выполняем необходимые команды
    для того, чтоб хост стал доступен
fi

Помогите с реализацией скрипта

P.S. Почему курлом? Потому что пингом ответы от узла идут, а страничка в браузере не открывается.



Последнее исправление: Dodik (всего исправлений: 1)
#!/bin/sh
HOST="условно запрещённая экстремистская организация"
if curl -v "$HOST" | grep "error" > /dev/null; then
    echo "Работаем дальше"
else
    Выполняем необходимые команды
    для того, чтоб хост стал доступен
fi

P.S. Вот навига в качестве примера писать «условно facebook.com»*? Написал бы настоящий, или 127.0.0.1, или linux.org.ru, зачем специально запрещёнку-то?


* Facebook признана экстремистской и запрещена в России

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 2)
Ответ на: комментарий от legolegs

Ну я исходил из постановки задачи — наличие искомого слова. Это же пример, может там помимо error ещё какие вещи интересные могут быть, и исходя из них хочется логику строить. А так да, можно и чисто по ответу сервера, даже не читая саму страницу, если сервер отдаёт ошибку.

CrX ★★★★★
()

А зачем бы перенаправил вывод в /dev/null? Ты ж хочешь в нём искать что-то, в /dev/null уже не поищешь.

И из условия непонятно, что надо делать если узел недоступен, т.к. у тебя тут три варианта:

1) недоступен

2) доступен и отвечает error

3) доступен и отвечает без error

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Да.

Там не совсем очевидно, ожидается ли error, или наоборот. Но да, видимо надо наоборот. В общем, думаю, ТС разберётся, в какую ветку что пихать.

CrX ★★★★★
()
Ответ на: комментарий от ugoday

У него curl отрабатывает в любом случае, судя по всему, но страница может содержать или не содержать слово error. Но да, если сервер возвращает таки ошибку, а не 200, то можно и так.

CrX ★★★★★
()
Ответ на: комментарий от s-warus

curl по умолчанию выводит в stdout, -O имеет смысл использовать, если надо в файл, в основном.

upd: более того, -O не нужен дополнительный аргумент, и это как раз использовать имя удалённого файла. Имелось в виду, наверное -o -. Маленькая буква, а не большая. Так будет работать. Но не требуется, поскольку это и так поведение по умолчанию.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 2)
Ответ на: комментарий от ugoday

Я в данном случае о том, что использвание && и || идеоматичнее, чем с помощью if пытаться делать из баша язык программирования.

Когда там одна команда, как в примере с echo, возможно. Когда же там «Выполняем необходимые команды для того, чтоб хост стал доступен», это может быть весьма неудобно. Особенно если у этих команд ещё какая-то там внутренняя логика есть — ещё ветвления или циклы. Придётся {} городить. С if идеоматичнее в таком случае.

А так да, в простейших случаях я тоже люблю && и || использовать вместо громоздких конструкций. Например:

[ -z "$XDG_DATA_HOME" ] && export XDG_DATA_HOME="$HOME/.local/share"

[ -f "/path/to/expected/config" ] || cp default.config "/path/to/expected/config"
CrX ★★★★★
()
  1. Method=1
#!/bin/bash
URL="http://www.freebsd.org"
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
# Check if the status code is 200
if [ "$HTTP_STATUS" -eq 200 ]; then
  echo "Success: Received 200 OK for $URL"
else
  echo "Failure: Received status code $HTTP_STATUS for $URL"
fi
  1. Method=2
#!/bin/bash
URL="http://www.freebsd.org"
if curl --fail --silent --head "$URL" > /dev/null; then
  echo "Success: The URL $URL returned an OK status (not >= 400)."
else
  echo "Failure: The URL $URL returned an error status (>= 400) or curl failed."
fi
antonio-an
()
Ответ на: комментарий от ugoday

Можно. А можно не выносить. Если это всё, что скрипт делает, то плодить функции будет тупо чрезмерным усложнением ради усложнения.

Я бы наверное вообще вот так сделал:

#!/bin/sh
HOST="hostname.ru"

# Если траница не содержит слова error, завершаем работу скрипта
curl -v "$HOST" | grep "error" > /dev/null || exit 0

# А тут уже тупо выполняем необходимые команды
# для того, чтоб хост стал доступен
CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 4)
Ответ на: комментарий от CrX

Это если буквально только это надо. Но вообще я бы сперва пингом проверил какой-нибудь ya.ru, чтобы узнать, есть ли вообще интернет (если нет, то […]). Затем пинганул хост, чтобы убедиться, что он пингуется (и если нет, но интернет есть, это другая проблема, и надо […]). И уже затем проверял содержимое возвращаемой страницы, ежели требуется.

CrX ★★★★★
()
Ответ на: комментарий от CrX

Это если буквально только это надо. Но вообще я бы сперва пингом проверил какой-нибудь ya.ru, чтобы узнать, есть ли вообще интернет (если нет, то […]). Затем пинганул хост, чтобы убедиться, что он пингуется (и если нет, но интернет есть, это другая проблема, и надо […]). И уже затем проверял содержимое возвращаемой страницы, ежели требуется.

Функций оверхеад для задачи.

Ещё не забываем про редирект 301

нужно еще одна проверка на 301 редирект.

А ещё может cloudflare стоять на защите тогда 403 ответ будет.

antonio-an
()
Последнее исправление: antonio-an (всего исправлений: 2)

if [ !встречается совпадение ‘error’ ]

globbing:

if [[ $var != *error* ]]; then
    echo дальше
else
    команда1
    команда2
    ...
fi

regex:

if [[ $var =~ .*error.* ]]; then
    команда1
    команда2
    ...
else
    echo дальше
fi
papin-aziat ★★★★★
()

Ну вот ansible playbook который отлично выполнит задачу.

- name: Send query to yandex.ru.
  ansible.builtin.uri:
    url: https://yandex.ru
    return_content: true
    status_code:
      - 200
      - 202
      - 401
      - 403
      - 404
  register: _this

- name: Fail when status code is 401.
  when:
    - _this.status == "401" 
  ansible.builtin.fail:
    msg: "Status code is 401."

- name: Fail when status code is 403.
  when:
    - _this.status == "403"
  ansible.builtin.fail:
    msg: "Status code is 403."

- name: Fail when status code is 404.
  when:
    - _this.status == "404"
  ansible.builtin.fail:
    msg: "Status code is 404."

- name: Fail when error is found.
  when:
    'error' in _this.content
  ansible.builtin.fail:
    msg: "Error was found in request."
  
Nurmukh ★★★★
()
Ответ на: комментарий от CrX

Но вообще я бы сперва пингом проверил какой-нибудь ya.ru, чтобы узнать, есть ли вообще интернет

Уж простите но пинг на ya.ru не даст никакого представления о «есть интернет или нет». И пинг на 8.8.8.8 тоже не всегда. Надеюсь намек понятен.

anc ★★★★★
()
Ответ на: комментарий от CrX

Но вообще я бы сперва пингом проверил какой-нибудь ya.ru

Я в P.S. это упомянул

P.S. Почему курлом? Потому что пингом ответы от узла идут, а страничка в браузере не открывается.

Чтоб не гадать, давайте выложу все карты.
Вопрос был задан, чтоб продолжить -> эту тему <-. По непонятным (а может и по понятным) причинам, добавленный маршрут, который выпускает маркированный трафик через другой интерфейс, часто отваливается, но сам пинг до необходимых узлов есть! Вот поэтому мне нужна проверка доступности именно по курлу, чтобы в условии else добавлять маршрут снова.
Может есть ещё какие-то способы? Буду рад выслушать

Dodik
() автор топика
Ответ на: комментарий от Dodik

А разве данная проблема не решалась за счет установки у себя на роутере bgp-сервера bird например.

Который бы прописывал какие маршруты куда должны идти?

Nurmukh ★★★★
()