Вопрос или проблема
У меня есть shell-скрипт, который может собирать время ответа и вес страницы URL. Ключевая часть скрипта выглядит следующим образом:
/usr/bin/curl -s -g -L -c /tmp/cookie.cook -b /tmp/cookie.cook -w "Time:%{time_total}\nSize:%{size_download}\n" -o /tmp/page.tmp $url
Скрипт получает некоторые ссылки в качестве входных данных (</tmp/list
) и затем отправляет данные каждой из них в файл. Каждая ссылка имеет структуру https://<domain>/<Xpath>
с одним и тем же доменом и разными путями.
Эта команда возвращает данные, если запускается из командной строки.
Например:
Time:0.147
Size:13175
Весь скрипт возвращает данные и сохраняет их в файл, если он запускается из командной строки.
Весь скрипт возвращает правильные данные для каждой ссылки кроме одной, если он запускается как задание cron.
*/3 * * * * /bin/bash /root/scripts/<scriptfolder>/<scriptname>.sh >/dev/null 2>&1
Я не знаю, почему это происходит.
В чем может быть проблема при манипуляции с cron?
UPD1: Выполнение команды с этой ссылкой занимает больше времени (не более нескольких секунд), чем выполнение команды с другими ссылками (я заметил это, когда отлаживал скрипт с -x
). Может ли задание cron пропустить строку кода скрипта из-за тайм-аута? И если да, то как решить эту проблему?
Ответ или решение
Для решения проблемы, связанной с различиями в поведении shell скрипта при его запуске в интерактивной оболочке и через cron, необходимо учесть несколько ключевых моментов.
Анализ проблемы
-
Окружение выполнения: Когда вы запускаете скрипт вручную, он наследует ваше пользовательское окружение, включая все переменные среды и инициализационные файлы оболочки. Однако, при выполнении через cron это окружение может существенно отличаться. Cron использует минимальный набор переменных среды, что может привести к различиям в поведении скрипта.
-
Задержка в выполнении задач: Ваша проблема может быть связана с тем, что один из URL имеет большую задержку при обращении. В cron нет механизма, который автоматически завершает долго выполняющиеся задачи, но стоит проверить возможные проблемы с сетью или сервером, связанным с определённым URL.
-
Отсутствие вывода и журналирования ошибок: Вы перенаправляете весь вывод скрипта в
/dev/null
, что затрудняет отладку. Это означает, что любые связанные с ошибками сообщения и предупреждения пропускаются. -
Файлы cookie: Использование файлов cookie может привести к ошибкам, если их содержимое отличается в разных окружениях. Убедитесь, что файл cookie доступен и корректен в окружении cron.
Рекомендации по решению проблемы
-
Настройте переменные окружения: Явно определите необходимые переменные окружения в начале вашего скрипта. Например, задайте
PATH
и любые другие переменные, которые могут повлиять на выполнение вашего скрипта. -
Логирование: Вместо перенаправления выхода в
/dev/null
, создайте лог-файл, чтобы иметь возможность прослеживать возможные ошибки или предупреждения. Измените строку задания cron следующим образом:*/3 * * * * /bin/bash /root/scripts/<scriptfolder>/<scriptname>.sh >> /var/log/myscript.log 2>&1
-
Отладка: Добавьте в скрипт команды для логирования промежуточных данных:
set -x # Включить расширенный вывод для отладки
-
Увеличьте таймаут для
curl
: Если выполнение определенного URL занимает больше времени, используйте параметр--max-time
для увеличения таймаута:/usr/bin/curl --max-time 30 -s -g -L -c /tmp/cookie.cook -b /tmp/cookie.cook -w "Time:%{time_total}\nSize:%{size_download}\n" -o /tmp/page.tmp $url
-
Проверка конкретного URL: Попробуйте запустить проблемный URL непосредственно вне cron, но в том же окружении. Это можно сделать сессино с использованием
su -c "команда"
, чтобы точно воспроизвести условия cron.
Заключение
Проблемы с выполнением скриптов через cron обычно связаны с различиями в окружении и недостаточным логированием ошибок. Применение предложенных решений поможет выявить и исправить проблемы, гарантируя корректное выполнение каждого URL. Однако не забудьте регулярно проверять логи для постоянного мониторинга выполнения ваших скриптов.