Вопрос или проблема
Можем ли мы сделать что-то подобное в скрипте (предпочтительно zsh):
smartctl -t long /dev/sda
smartctl -t long /dev/sdb
smartctl -t long /dev/sdc
[Подождите столько, сколько нужно smartctl]
smartctl -H /dev/sda
smartctl -H /dev/sdb
smartctl -H /dev/sdc
Как видно, я просто пытаюсь автоматизировать это.
Существует 2 возможности. smartctl -c
выведет список возможностей устройства, которые включают строки вроде
Рутина короткого самопроверки
рекомендуемое время опроса: ( 1) минут.
Расширенная рутина самопроверки
рекомендуемое время опроса: ( 48) минут.
Таким образом, вы можете просто прочитать их и сделать паузу на необходимое короткое или длинное время.
Во-вторых, пока тест выполняется, тот же параметр -c
выведет текущий статус любого теста, например:
Статус сбора данных в оффлайне: (0x03) Активность сбора данных в оффлайне
выполняется.
Статус выполнения самопроверки: ( 247) Рутины самопроверки в процессе...
70% от теста осталось.
Общее время для завершения
сбора данных в оффлайне: ( 44) секунд.
Таким образом, вы можете опрашивать каждые несколько минут и ждать, пока оставшееся время не вернется к 0, а другие поля не примут свои окончательные значения:
Статус сбора данных в оффлайне: (0x02) Активность сбора данных в оффлайне
была выполнена без ошибок.
Статус выполнения самопроверки: ( 0) Предыдущая рутина самопроверки завершена
без ошибок или самопроверка никогда не
выполнялась.
Общее время для завершения
сбора данных в оффлайне: ( 0) секунд.
Это не выглядит красиво, но, похоже, это работает. Легко может быть изменено, чтобы обрабатывать произвольное количество дисков. Модификации приветствуются.
#!/usr/bin/zsh
#set -x
outputmsg () { echo -e "\e[35;1m$@\e[0m"; }
infomsg () { echo -e "\e[36;1m$@\e[0m"; }
smartctl -X /dev/sda &> /dev/null
wait_time_greatest=$( smartctl -t short /dev/sda | grep 'Please wait' | sed 's,^\(Please wait \)\([[:digit:]]*\)\(.*\),\2,' )
smartctl -X /dev/sdb &> /dev/null
wait_time_new=$( smartctl -t short /dev/sdb | grep 'Please wait' | sed 's,^\(Please wait \)\([[:digit:]]*\)\(.*\),\2,' )
[ "$wait_time_new" -gt "$wait_time_greatest" ] && wait_time_greatest="$wait_time_new"
wait_time_greatest=$((wait_time_greatest + 1)) #На всякий случай?
infomsg "\nМы закончим через $wait_time_greatest минут ...\n"
sleep "$[wait_time_greatest]m"
outputmsg "Диск sda:" # Странно, что в отчете не указано ID диска.
echo -e \e[0m # Необходимо сбросить цвет!
smartctl -H /dev/sda
outputmsg "Диск sdb:"
echo -e \e[0m # Необходимо сбросить цвет!
smartctl -H /dev/sdb
# Поскольку smartctl, похоже, это портит, нужно выполнить снова:
hdparm -S60y /dev/sda
hdparm -S60y /dev/sdb
В оболочке xonsh вы можете использовать это, чтобы дождаться завершения всех дисков их тестов smart:
while not all(
$(sudo smartctl -c @(drive) | egrep r"Статус выполнения самопроверки:\s+\(\s*0\)")
for drive in g`/dev/sd?`):
sleep 20s
Этот цикл выполняется до тех пор, пока вывод smartctl для всех дисков, совпадающих с глобом /dev/sd?, не соответствует регулярному выражению, переданному в egrep.
Регулярное выражение ищет следующий вывод:
Статус выполнения самопроверки: ( 0)
Пока хотя бы один тест выполняется, соответствующий egrep ничего не находит, возвращая пустую строку. Это заставляет вызов all() возвращать False, что инвертируется в True с помощью not, поддерживая цикл в работе. Как только все диски совпадают, т.е. завершены, цикл while прерывается.
Примечание о sudo
Это требует, чтобы команда sudo smartctl -c /dev/sdX выполнялась без запроса пароля. Либо настройте sudo так, чтобы он не требовал паролей для этой команды, либо настройте его так, чтобы он не требовал пароля в течение времени, превышающего период ожидания с момента последнего использования sudo. Опрос будет держать аутентификацию активной и не требовать пароль до завершения.
Или уберите sudo и выполните оболочку (скрипт) от имени root.
Ответ или решение
Автоматическое ожидание завершения тестов с помощью smartmontools
Вопрос автоматизации ожидания завершения тестов на дисках с использованием инструмента smartctl
из пакета smartmontools
является распространенной задачей для системных администраторов и техников. В этой статье мы рассмотрим, как можно реализовать автоматическое ожидание, используя язык сценариев zsh
.
Возможные подходы
Существует два основных подхода, которые можно использовать для достижения автоматизации вашего сценария:
-
Изучение временных интервалов тестирования
Инструментsmartctl
предоставляет информацию о времени, необходимом для завершения теста, при помощи командыsmartctl -c /dev/sdX
. Это позволит нам извлечь ожидаемое время выполнения тестов, затем использоватьsleep
для ожидания. -
Проверка статуса выполнения теста
Во время выполнения теста можно периодически проверять статус с помощью той же командыsmartctl -c /dev/sdX
, чтобы видеть, когда тест завершится, и только после этого продолжать выполнение следующего шага.
Рекомендуемый сценарий на языке zsh
Далее приведен пример скрипта, который реализует оба подхода:
#!/usr/bin/zsh
# Функция вывода сообщения
outputmsg () { echo -e "\e[35;1m$@\e[0m"; }
infomsg () { echo -e "\e[36;1m$@\e[0m"; }
# Запускаем тесты на всех целевых дисках
for disk in /dev/sda /dev/sdb /dev/sdc; do
smartctl -t long "$disk" &> /dev/null
done
# Получаем максимальное время ожидания для всех запущенных тестов
wait_time=0
for disk in /dev/sda /dev/sdb /dev/sdc; do
time_required=$(smartctl -c "$disk" | grep 'recommended polling time:' | awk '{print $NF}')
wait_time=$(($wait_time > $time_required ? $wait_time : $time_required))
done
infomsg "\nОжидание завершения тестов займет примерно $wait_time минут(ы)...\n"
sleep "${wait_time}m"
# Проверка статуса завершения теста для каждого диска
while true; do
all_done=true
for disk in /dev/sda /dev/sdb /dev/sdc; do
status=$(smartctl -c "$disk" | grep 'Self-test execution status' | awk '{print $NF}')
if [[ "$status" != "(0)" ]]; then
all_done=false
break
fi
done
if $all_done; then
break
fi
sleep 20s
done
# Вывод результатов тестирования
for disk in /dev/sda /dev/sdb /dev/sdc; do
outputmsg "Результаты теста для $disk:"
smartctl -H "$disk"
done
Как работает скрипт
- Запуск тестов: Скрипт запускает длинные тесты для всех заданных дисков.
- Извлечение времени ожидания: Для каждого диска извлекается рекомендованное время ожидания, и выбирается максимальное время для использования в
sleep
. - Ожидание завершения: После ожидания указанного времени выполняется цикл проверки состояния теста. Скрипт продолжает опрашивать состояние до тех пор, пока все тесты не будут завершены.
- Вывод результатов: Напоследок выводятся результаты тестов для каждого диска.
Заключение
Использование приведенного скрипта на zsh
позволяет автоматизировать процесс ожидания завершения тестов на дисках, делая вашу работу более эффективной и освобождая время для более важных задач. Обратите внимание на возможность конфигурации sudo
, если она необходима для выполнения команд без необходимости ввода пароля.
Этот подход значительно упрощает наблюдение за состоянием дисков и гарантирует, что ваша система останется в исправном состоянии, благодаря регулярной проверке состояния SMART.