Skip to content

Instantly share code, notes, and snippets.

@xomachine
Created October 8, 2016 18:26
Show Gist options
  • Save xomachine/0d3eebc1f13b2e6a4aa1c063632bfae2 to your computer and use it in GitHub Desktop.
Save xomachine/0d3eebc1f13b2e6a4aa1c063632bfae2 to your computer and use it in GitHub Desktop.
The script for making your usb flash drive bootable with linux isos without lossing data.
#!/bin/bash
set -e
show_help () {
cat <<EOF
The script for making multiboot linux live flashes.
Arguments:
-b <path> set path to the boot directory on the flash drive
-i <path to drive> install loader to the suplied flash drive
-a <path to iso> add iso to multiboot flash
-h show this help message
EOF
}
get_value() {
local FIRSTWORDS=$(echo -e "$1" | grep -io "$2")
if [ -z "$FIRSTWORDS" ]
then
return
fi
echo -e "$1" | sed -n "s/[ \\t]*$FIRSTWORDS[ \\t]*//gp"
}
unmount() {
echo -n "Unmounting ISO file..."
sudo umount $1
rm -r $1
echo "done"
}
convert_syslinux () {
local OLD_ISO_NAME=""
local NEW_ISO_NAME=""
local ISO_ROOT=""
local FLASH_ISO_ROOT=""
while [ $# -gt 1 ]
do
case $1 in
-oldisoname)
OLD_ISO_NAME="$2"
shift
;;
-newisoname)
NEW_ISO_NAME="$2"
shift
;;
-isoroot)
ISO_ROOT="$2"
shift
;;
-flashisoroot)
FLASH_ISO_ROOT="$2"
shift
;;
*)
echo "Unknown option $1" >&2
exit 1
;;
esac
shift
done
local kernel=""
local initrd=""
local append=""
local label=""
local pre_label=""
local name=""
local line=""
read line
local the_end=1
#echo "---------- FILE STARTS -----------" >&2
while test $the_end
do
read line
the_end=$?
append+=$(get_value "$line" '^[[:blank:]]*append' )
kernel+=$(get_value "$line" '^[[:blank:]]*kernel' )
name+=$( get_value "$line" '^[[:blank:]]*menu \+label')
initrd+=$(get_value "$line" '^[[:blank:]]*initrd')
label+=$( get_value "$line" '^[[:blank:]]*label')
#echo "pre =$pre_label" >&2
#echo "label =$label" >&2
#echo "append=$append" >&2
#echo "kernel=$kernel" >&2
if [ 1 -eq $the_end -o ! -z "$label" ]
then
if [ ! -z "$pre_label" ]
then
echo "menuentry \"$pre_label $name\" {"
if [ -e "$ISO_ROOT/$kernel" -a ! -z "$kernel" ]
then
IFS=$' '
local append_fixed=""
for a in $append
do
local key=$(echo $a | sed -e 's/^\(.*\)=.*$/\1/')
local val=$(echo $a | sed -n 's/^.*=\(.*\)$/\1/p')
local newval=""
if [ -z "$val" ]
then
newval=""
elif [ "$OLD_ISO_NAME" = "$val" ]
then
newval="$NEW_ISO_NAME"
elif [ -e "$ISO_ROOT/$val" ]
then
newval="/$FLASH_ISO_ROOT/$val"
elif [ "$key" = "initrd" ]
then
if [ ! -z "$initrd" ]
then
initrd+=","
fi
initrd+="$val"
continue
else
newval="$val"
fi
append_fixed+=" $key"
if [ ! -z "$newval" ]
then
append_fixed+="=$newval"
fi
done
echo "linux /$FLASH_ISO_ROOT/$kernel $append_fixed"
fi
if [ ! -z "$initrd" ]
then
local fixed_initrd=$(echo " $initrd" | sed -e 's/,/ /g' | sed -e "s% /% /$FLASH_ISO_ROOT/%g")
echo "initrd $fixed_initrd"
fi
echo "}"
fi
pre_label="$label"
label=""
kernel=""
append=""
initrd=""
name=""
fi
done
}
while [ $# -gt 1 ]
do
case $1 in
-b)# Loader directory path
BOOT_DIR="$2"
shift
;;
-i)# Install loader
BOOT_DRIVE="$2"
shift
;;
-a)# Add iso
ADD_ISO="$2"
shift
;;
-h)# Help
show_help
exit 0
;;
*)
echo "Unknown option $1"
show_help
exit 1
;;
esac
shift
done
IFS=$'\n'
if [ -z "$BOOT_DIR" ]
then
echo "You need to specify a boot directory path on your flash drive, where loader files (have been/will be) installed!"
show_help
exit 1
fi
set +e
BOOT_DEV=$(df --output="source" "$BOOT_DIR" | grep '/dev')
GRUB_CONFIG="$BOOT_DIR/grub/grub.cfg"
#SYSLINUX_CONFIG="$BOOT_DIR/syslinux.cfg"
ISO_DIR="$BOOT_DIR/iso"
MOUNTED_FLASH=$(df --output="target" "$BOOT_DIR" | grep '/')
set -e
if [ ! -z "$BOOT_DRIVE" ]
then
if [ ! -b "$BOOT_DRIVE" ]
then
echo "$BOOT_DRIVE is not a block device!"
exit 1
fi
grub-install --boot-directory="$BOOT_DIR" "$BOOT_DRIVE"
#syslinux --install --directory "$BOOT_DIR" "$BOOT_DEV"
fi
mkdir -p $ISO_DIR
if [ ! -z "$ADD_ISO" ]
then
if [ ! -e "$ADD_ISO" ]
then
echo "File $ADD_ISO does not exist!"
exit 1
fi
ISO_NAME=$(basename $ADD_ISO)
MOUNTED_DIR=$(mktemp -d)
THIS_ISO_DIR="$ISO_DIR/$ISO_NAME"
echo "Mounting iso file..."
mkdir -p "$MOUNTED_DIR"
sudo mount -o ro "$ADD_ISO" "$MOUNTED_DIR"
echo "Mounted!"
ENTRIES=""
ISO_CHROOT=$(realpath --relative-to=$MOUNTED_FLASH $THIS_ISO_DIR)
NEWNAME=$(lsblk -n --output=LABEL $BOOT_DEV)
LOOP_DEV=$(df --output="source" "$MOUNTED_DIR" | grep '/dev')
OLDNAME=$(lsblk -n --output=LABEL $LOOP_DEV)
if [ -z "$NEWNAME" -o -z "$OLDNAME" ]
then
echo "$NEWNAME old=$OLDNAME"
echo "Error! Flash drives filesystem must have a label!" >&2
unmount $MOUNTED_DIR
exit 1
fi
echo -n "Searching for bootloader in ISO file..."
CONFIGS=$(find "$MOUNTED_DIR" -name "isolinux.cfg" -or -name "syslinux.cfg")
if [ ! -z "$CONFIGS" ]
then
mkdir -p "$THIS_ISO_DIR"
echo "found ISOLINUX"
echo -n "Generating entries..."
for isoconfig in $CONFIGS
do
configpath=$(realpath --relative-to=$MOUNTED_DIR $isoconfig)
mkdir -p $THIS_ISO_DIR/$(dirname $configpath)
# cp $isoconfig $THIS_ISO_DIR/$configpath.fix
# sed -i "s%\\([^a-z0-9_-]\\)/%\\1/$ISO_CHROOT/%g" $THIS_ISO_DIR/$configpath.fix
#cat "$isoconfig" | convert_syslinux -isoroot "$MOUNTED_DIR" -flashisoroot "$ISO_CHROOT" -oldisoname "$OLDNAME" -newisoname "$NEWNAME"
FIXED_CONFIG=$(cat "$isoconfig" | convert_syslinux -isoroot "$MOUNTED_DIR" -flashisoroot "$ISO_CHROOT" -oldisoname "$OLDNAME" -newisoname "$NEWNAME" | cat)
ENTRIES+="
submenu \"$configpath\"
{
$FIXED_CONFIG
}
"
# ENTRIES+="
#LABEL
# MENU LABEL \"$configpath\"
# CONFIG $ISO_CHROOT/$configpath.fix
#
#"
done
echo "done"
else
echo "not found"
fi
if [ ! -z "$ENTRIES" ]
then
echo -n "Copying content of iso file to the flash drive..."
cp -Ru --target-directory="$THIS_ISO_DIR" $MOUNTED_DIR/*
echo "done"
cat > $THIS_ISO_DIR/subconfig.cfg << EOF
submenu "$ISO_NAME" {
$ENTRIES
}
EOF
fi
unmount $MOUNTED_DIR
fi
echo -n "Regenerating loader config..."
#SYSLINUX_INCLUDES=""
GRUB_INCLUDES=""
for iso in $(ls $ISO_DIR)
do
if [ ! -e "$ISO_DIR/$iso/subconfig.cfg" ]
then
echo ""
echo "skipping $iso"
continue
fi
relpath=$(realpath --relative-to="$MOUNTED_FLASH" "$ISO_DIR/$iso")
#if [ $(grep -c 'GRUB' $ISO_DIR/$iso/subconfig.cfg) -gt 0 ]
#then
GRUB_INCLUDES+="
menuentry \"$(basename $iso)\" {
configfile (\$root)/$relpath/subconfig.cfg
}
"
# else
# SYSLINUX_INCLUDES+="
#LABEL
# MENU LABEL \"$(basename $iso)\"
# CONFIG $relpath/subconfig.cfg
#"
# fi
done
FSID=$(lsblk --output="UUID" -n "$BOOT_DEV")
cat > $GRUB_CONFIG << EOF
search --fs_uuid $FSID --set root
set gfxmode=auto
set gfxpayload=auto
insmod vbe
insmod gfxterm
terminal_output gfxterm
loadfont unicode
set lang=ru_RU
## ISO FILES ##
#menuentry "Syslinux based ISOs" {
# chainloader (\$root)+1
#}
$GRUB_INCLUDES
EOF
#cat > $SYSLINUX_CONFIG << EOF
#$SYSLINUX_INCLUDES
#EOF
echo "done"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment