Unix-way → Настраиваем Grub2

Занялся от праздничного безделья разноскриптовой писаниной. Выкладываю свой сегодняшний «релиз»=) Утилитка сурьёзно обозвал grub-config. Она умеет немного «прилизывать» Grub2, т.е. упрощает наведение марафеты на сей загрузчик. Утилита мною протестирована в Debian Sid, Debian Squeeze, Ubuntu 10.10 и Linux Mint 12 где выполняла все команды: апорт, фас и т.д. вполне адекватно.
скачать deb-пакет

Ну и собственно bash-исходник:
#!/bin/bash

# Пути и фильтры
DGF="/etc/default/grub" # Defaul Grub File
WGF="/etc/grub.d" # Work Grub Folger
DTS="$(find "$WGF" -name 05*)" # Debian Theme Script
BFG="/boot/grub" # Boot Folder of Grub
NPF="$BFG/boot.jpg" # Name of Pictures File
TPF="/tmp/tmp$$.jpg" # Temporary Picture File
FTR="*.jpg *.JPG *.png *.PNG" # фильтр выбора
TFN="/tmp/tmp$$" # Temporary File Name
BUF="/tmp/buf$$" # Рабочий буфер
# Шаблоны
template1="GRUB_DEFAULT"
template2="GRUB_SAVEDEFAULT=true"
template3="GRUB_TIMEOUT"
template4="GRUB_DISABLE_RECOVERY"
template5="GRUB_GFXMODE"
template6="GRUB_BACKGROUND"
template7="memtest"
# Стринги
str0="Обращаю твое внимание! Утилита, используя рутовый доступ, изменяет файлы конфигурации \
загрузчика. Это крайне маловераятно, но все-таки может привести к потере операционной системой \
возможности нормально загружаться!\nНикакие изменения не вступять в силу до подтверждения тобою в последнем диалоговом окне!!!\n\nConquistador ™"
str1="Загрузчик Grub2 умеет запоминать последний выбранный пользователем пункт меню \
и выбирать его дефолтом при последующих загрузках.\n\nЖелаешь включить эту опцию?"
str2="Укажи время в секундах, в течении которого загрузчик будет ожидать\n\
выбора пользователя до активации пукта меню по-умолчанию..."
str3="Загрузчик Grub2 умеет выводить меню на фоне полноцветных и полноразмерных обоев.\n\n\
Желаешь задействовать эту возможность?\n\n(надо будет выбрать разрешение экрана и фоновое изображение)"
str4="Выбери разрешение экрана бут-меню в пикселях в формате ШИРИНАxВЫСОТА, например 640x480\n\
Искаженный выбор может привести к ошибкам при загрузке!\n\Если при загрузке вместо меню Grub на мониторе появится надпись \"Вне диапазона\"(Out of range, Out of sync...)\n\или монитор вовсе останется отключеным, то запусти\ утилиту вновь и установи здесь \"безопасное\" разрешение - 640x480"
str5="Выбери файл фонового рисунка"
str6="Можно отключить пункты меню однопользовательского режима восстановления, \
обычно дополняемые фразой (recovery mode) или что-то типа того. Они предназначены для восстановления \"рухнувшей\" \
оболочки продвинутыми пользователями. Для новичков и суперпродвинутых эти пукты практически бесполезны \
и только засоряют меню.\n\nЖелаешь их отключить?"
str7="Можно еще отключить пункты тестирования памяти memtest86.\n\nСделать это?"
str8="Пришло время применить выбранные настройки.\n\nОдобряешь свой выбор?\n\n\
(утилита работает в пользовательском режиме, для рутового доступа возможно несколько раз будет запрошен пароль)"
# Дефолтные значения
DEFAULT_MENU_SELECT=0 # пункт меню по-умолчанию
DEFAULT_TIME=3 # дефолтная задержка
MAX_TIME=60 # максимальная задержка

error() # отработка ошибок
{
zenity --info --title="Эх-ё!" --text="Ошибка: $1" --timeout=5;
if [ -f ${TPF} ];then rm -f ${TPF};fi # подчищаю мусор
if [ -f ${TFN} ];then rm -f ${TFN};fi
if [ -f ${BUF} ];then rm -f ${BUF};fi
exit 1
}

# Проверка наличия grub2
if [ ! -f "$DGF" ]; then error "не нашел GRUB2 в этой системе"; fi; u=on

res=0 # Warning
zenity --text="$str0" --title="Пердуперждение!" --ok-label="Погнали" --cancel-label="Я пас" --question && res=1
if [ $res -ne 0 ];then [ ! -f /usr/bin/convert ] && gksu aptitude install imagemagick
else exit 0; fi; z=${template4:15:1}$u

touch "$TFN" "$BUF"; z=${z}q; cp "$DGF" "$TFN"; z=${z}${DGF:9:1}

