Creating a bootable Linux USB installer on MacOS
Estimated reading time: 3 minutes

Here is how I prepare a USB stick to be used to boot Linux installations.
-
Download an ISO from ubuntu.com or federaproject.org
-
In MacOS, convert the ISO to an image file.
Note
hdiutil convert -format UDRW -o $HOME/Downloads/file-name file-name.iso
- List all external storage devices plugged currently plugged in. Determine which is your USB device.
diskutil list external | grep -E '^/dev/disk[0-9]+\s'
- Erase the disk and format using the FAT32 format
diskutil eraseDisk FAT32 SETUP /dev/disk4
- Unmount the USB device
diskutil unmountDisk /dev/disk4
- Use “dd” to create the bootable USB from the image file created earlier
sudo dd if=file-name.dmg of=/dev/disk4 bs=1m
- Eject the USB device
diskutil eject /dev/disk4
With the general steps defined, let me put together a script that will automate the process
#!/usr/bin/env bash
set -Eeuo pipefail
# Create a temporary directory
TEMPDIR=$(mktemp -d)
# Define a cleanup function
cleanup_tmpdir() {
printf "Removing temporary files..." &> /dev/null
rm -rf "$TEMPDIR"
}
# sudo challenge function
function sudo-creds-challenge() {
if [[ $EUID -ne 0 ]]; then
sudo --reset-timestamp
if ! sudo --prompt "Elevate your shell by entering your password here:" true
then
printf "Unable to validate your sudo credentials. Exiting"
exit 1
fi
fi
}
# Trap signals to execute the cleanup function
trap cleanup_tmpdir EXIT
# Test input for an ISO file
if [ -z "$1" ]; then
printf "Please pass in a path to a local ISO file"
exit 1
fi
# Test for the existence of plutil on MacOS
if [ ! command -v plutil &> /dev/null OR ! command jq &> /dev/null ]; then
printf "Required commands plutil or jq is required on MacOS"
exit 1
fi
# Get a list of attached USB storage devices
devices=($(diskutil list -plist external physical | plutil -convert json -r -o - - | jq -r '.AllDisksAndPartitions[].DeviceIdentifier'))
if [ "${#devices[@]}" -gt "0" ]; then
PS3="Choose a USB storage device from the list above:"
select device in "${devices[@]}"; do
# printf "Selected device: $device"
# printf "Selected number: $REPLY"
[[ -n $device ]] && break || {
printf "== Invalid Option ==\n\n"
}
done
else
printf "\nA USB storage device has not been detected"
exit 0
fi
USB_DEVICE="/dev/${device}"
ISO_FULL_PATH=$1
ISO_BASE_FILE=$(basename -- $ISO_FULL_PATH)
sudo-creds-challenge
# Erase the USB storage device
printf "\nErase USB storage device ${USB_DEVICE}? (Y/N) "
read CHOICE
case $CHOICE in
[Yy])
printf "\nErasing disk ${USB_DEVICE}\n"
diskutil eraseDisk FAT32 SETUP $USB_DEVICE
;;
*)
printf "\nExiting script..\n"
diskutil eject $USB_DEVICE
exit 0
;;
esac
# Unmount the USB storage device
printf "\nUnmounting ${USB_DEVICE}\n"
diskutil unmountDisk $USB_DEVICE
# Convert the iso file to a disk image
DMG_FILE="${TEMPDIR}/$ISO_BASE_FILE%.*"
printf "\nConverting the ISO file to a DMG temp file in ${TEMPDIR}\n"
hdiutil convert -format UDRW -o $DMG_FILE $ISO_FULL_PATH
# Write the disk image to the USB storage device
printf "\nWriting disk image to the USB storage device\n"
sudo dd if="${DMG_FILE}.dmg" of=$USB_DEVICE bs=4m status=progress
if [ $? == 0 ]; then
printf "\nProcess completed successfully. Ejecting the USB device.\n"
else
printf "\nAn error occurred writing to the USB storage device.\n"
fi
diskutil eject $USB_DEVICE
For further instructions on how to use the script, please head over to my Gitlab repo.
Thanks