Most of the work I do with Ubuntu Linux is on home computers where the user needs to have Windows XP (Vista, 7) as a boot option. The best way for Ubuntu, or Linux in general, to work is if its on its own partition and not installed with the Wubi Installer. One of the main issues I have with installing Ubuntu on its own partition is that the Grub2 Boot Loader menu looks terrible and is confusing once you’ve gone through several kernels updates. I wanted a simple and easier to understand Grub2 menu and something that would take care of itself in the long run.

This script makes four entries at the top of the Grub2 boot menu.


Ubuntu
Windows

Other boot options:

The one titled “Ubuntu” should be the same as your first Ubuntu option and most updated kernel. The “Windows” is the first option returned by “/etc/grub.d/30_os-prober”. Which should return a bootable Windows Partition. This still leaves all the original boot options underneath so you can still take advantage of selecting an older kernel or the recovery mode. It will also include any Windows Recovery partitions as well towards the very bottom.

Disclaimer: I have no idea what this will actually do out in the wild. I surely can’t account for every scenario but I’ve done MY best and tested with a couple of systems with success!

Note: Do not use this if you are doing more than just dual booting Ubuntu and Windows!

Here is what my partition tables look like on the computer I tested with today. The script worked perfectly on it. As well as another Windows 7 machine I tested on.

/etc/grub.d/05_custom :


#!/bin/bash

awk '/BEGIN\ \/etc\/grub\.d\/10_linux/,/END\ \/etc\/grub\.d\/10_linux/' /boot/grub/grub.cfg > /tmp/grub1.tmp
LINE1=`grep menuentry /tmp/grub1.tmp -n | cut -f1 -d: | head -n1`
LINE2=`grep } /tmp/grub1.tmp -x -n | cut -f1 -d: | head -n1`
echo 'menuentry "Ubuntu" {'
sed -n "${LINE1},${LINE2}p" /tmp/grub1.tmp | sed -n "2,${LINE2}p"

#check for NTFS partitions!
#This also means this script is only for XP, Vista, or Win 7. (Not tested with Vista and Win7 yet!)
chkntfs=`sfdisk -l 2> /dev/null | grep NTFS -n | cut -f1 -d:`

if [ -n "$chkntfs" ]; then 
#grub-mkconfig 2> /dev/null | awk '/BEGIN\ \/etc\/grub\.d\/30_os-prober/,/END\ \/etc\/grub\.d\/30_os-prober/' > /tmp/grub2.tmp
awk '/BEGIN\ \/etc\/grub\.d\/30_os-prober/,/END\ \/etc\/grub\.d\/30_os-prober/' /boot/grub/grub.cfg > /tmp/grub2.tmp
LINE1=`grep menuentry /tmp/grub2.tmp -n | cut -f1 -d: | head -n1`
LINE2=`grep } /tmp/grub2.tmp -x -n | cut -f1 -d: | head -n1`
echo 'menuentry "Windows" {'
sed -n "${LINE1},${LINE2}p" /tmp/grub2.tmp | sed -n "2,${LINE2}p"
else
echo "There were no NTFS partitions found!" >&2
fi

#entries must point somewhere or they don't show up.
#might as well be the partition that houses our kernel. 
#also, when its selected it just shows the menu again.
#which makes it a nice dummy file.

echo "menuentry \\" \\" {"
echo "	insmod ext2"
echo `cat /tmp/grub1.tmp | grep "set root" | head -n1`
echo "}"

echo "menuentry \\"Other boot options:\\" {"
echo "	insmod ext2"
echo `cat /tmp/grub1.tmp | grep "set root" | head -n1`
echo "}"

To create the file and mark it executable… Open Terminal (Applications > Accessories > Terminal)


sudo gedit /etc/grub.d/05_custom
*** PASTE THE ABOVE SCRIPT AND HIT SAVE ***
sudo chmod +x /etc/grub.d/05_custom
sudo update-grub

End result:

At this point you could make Windows default by editing /etc/default/grub and chaning the line:


GRUB_DEFAULT="Windows"

I welcome any and all suggestions on how to improve this script. I make no claim to be very good at BASH scripting but I needed this and couldn’t find any other solutions!