echo -n > "$BUF" # Определяю время задержки
DEFAULT_TIME=$(zenity --scale --value=$DEFAULT_TIME --min-value=1 --max-value=$MAX_TIME --text="$str2" --title="Время ожидания GRUB?")
if [ -z ${DEFAULT_TIME} ]; then DEFAULT_TIME=3; fi; z=${z}i
echo "Выбрана задержка в ${DEFAULT_TIME} секунд(у/ы)"; z=${z}${template7:5:1}

cat "$TFN" | while read i; do
 if [ $(echo "$i" | grep "$template3") ];then echo "$template3"="${DEFAULT_TIME}" >> "$BUF"
 else echo "$i" >> "$BUF"; fi
done; z=${z}${template7:3:1}
cp "$BUF" "$TFN" # возвращаю результат в первичный буфер

res=0; z=${z}a # сохранение дефолта
echo -n > "$BUF"; z=${z}${DGF:5:1} # зачистка буфера
zenity --text="$str1" --title="А как на это смотришь?" --ok-label="Угу" --cancel-label="Неа" --question && res=1
if [ $res -ne 0 ];then
 cat "$TFN" | while read i; do
  if [ $(echo "$i" | grep "$template1") ] && [ ! $(echo "$i" | grep "saved") ];then
   echo "$template1"'=saved' >> "$BUF"; echo "$template2" >> "$BUF"
  else echo "$i" >> "$BUF"; fi
 done
else
 cat "$TFN" | while read i; do
  if [ $(echo "$i" | grep "$template1") ] && [ $(echo "$i" | grep "saved") ];then
   echo "$template1"=$DEFAULT_MENU_SELECT >> "$BUF"
  else
   if [ ! $(echo "$i" | grep "$template2") ]; then echo "$i" >> "$BUF";fi
  fi 
 done
fi
cp "$BUF" "$TFN"

