Избегайте ошибок подключения в сценариях Bash, проверяя URL-адреса: вот как
Ключевые выводы
- Не предполагайте, что URL-адреса действительны. Перед использованием проверьте их статус.
- Команда wget может проверить правильность URL-адреса и дать вам некоторую информацию о сбоях.
- Команда cURL может получить код ответа HTTP с веб-сервера для более детального управления.
Когда вы кодируете, предположения — враг надежности. Проверьте веб-адреса, прежде чем использовать их, чтобы убедиться, что они правильно сформированы и находятся в сети. Эти методы проверяют URL-адреса и корректно обрабатывают ошибки.
Не просто надейтесь, проверяйте
Использование веб-адреса или единого указателя ресурсов (URL) в сценарии предполагает решительный шаг. Существует множество причин, по которым попытка использовать URL-адрес может оказаться неудачной.
URL-адрес может содержать опечатки, особенно если URL-адрес передается в качестве параметра скрипта.
Возможно, URL-адрес устарел. Интернет-ресурс, на который он указывает, может быть временно отключен или удален навсегда.
Проверка существования URL-адреса и его корректности перед попыткой его использования является хорошей рабочей практикой. Вот несколько методов, которые вы можете использовать, чтобы убедиться в безопасности продолжения работы с URL-адресом и корректной обработки ошибок.
Нам понадобятся инструменты wget и cURL.
Использование wget для проверки URL-адреса
Команда wget используется для загрузки файлов, но мы можем подавить действие загрузки, используя параметр --spider. Когда мы это сделаем, wget предоставит нам полезную информацию о том, доступен ли URL-адрес и отвечает ли он.
Мы попытаемся проверить, активен ли google.com, а затем попробуем вымышленный URL-адрес geegle.com. Мы проверим коды возврата в каждом случае.
wget --spider https://www.google.com
echo $?
wget --spider https://www.geegle.com
echo $?
Как мы видим, wget сообщает нам, что Google жив и здоров, а Geegle (что неудивительно) — нет. Также обратите внимание, что код выхода в успешном случае равен нулю, а в неудачном — четыре.
Ноль означает успех, все остальное означает наличие какой-то проблемы. Мы можем использовать эти значения в нашем скрипте для управления потоком выполнения.
Вы не можете не заметить, что wget отправляет на экран большой объем вывода. Мы можем подавить вывод с помощью опции -q (тихий).
wget --spider -q https://www.google.com
echo $?
wget --spider -q https://www.geegle.com
echo $?
Откройте свой любимый редактор, скопируйте в него эти строки и сохраните как url-1.sh.
#!/bin/bash
if wget --spider -q https://www.google.com; then
echo "The URL exists and is accessible."
else
echo "Can't access that URL."
fi
Вам нужно будет сделать скрипт исполняемым.
chmod +x url-1.sh
Вам нужно будет сделать это со всеми сценариями, обсуждаемыми здесь. В каждом случае используйте подходящее имя сценария. Давайте запустим наш скрипт.
./url-1.sh
Тест сравнения if обнаруживает нулевой ответ команды wget и выполняет первое предложение оператора if. Если вы отредактируете сценарий и измените URL-адрес на что-то вроде https://www.geegle.com, он сообщит об ошибке.
./url-1.sh
Существует восемь различных ответов, которые может генерировать wget, семь из которых являются ошибочными.
- 0: проблем не возникло.
- 1: общий код ошибки.
- 2: ошибка анализа параметров командной строки.
- 3: ошибка ввода-вывода файла.
- 4: сбой сети.
- 5: ошибка проверки SSL.
- 6: ошибка аутентификации имени пользователя и пароля.
- 7: ошибки протокола.
- 8: сервер выдал ответ с ошибкой.
Команда cURL расширяет эту тему. Он может отображать код ответа HTTP с URL-адреса (или, точнее, с веб-сервера, на котором размещен URL-адрес).
Изолирование кода ответа HTTP
Возможно, вам потребуется установить команду cURL. Вы найдете его в репозиториях вашего дистрибутива.
В Ubuntu используйте:
sudo apt install curl
В Fedora введите:
sudo dnf install curl
На Манджаро и Арче команда такая:
sudo pacman -S curl
Давайте направим cURL на Google и посмотрим, что мы получим. Опция --head указывает Curl получать только информацию заголовка с веб-сайта, а не загружать всю веб-страницу. Опция --silent не подавляет вывод cURL, она не позволяет cURL сообщать о ходе выполнения.
curl --head --silent https://www.google.com
echo $?
Нулевой код завершения — это cURL, сообщающий нам, что все в порядке, но ответ, который нам нужен, — это фактический HTTP-код с сервера. Это число 200 в первой строке вывода. На языке HTTP 200 означает успех.
Мы можем улучшить поведение cURL, направив его вывод в /dev/null, чтобы он работал автоматически, а затем частично отменить это, используя опцию --write-out для отправки кода ответа HTTP в окно терминала.
curl --head --silent --output /dev/null --write-out '%{http_code}' https://www.google.com
Теперь у нас есть код ответа HTTP, и мы можем использовать его в скрипте.
Использование cURL для проверки URL-адреса
Этот сценарий присваивает код ответа HTTP переменной result. Скопируйте это в свой редактор, сохраните как url-2.sh, затем используйте chmod, чтобы сделать его исполняемым.
#!/bin/bash
result=$(curl --head --silent --write-out "%{http_code}" --output /dev/null https://www.google.com)
if [[ $result -eq 200 ]]; then
echo "The URL exists and is accessible."
else
echo "Can't access that URL."
fi
Тест сравнения if проверяет переменную на соответствие значению 200. Если оно соответствует, сценарий выполняет первое предложение оператора if. Любое другое значение рассматривается как состояние ошибки, и выполняется второе предложение.
./url-2.sh
Обработка различных состояний ошибки
Теперь, когда у нас есть способ получить HTTP-код, мы можем расширить возможности нашего сценария по обработке различных ошибок.
#!/bin/bash
target="https://www.google.com"
result=$(curl --head --silent --output /dev/null --write-out '%{http_code}' "$target")
case $result in
200)
echo "The URL exists and is accessible."
;;
301)
echo "HTTP error 301. The resource has been permanently relocated."
;;
403)
echo "HTTP error 403. The server heard you, but won't comply."
;;
404)
echo "HTTP error 404. The classic Page Not Found."
;;
000)
echo "No response from server."
;;
*) # anything not captured in the above list
echo "HTTP error $result."
;;
esac
URL-адрес присваивается переменной с именем target. Эта переменная используется в команде cURL. Если у вас очень длинный URL-адрес, это облегчит чтение сценария.
HTTP-код фиксируется в переменной с именем result. Это используется в операторе случая. Эта структура позволяет вам иметь специальные разделы, обрабатывающие определенные типы ошибок. Последний случай «*)» фиксирует все ошибки, которые не обрабатываются в специальном случае.
Скопируйте это в свой редактор, сохраните как url-3.sh и используйте chmod, чтобы сделать его исполняемым.
./url-3.sh
./url-3.sh
./url-3.sh
Наш скрипт теперь отвечает на ряд кодов ответа HTTP.
Обработка таймаутов
Другой сценарий, с которым должен справиться наш сценарий, — это избежание длительных пауз в ожидании ответа от медленного веб-сервера.
Мы можем добавить еще две опции в командную строку cURL. Опция --connect-timeout устанавливает ограничение на время, в течение которого cURL будет ожидать установления соединения.
Тайм-аут --max-time указывает общее количество времени, которое cURL потратит на выполнение команды. Обратите внимание, что тайм-аут --max-time сработает, даже если команда работает и все еще выполняется. Если вы его используете, поэкспериментируйте с командной строкой, чтобы установить безопасное значение времени для использования.
Мы можем добавить эти параметры в команду cURL следующим образом:
curl --head --connect-timeout 8 --max-time 14 --silent --output /dev/null --write-out '%{http_code}' https://www.google.com
Другие возможности
Раздел скрипта с командой cURL и проверкой кода ответа HTTP может быть отдельной функцией. Любой URL-адрес, который использует ваш скрипт, может быть передан ему для проверки.
У вас может быть файл со списком URL-адресов. Ваш сценарий может открыть файл, прочитать его построчно и проверить каждый URL-адрес. Это был бы простой способ мониторинга работоспособности набора веб-серверов.