Найти загрузчик 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:vfat
2. Получаем путь к устройству и тип файловой системы отдельно в переменные, соответственно, 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=0
2. Получаем выхлоп команды 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

1. Определение файловой системы раздела диска в Linux Копия
2. Команда find в Linux Копия