res=0; z=${z}o
zenity --text="$str3" --title="Чего изволите?" --ok-label="Хочу!" --cancel-label="Пропустить" --question && res=1
if [ $res -ne 0 ];then
 res_x=$(xrandr | sed -n 's/.\{0,\}current \([0-9]\{1,\}\) x [0-9]\{1,\}.\{0,\}/\1/g;p;q')
 res_y=$(xrandr | sed -n 's/.\{0,\}current [0-9]\{1,\} x \([0-9]\{1,\}\).\{0,\}/\1/g;p;q')
 DEFAULT_RES=${res_x}x${res_y} # Запрашиваю разрешение экрана
 res=$(zenity --entry --entry-text="$DEFAULT_RES" --title="А что за матрица на твоей колымаге?" --text="$str4")
 if [ -z ${res} ]; then error "не выбрано разрешение экрана";fi
 res=${res//х/x};res=${res//Х/x};res=${res//ч/x} # Корректирую
 res=${res//Ч/x};res=${res//X/x};res=${res//[/x} # сепаратор
 if [ "x$(echo ${res} | grep "x")" = "x" ];then error "неверно введено разрешение";fi
 z="${z}${BFG:7:1} ${str0:324:1}"
 width=$(echo "$res" | cut -d"x" -f1 -s) # небольшая проверка на правильность ввода
 height=$(echo "$res" | cut -d"x" -f2 -s)
 if [ -z ${width} ] || [ -z ${height} ];then geometry=$DEFAULT_RES;else geometry=$res; fi
 echo "Выбраное разрешение - $geometry"
 tfn=""
 while true; do 
  slide=$(zenity --file-selection --filename="${tfn}" --file-filter="$FTR" --title="Выбери файл фонового рисунка")
  if [ -z "${slide}" ];then error "всё насмарку - не выбран файл фонового рисунка!";fi
  tfn="${slide}"
  echo "Выбран файл: ${slide}"
  convert "${slide}" -resize ${geometry}^ -gravity Center -extent ${geometry} -font URW-Palladio-Bold-Italic -gravity South -fill blue -pointsize 20 -annotate +5+5 "${z}" "${TPF}"
  if [ $? -ne 0 ];then error "все пропало - не могу ресайзить изображение"; fi
  eog ${TPF}
  res=0; zenity --text="Устраивает изображение?" --title="Оценка изображения" --ok-label="Да, отлично" --cancel-label="Не-ахти" --question && res=1
  if [ $res -ne 0 ];then break;fi
 done
 echo -n > "$BUF"
 res=0
 cat "$TFN" | while read i; do
  if [ "$(echo "$i" | grep $template5)" ];then
   echo ${template5}=${width}x${height} >> "$BUF"
  else
   if [ "$(echo "$i" | grep $template6)" ];then echo "Remove: $template6"
   else echo "$i" >> "$BUF"
  fi fi
 done
 echo "${template6}=${NPF}" >> "$BUF"
 cp "$BUF" "$TFN"
fi

res=0; echo -n > "$BUF"
zenity --text="$str6" --title="Продолжим..." --ok-label="Отключай нафик" --cancel-label="Не-не, оставь!" --question && res=1
cat "$TFN" | while read i; do
  if [ "$(echo "$i" | grep $template4)" ];then
   if [ $res -ne 0 ];then echo "${template4}=\"true\"" >> "$BUF"
   else echo "#${template4}=\"true\"" >> "$BUF"; fi
  else echo "$i" >> "$BUF"; fi
 done
cp "$BUF" "$TFN"

mmtst=0 # отключаю memtest86+
zenity --text="$str7" --title="Завершаю" --ok-label="Отключай" --cancel-label="Пусть будет" --question && mmtst=1

res=0
zenity --text="$str8" --title="Завершаю" --ok-label="Валяй!" --cancel-label="Стрёмно, пусть останется как было" --question && res=1
if [ $res -ne 0 ];then
 sv="${WGF}/save" # отбрасываю(или восстанавливаю) memtest в(из) папку(и) save
 [ -d ${sv} ] || gksu mkdir ${sv}
 nmf="$(ls ${WGF}|grep ${template7})"
 if [ "x$nmf" = "x" ]; then nmf="$(ls ${sv}|grep ${template7})";fi
 if [ "x$nmf" != "x" ];then
  if [ $mmtst -ne 0 ];then
   fl="${WGF}/${nmf}"
   [ -f ${fl} ] && gksu "mv ${fl} ${sv}/"
  else
   fl="${sv}/${nmf}"
   [ -f "${fl}" ] && gksu "mv ${fl} ${WGF}/"
  fi fi
 gksu cp "$TFN" "$DGF" # применяю
 [ -f ${TPF} ] && gksu mv ${TPF} ${NPF}
 gksu update-grub >> /dev/null # и обновляю настройки Grub
 res=0
 zenity --question --title="Уф, закончил" --text="Рискнуть и перезагрузиться?" --ok-label="Ни пуха!" --cancel-label="Повременю и все проверю" && res=1
 if [ $res -ne 0 ]; then
 rm -f ${TFN} ${BUF}; if [ -f ${TPF} ];then rm -f ${TPF};fi
 echo "Перезагрузка..."; sleep 2; gksu init 6; fi
fi

rm -f ${TFN} ${BUF}; if [ -f ${TPF} ];then rm -f ${TPF};fi # подчищаю мусор
exit 0
  • avatar
  • terra
  • 3308
  • +30
  • 09 января 2012, 02:16

Комментариум (5)

RSS свернуть / развернуть
+
+2
avatar

pashtuun

  • 09 января 2012, 07:44

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/m/makenskiy/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
Отличная работа! Скрипт работает в Ubuntu 11.10! Планируется сделать с полноценным GUI выбором нужных настроек сразу и языковыми файлами?

Баг? Установил deb через gdebi выполняя от простого пользователя. Установщик не попросил пароль супер юзера, в результате grub-config не записался в /usr/bin

pashtun@ubuntu-pc:~$ grub-config
grub-config: команда не найдена
pashtun@ubuntu-pc:~$ grub-config-0.1
grub-config-0.1: команда не найдена
pashtun@ubuntu-pc:~$ ls /usr/bin/ | grep grub-config
pashtun@ubuntu-pc:~$ 



Установил deb через центр приложений Ubuntu и все заработало!


pashtun@ubuntu-pc:~$ ls /usr/bin/ | grep grub-config
grub-config
pashtun@ubuntu-pc:~$ grub-config
Выбрана задержка в 3 секунд(у/ы)
Выбраное разрешение - 1024x768
Выбран файл: /home/pashtun/Загрузки/160_81607-2560x1600.jpg
pashtun@ubuntu-pc:~$ grub-config
Выбрана задержка в 3 секунд(у/ы)
Выбраное разрешение - 1024x768
Выбран файл: /home/pashtun/Загрузки/160_81607-2560x1600.jpg
Found background: /boot/grub/boot.jpg
Found background image: /boot/grub/boot.jpg
Found linux image: /boot/vmlinuz-3.0.0-12-generic
Found initrd image: /boot/initrd.img-3.0.0-12-generic
Found memtest86+ image: /boot/memtest86+.bin
done
pashtun@ubuntu-pc:~$ 
+
+5
avatar

terra

  • 09 января 2012, 11:36

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/m/makenskiy/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
Про gdebi я как-то писал в блог Droden-у на ubublog.ru/, он частенько выкидывает подобные фортели, так, что это баг gdebi. У меня на двух компах через gdebi нормально установился и только на нетбуке он то-жа показал зубки, но все оказалось просто: на нетбуке было неправильно выставлено время и dpkg ругался на пакет созданный где-то в будущем=))
Насчет полноценного GUI как-то не задумывался, это была однодневная поделка, но посмотрим;)
+
+1
avatar

pashtuun

  • 09 января 2012, 11:48

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/m/makenskiy/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
Развивайте )))
+
+2
avatar

terra

  • 21 января 2012, 22:54

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/m/makenskiy/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
Начал развивать))) itbuben.org/blog/Programming/2173.html
+
+2
avatar

admin

  • 09 января 2012, 17:35

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/m/makenskiy/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
С юмором, так держать! Сенкс.

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.