For my work I'm preparing a live USB with Clonezilla. It runs a custom bash script to clone disks. This USB is going to be cloned to several other USBs so they can be used in multiple machines.
It's not possible to run Clonezilla to RAM since the image to clone (22G) is in the USB.
I want to replicate, in my script, the standard behavior of live Linux distributions installer, that ask to remove the USB medium and then press enter to reboot the machine.
Example script using eject, but this doesn't seem right:
eject /dev/sdb read -r -p 'Remove USB and press Enter' # not executed since the USB is no longer plugged reboot I want to be very sure that the USB(s) are removed safely, since they are from work, they are many, and of course taking the risk of ruining them is not an option.
What would be the best and safest way to do this?
Now, why so much effort for a seemingly trivial thing? The USBs are going to be deployed to hundreds of machines. All that can be automated is needed to gain time and avoid errors. The users need to check the cloning worked, hence the reboot. But if the USB is still plugged, the machine will boot it instead of the local OS.
This question is related but I understand it doesn't apply to a live system.
This is the script that seems to do this, from a Lubuntu that I got unsquashing the filesystem.squashfs file from the ISO. I'm still trying to understand it, any help appreciated.
#! /bin/sh # Author: Mathieu Trudel-Lapierre <[email protected]> # Tollef Fog Heen <[email protected]> # Marco Amadori <[email protected]> # PATH=/usr/sbin:/usr/bin:/sbin:/bin NAME=casper SCRIPTNAME=/etc/init.d/${NAME} DO_SNAPSHOT=/sbin/${NAME}-snapshot # Exit if system was not booted by casper [ -f /run/.casper-boot ] || exit 0 # Exit if the system was booted from an ISO image rather than a physical CD grep -qs find_iso= /proc/cmdline && exit 0 # Read configuration variable file if it is present [ -r /etc/$NAME.conf ] && . /etc/$NAME.conf # Try to cache everything we're likely to need after ejecting. This # is fragile and simple-minded, but our options are limited. cache_path() { path="$1" if [ -d "$path" ]; then for f in $(find "$path" -type f); do cache_path "$f" done elif [ -f "$path" ] && [ ! -L "$path" ]; then if [ -x "$path" ]; then if file -L "$path" | grep -q 'dynamically linked'; then for lib in $(ldd "$path" | awk '{ print $3 }'); do cache_path "$lib" done fi fi echo -n >> "$path" fi } do_stop () { logger -t ${NAME} "resyncing snapshots and caching reboot files..." if [ ! -z "${ROOTSNAP}" ]; then $DO_SNAPSHOT --resync-string="${ROOTSNAP}" fi if [ ! -z "${HOMESNAP}" ]; then $DO_SNAPSHOT --resync-string="${HOMESNAP}" fi # check for netboot if [ ! -z "${NETBOOT}" ] || grep -qs netboot /proc/cmdline || grep -qsi root=/dev/nfs /proc/cmdline || grep -qsi root=/dev/cifs /proc/cmdline ; then return 0 fi # Don't prompt to eject the SD card on Babbage board, where we reuse it # as a quasi-boot-floppy. Technically this uses a bit of ubiquity # (archdetect), but since this is mostly only relevant for # installations, who cares ... if type archdetect >/dev/null 2>&1; then subarch="$(archdetect)" case $subarch in arm*/imx51) return 0 ;; esac fi prompt=1 if grep -qs noprompt /proc/cmdline || [ -e /run/casper-no-prompt ]; then prompt= fi for path in $(which halt) $(which reboot) /bin/chvt /etc/rc?.d /etc/default $(which stty) /bin/plymouth /lib/plymouth /lib/*/plymouth /lib/systemd /etc/systemd /lib/*/libnss_files* /etc/nsswitch.conf /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf /usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf /usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf /etc/fonts/fonts.conf /etc/fonts/conf.d/60-latin.conf; do cache_path "$path" done device="$(grep " /cdrom " /proc/mounts | cut -d' ' -f1)" || device= # If /cdrom isn't mounted, don't try to eject it if [ -z "$device" ]; then return 0 fi # If the device exists but can't be found in /sys/block, it's most likely a partition # so unmount it (lazy mode) and sync if [ -b "$device" ] && [ ! -f "/sys/block/$(basename $device)/removable" ]; then umount -l $device >/dev/null 2>&1 sync # from now on operate on the partition's block device device=/dev/$(basename "$(readlink -f /sys/class/block/$(basename $device)/..)") fi # If we're still there, then we're probably a cdrom or other media # ship the eject if the kernel says the media isn't removable if [ "$(cat /sys/block/$(basename $device)/removable)" = "0" ]; then return 0 fi # XXX - i18n MSG="Please remove the installation medium, then press ENTER: " MSG_FALLBACK="Please remove the installation medium, then reboot." if [ "$prompt" ]; then if [ -x /bin/plymouth ] && plymouth --ping; then chvt 63 plymouth message --text="$MSG" clear > /dev/tty1 echo $MSG_FALLBACK > /dev/tty1 else stty sane < /dev/console echo $MSG > /dev/console fi fi eject -p -m $device >/dev/null 2>&1 [ "$prompt" ] || return 0 if [ -x /bin/plymouth ] && plymouth --ping; then plymouth watch-keystroke > /dev/null else read x < /dev/console fi } do_stop
toram, which means that you can unmount and unplug the USB drive and still have the live system running.