Skip to content

Instantly share code, notes, and snippets.

@glennzw
Created August 19, 2014 02:09
Show Gist options
  • Save glennzw/f946a6d25416ca19c80f to your computer and use it in GitHub Desktop.
Save glennzw/f946a6d25416ca19c80f to your computer and use it in GitHub Desktop.
Script to write to multiple SD cards simultaneously from OSX
#!/bin/bash
# Write an image to multiple SD cards at the same time
# Supply: image to be written, comma separated list of devices
# @glennzw
#set -e
echo -en " +++ Glenn's multi SD writer. Use with care. @glennzw +++\n\n"
BS=1m
OIFS=$IFS;
IFS=",";
IMG=$1
DEVs=$2
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <image> </dev/rdiskX>[,</dev/rdiskY>,</dev/rdiskZ>,</dev/rdiskN>]"
echo "Note : Using /dev/rdiskX instead of /dev/diskX increases performance dramatically on OSX (and other BSDs)"
exit
fi
if [ ! -f $IMG ]; then
echo "File not found! ($IMG)"
exit
fi
FILESIZE=$(ls -l $IMG | awk '{print $5}') #Bytes
FILESIZE=$(echo $FILESIZE| awk '{ foo = $1 / 1024 / 1024 ; print foo }') #mergerbertz
echo "[+] Going to write $IMG ($FILESIZE MB) to the following devices:"
for dev in $DEVs
do
sz=$(diskutil info $dev | grep "Total Size" | cut -d ":" -f 2 | tr -d ' ' | cut -d "(" -f 1)
fs=$(diskutil info $dev | grep "File System Personality" | cut -d ":" -f 2 | sed 's/^ *//' | cut -d "(" -f 1)
if [[ -z "$sz" ]]; then echo "[!] Cannot read $dev. Exiting.";exit; fi
if [[ -z "$fs" ]]; then fs="No FS";fi
echo " $dev ($sz, $fs)"
done
echo -e "\n\x1B[5mWARNING:\x1B[25m Double check the above."
read -p "Do you want to continue? [y/N] " prompt
if [[ "$prompt" != "y" ]]; then echo "Exiting!";exit; fi
echo " [+] Here we go!"
PIDS=()
for dev in $DEVs
do
diskutil unmount $dev &> /dev/null
diskutil unmountDisk $dev &> /dev/null
echo " Writing to $dev..."
dd if=$IMG of=$dev bs=$BS &> /tmp/dd-${dev##*/}.txt &
PIDS+=($!)
done
sleep 2
failed=0
for pid in "${PIDS[@]}"
do
if ! kill -0 $pid &> /dev/null; then ((failed++)); fi
done
if [ $failed -gt 0 ]; then
echo "[E] Out of ${#PIDS[@]} disk writes started, $failed have failed :-( Exiting."
exit
fi
clear
while true
do
killall -INFO dd &> /dev/null
if [[ $? -ne 0 ]]; then echo "All dd processes have ended. Check /tmp/<diskN>.txt for logs. Exiting.";exit; fi
#Check the log file for each dd
for dev in $DEVs
do
fl=/tmp/dd-${dev##*/}.txt
mb=$(tail -n 1 $fl| cut -d " " -f 1 | awk '{ foo = $1 / 1024 / 1024 ; print foo }') #total mb
sp=$(tail -n 1 $fl | cut -d " " -f 7 | tr -d '(' | awk '{ foo = $1 / 1024 / 1024 ; print foo }') #mb/sec
echo " ${dev##*/}: $mb MB of $FILESIZE MB @ $sp mb/sec "
done
sleep 2
clear
done
IFS=$OIFS;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment