При реабилитации сайта из бекапов случилась рассинхронизация базы данных и файла sitemap.xml. По всей видимости, бекап файловой системы сделал, а база данных устарела (хотя, подозреваю, и sitemap.xml тоже далёк от последней версии).

Yandex и Google подобная картина не нравится и они ругаются на 404 ответ сервера по ссылкам из карты сайта. Дальше я напишу небольшой скрипт для проверки sitemap.xml.

Узнать код ответа сервера по ссылке в bash

Буду собирать этот пазл по кусочкам, и начну с ответа сервера. Для начала нужно получить его заголовок. Сделать это можно, к примеру, с помощью curl:

$ curl -Is https://ozi-blog.ru/ustanovka-lxde-v-ubuntu-16-04/
HTTP/2 200 
server: nginx
date: Sat, 18 Jul 2020 20:16:29 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
x-powered-by: PHP/7.4.7
link: <https://ozi-blog.ru/wp-json/>; rel="https://api.w.org/", <https://ozi-blog.ru/?p=689>; rel=shortlink
cache-control: private, must-revalidate

Интересует первая строчка, а ещё точнее — второе слово в этой строке. Код ответа сервера 200 означает, что страница существует и всё хорошо. Именно этот ответ я приму за эталон, проигнорировав для своих GET запросов другие 2XX коды — т.к. они не должны встречаться на сайте. Само же число можно получить с помощью простого shell конвеера:

$ curl -Is https://ozi-blog.ru/ustanovka-lxde-v-ubuntu-16-04/ | head -1 | awk '{print $2}'
200

Получить ссылки из sitemap.xml в bash

Вторая часть мозайки — необходимо обработать входной xml файл. В нём интересен тег <loc></loc>, содержащий URL страницы. Получить все ссылки из файла sitemap.xml тоже не сложно в shell-скрипте:

$ grep -e loc sitemap.xml | sed 's|<loc>\(.*\)<\/loc>$|\1|g' | xargs -n1
https://ozi-blog.ru/
...

Собираем результат

Осталось пройтись по всем ссылкам из файла в цикле, получить код ответа сервера и сравнить их с 200. В консоль будут выводиться сообщения с кодом ответа и ссылкой, если со страничкой что-то не так. Собственно, сам shell скрипт:

#!/usr/bin/env bash

SITEMAP_XML_PATH=sitemap.xml
while read URL; do
	STATUS_CODE=`curl -Is ${URL} | head -1 | awk '{print $2}'`
	if [[ "${STATUS_CODE}" != "200" ]]
	then
		echo ${STATUS_CODE} ${URL}
	fi
done < <(grep -e loc ${SITEMAP_XML_PATH} | sed 's|<loc>\(.*\)<\/loc>$|\1|g' | xargs -n1)

С помощью переменной SITEMAP_XML_PATH можно задать путь к файлу sitemap.xml, ну или просто запустить скрипт из той же директории.

$ ./check_sitemap.sh 
404 http://ozi-blog.ru/obrabotka-argumentov-komandnoy-stroki-v-bash/
404 http://ozi-blog.ru/kak-zapustit-unity-8-v-ubuntu-16-10/
404 http://ozi-blog.ru/skachat-besplatnyie-knigi-izdatelstva-o-reilly/
404 http://ozi-blog.ru/rabota-s-funktsiyami-v-bash-hanoyskaya-bashnya/
404 http://ozi-blog.ru/podsvetka-redaktiruemoy-stroki-v-emacs/
404 http://ozi-blog.ru/programmnaya-emulyatsiya-nazhatiya-klavish-v-linux-x11/
404 http://ozi-blog.ru/podschyot-simvolov-v-fayle-v-emacs/
404 http://ozi-blog.ru/privyichnyie-kopirovat-vstavit-vyirezat-v-emacs/
404 https://ozi-blog.ru/podschyot-summyi-stolbtsa-v-fayle-bash-awk/
404 https://ozi-blog.ru/ustanovka-lxqt-v-ubuntu/
404 https://ozi-blog.ru/otklyuchenie-nedavno-dobavlennih-zakladok-v-firefox-49-0/

Масштаб проблемы оказался в 11 статьях, возможно, попробую восстановить их из web-архива когда-нибудь.

Сам shell скрипт проверки sitemap.xml скачать можно по ссылке.

Навигация по записям