Скрипт для поиска загрузчика Windows из Linux-окружения.
Найти загрузчик Windows на разделе жесткого диска, дело не очень сложное:
1. Надо проверить файловую систему раздела, она должна быть FAT32 или NTFS
2. Проверить наличие файла
ntldr (Windows XP и ранее) или bootmgr (Windows Vista и позднее) в корне раздела. Windows XP и старше, при установке по умолчанию, записывают файл ntldr в корень системного раздела, а более новые - создают отдельный загрузочный раздел, в корне которого лежит bootmgr. Для чего? Например, для создания своего скрипта автоматической настройки загрузчика Grub или Syslinux
Я недавно писал о том, как узнать файловую систему раздела (диска) в Linux Копия. В данном случае действовать будем примерно также.
Обработать вывод команды
blkid (вывод данных о блочных устройствах) можно в цикле for:echo "Find Windows loaders..."
IFS=$'\n'
for DEVDATA in $(blkid); do
...
doneПеред циклом необходимо установить значение переменной
IFS, как \n (перенос строки)IFS - переменная, задающая разделители полей при работе со строками в shell, по умолчанию разделители это табуляция, перенос строки и пробел, если не установить ее значение, как "только перенос строки", то строка с описанием каждого раздела (например, /dev/sda1: UUID="68DF-FF87" TYPE="vfat" PARTUUID="00003214-01") распадется на части, что поломает алгоритм.В цикле
for:1. Вытаскиваем в переменную
VOL нужные данные - путь к устройству и файловую систему:VOL=`echo "$DEVDATA" |sed -n 's/\(.*:\).* TYPE=\"\([^\"]*\)\".*/\1\2/p'`Для вышеуказанного
/dev/sda1 получится строка /dev/sda1:vfat2. Получаем путь к устройству и тип файловой системы отдельно в переменные, соответственно,
VOLNAME и VOLFS.VOLNAME=`echo "$VOL"|awk -F ":" '{print $1}'`
VOLFS=`echo "$VOL"|awk -F ":" '{print $2}'`Параметр
-F ":" устанавливает двоеточие в качестве разделителя полей awk.3. Далее, проверяем, не пуста ли строка в переменной
VOLFS, и проверяем ее значение. Если VOLFS равна ntfs или vfat, то запускаем функцию find_loader(), проверяющую наличие загрузчика в корне соответствующего раздела. Если файловая система раздела другая - выводится сообщение, что это не Windows-раздел.if [ -n "$VOLFS" ]; then
if [[ "$VOLFS" == "ntfs" || "$VOLFS" == "vfat" ]];then
find_loader $VOLNAME $VOLFS
else
echo "$VOLNAME not windows volume"
fi
fi
Можно было бы еще исключать разделы FAT16, но решил не загромождать скрипт лишней проверкой.
В функцию
find_loader() передаются два параметра: путь к устройству (разделу) и его файловая система.1. Заведем переменную-флаг, указывающую, был ли раздел временно смонтирован
TMPMOUNT=02. Получаем выхлоп команды
mount. grep'ом фильтруем вывод по соответствующему разделу, с помощью awk вытаскиваем точку монтирования.MOUNTPOINT=`mount|grep -w "$1"|awk '{print $3}'`3. Если переменная
MOUNTPOINT пустая, раздел не смонтирован. Создаем временную точку монтирования, пытаемся смонитровать раздел, если получилось - устанавливаем TMPMOUNT=1, в переменную MOUNTPOINT записываем временную точку монтирования и приступаем к поиску загрузчика, если не получилось - выходим из функции:if [ -z "$MOUNTPOINT" ]; then
mkdir -p "/tmp/tmpmount"
mount -t "$2" "$1" "/tmp/tmpmount"
if [ $? -ne 0 ]; then
echo "$1 not mounted"
return
fi
MOUNTPOINT="/tmp/tmpmount"
TMPMOUNT=1
fi
Примечание: ключ
-p команды mkdir позволяет создать путь вместе со всеми подкаталогами, а если путь уже создан, то команда mkdir не выдаст ошибки, что путь уже существует.Надо обратить внимание на то, что Windows нечувствительна к регистру имен файлов, так что загрузчик может быть и
bootmgr и BOOTMGR, и даже BoOtMgR (аналогично и ntldr). Поэтому придется воспользоваться командой find.find <path> -maxdepth 1 -iname <filename>где:
<path> - путь к каталогу, с которого начинать поиск-maxdepth - глубина поиска в подкаталогах (начиная с указанного в <path>, 1 - только каталог <path> без подкаталогов).-iname - игнорировать регистр имени файла<filename> - имя файла (или маска), который будем искать.В данном случае надо обязательно установить
-maxdepth 1, иначе будут большие тормоза, а при отмонтировании возможны глюки.4. Ищем загрузчик Vista и выше и сохраняем выхлоп в переменную
FOUND:FOUND=`find "$MOUNTPOINT" -maxdepth 1 -iname "bootmgr"`5. Если нашли (переменная
FOUND не пустая), выводим соответствующее сообщение, если нет - ищем загрузчик Windows XP, и выводим сообщение в зависимости от того, нашли или нет:if [ -n "$FOUND" ];then
echo "$1: found bootmgr (Windows Vista and newer)"
else
#ntldr - Win XP and older
FOUND=`find "$MOUNTPOINT" -maxdepth 1 -iname "ntldr"`
if [ -n "$FOUND" ];then
echo "$1: found ntldr (Windows XP and older)"
else
echo "$1: Windows loader not found"
fi
fi
6. Проверяем флаг
TMPMOUNT, если он был установлен в 1, отмонтируем временно смонтированный раздел:if [ $TMPMOUNT -eq 1 ]; then
sleep 1
umount "/tmp/tmpmount"
fi
Запуск на тестовой машине с разделами FAT32/NTFS, но без установленной Windows:

Запуск на машине с установленной Windows 7:

Запуск на машине с установленной Windows XP

На GitHub
На PasteBin
1. Определение файловой системы раздела диска в Linux Копия
2. Команда find в Linux Копия
Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2019/03/27/skri