Created
October 8, 2016 18:26
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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