This repository has been archived by the owner on Feb 8, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathiso2usb
executable file
·277 lines (239 loc) · 8.03 KB
/
iso2usb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#!/bin/bash
##
# AUTHOR: Andy Savage <[email protected]>
# GITHUB: www.github.com/hongkongkiwi
# DESCRIPTION: This script is for converting ISO files and burning them to a USB drive
##
HELP="USAGE: iso2usb blah.iso [/dev/disk#]"
ISOPATH="$1"
DEVPATH="$2"
DEBUG="No" # Set to Yes to avoid non-destructive actions
# Check if a value exists in an array
# @param $1 mixed Needle
# @param $2 array Haystack
# @return Success (0) if value exists, Failure (1) otherwise
# Usage: in_array "$needle" "${haystack[@]}"
# See: http://fvue.nl/wiki/Bash:_Check_if_array_element_exists
in_array() {
local hay needle=$1
shift
for hay; do
[[ $hay == $needle ]] && return 0
done
return 1
}
## Check the user supplied a valid files
if [ "$ISOPATH" == "" -o ! -f "$ISOPATH" ]; then
echo "ERROR: ISO file not found. Aborting"
echo
echo "$HELP"
exit 1
fi
## If the user didn't pass a device to write to, we offer a selection
if [[ "$DEVPATH" == "" ]]; then
DEVICES=`diskutil list | grep "/dev"`
OPTIONS=()
OPTION_DEVICES=()
while read -r DEVICE; do
DEVICE=`echo "$DEVICE" | cut -d' ' -f1`
DISKUTIL_INFO=`diskutil info "$DEVICE"`
PROTOCOL=`echo "$DISKUTIL_INFO" | grep 'Protocol:' | tr -d ' ' | cut -d':' -f2`
DEVICE_LOCATION=`echo "$DISKUTIL_INFO" | grep 'Device Location:' | tr -d ' ' | cut -d':' -f2`
REMOVABLE_MEDIA=`echo "$DISKUTIL_INFO" | grep 'Removable Media:' | tr -d ' ' | cut -d':' -f2`
if [ "$PROTOCOL" == "USB" -a "$DEVICE_LOCATION" == "External" -a "$REMOVABLE_MEDIA" == "Yes" ]; then
DEVICE_SIZE=`echo "$DISKUTIL_INFO" | grep 'Total Size:' | tr -d ' ' | cut -d':' -f2 | cut -d'(' -f1`
DEVICE_NAME=`echo "$DISKUTIL_INFO" | grep "Device / Media Name:" | cut -d':' -f2 | sed -e 's/^[[:space:]]*//'`
OPTIONS+=("$DEVICE_NAME ($DEVICE_SIZE)")
OPTION_DEVICES+=("$DEVICE")
fi
done <<< "$DEVICES"
# Check if our devices list is empty
if [ ${#OPTIONS[@]} -eq 0 ]; then
echo "ERROR: Looks like there are no USB devices plugged in"
exit 0
fi
OPTIONS+=("Quit")
PS3='Please select USB device: '
select CHOICE in "${OPTIONS[@]}"; do
if [[ "$CHOICE" == "Quit" ]]; then
exit 0
elif [[ "$CHOICE" == "" ]]; then
echo "Invalid Selection"
elif [[ "$CHOICE" == "" ]]; then
exit 0
else
in_array "$CHOICE" "$OPTIONS"
DEVPATH=${OPTION_DEVICES[${?}]}
break
fi
done
fi
if [[ ! -b "$DEVPATH" ]]; then
echo "ERROR: Device not found. Aborting"
echo
echo "$HELP"
exit 1
fi
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
# This just does some cleanup if necessary
function ctrl_c() {
# Get rid of that pesky disk inserted is not readable error
NOTIFICATION_PID=`ps axww | grep -i "[u]ser[n]otification[c]enter" | awk '{print $1}'`
if [[ "$NOTIFICATION_PID" != "" ]]; then
kill "$NOTIFICATION_PID"
fi
if [[ "$CONVERTED" == "YES" && -f "$DMGPATH" ]]; then
rm "$DMGPATH"
fi
echo "ERROR: User Quit"
exit 255
}
#### Some Useful Variables ####
DEVINFO=`diskutil info "$DEVPATH" | grep 'Protocol' | tr -d ' ' | cut -d':' -f2`
DMGPATH=`mktemp -t 'iso2usb.XXXXXXXXXX'`
ISOFILENAME=$(basename "$ISOPATH")
ISOEXT="${ISOFILENAME##*.}"
ISONAME="${ISOFILENAME%.*}"
DISKNUMBER=`basename "$DEVPATH"`
#add an 'r' to the beginning of the device name
#rdisk or raw disks write much faster
RDISKPATH="/dev/r$DISKNUMBER"
DISKSIZE=`diskutil info "$DEVPATH" | grep 'Total Size:' | tr -d ' ' | cut -d':' -f2 | cut -d'(' -f1`
DISKNAME=`diskutil info "$DEVPATH" | grep "Device / Media Name:" | cut -d':' -f2 | sed -e 's/^[[:space:]]*//'`
DDBSSIZE="1M"
PV_BIN=`which pv`
#### DO SOME SANITY CHECKING ###
PLATFORM='unknown'
UNAMESTR=`uname`
if [[ "$UNAMESTR" == 'Linux' ]]; then
PLATFORM='linux'
elif [[ "$UNAMESTR" == 'FreeBSD' ]]; then
PLATFORM='freebsd'
elif [[ "$UNAMESTR" == "Darwin" ]]; then
PLATFORM="mac"
fi
if [[ "$PLATFORM" != "mac" ]]; then
echo "ERROR: This script is designed only to run on Mac OSX"
echo " if you have some time, please help to improve it"
echo " and submit a pull request. I would appreciate it!"
fi
if [[ "$PV_BIN" == "" ]]; then
echo "WARNING: pv is not installed. I recommend you install it to get better transfer progress info"
echo " if you have homebrew you can use 'brew install pv'"
fi
#check is script has been run as root /sudo
if [[ $UID != 0 ]]; then
echo "Looks like your not running the script using sudo, we will do it for you"
RESULT=`sudo -p "Please enter your user password so we can gain root privileges: " echo > /dev/null`
if [[ $? != 0 ]]; then
echo "ERROR: We were unable to get root privileges!"
echo " try running the script with sudo"
exit 1
fi
fi
if [[ ! -f "$ISOPATH" ]]; then
echo "ERROR: ISO not found."
echo "$HELP"
exit 1
fi
if [[ `echo $ISOEXT | tr '[:upper:]' '[:lower:]'` != 'dmg' && `echo $ISOEXT | tr '[:upper:]' '[:lower:]'` != 'iso' ]]; then
echo "ERROR: Accepted input ISO types are .iso or .dmg, anything else is not supported"
exit 1
fi
#check if device is USB. Exit if device is not USB.
if [[ $DEVINFO != "USB" ]]; then
echo "Non-USB device specified. This is dangerous and I assume a mistake."
echo "Aborting."
exit 1
fi
echo "Are you sure you want to write \"$ISONAME.$ISOEXT\" to \"$DISKNAME\" ($DISKSIZE)?"
read -p "WARNING: This is a destructive action! Proceed? (y/n)? " -n 1 -r
echo # (optional) move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "ERROR: User Quit"
exit 1
fi
if [[ "$DEBUG" == "YES" ]]; then
echo "WARNING: Running in Debug mode! We won't actually do any destructive actions"
fi
if [[ `echo $ISOEXT | tr '[:upper:]' '[:lower:]'` == 'dmg' ]]; then
echo "-> ISO file is actually a DMG file, skipping convert"
DMGPATH="$ISOPATH"
else
echo "-> Converting ISO to DMG file..."
#convert the ISO to Mac format
if [[ "$DEBUG" == "YES" ]]; then
echo "hdiutil convert -format UDRW -o $DMGPATH $ISOPATH"
fi
if [[ -f "$DMGPATH" ]]; then
rm "$DMGPATH"
fi
RESULT=`hdiutil convert -format UDRW -o "$DMGPATH" "$ISOPATH"`
DMGPATH="$DMGPATH.dmg"
#change the ownership of the new file to match the owner of the
#current directory
OWNER=$(ls -dl . | cut -d' ' -f3)
GROUP=$(ls -dl . | cut -d' ' -f4)
chown ${OWNER}:${GROUP} "$DMGPATH"
CONVERTED="YES"
fi
# Unmount the device target device
if [[ $(mount | grep $DEVPATH) ]]; then
RESULT=`diskutil unmountDisk $DEVPATH`
echo "-> Unmounted disk $DEVPATH"
sleep 2
if [[ $(mount | grep $DEVPATH) ]]; then
echo "ERROR: Unable to unmount target device."
echo "Aborting."
exit 1
fi
fi
echo "-> Writing DMG file to device. This may take a while..."
#start the image writing process in the background
if [[ "$PV_BIN" == "" ]]; then
if [[ "$DEBUG" == "YES" ]]; then
echo "sudo dd if=\"${DMGPATH}\" of=\"${RDISKPATH}\" bs=${DDBSSIZE} &"
else
sudo dd if="${DMGPATH}" of="${RDISKPATH}" bs="${DDBSSIZE}" &
fi
# This is the awkward way of getting dd progress
PID=$(ps | grep dd | grep -v grep)
PID=$(echo $PID | cut -d' ' -f1)
while [[ $(ps | grep $PID | grep -v grep) ]]
do
kill -INFO $PID
sleep 10
done
else
# Progress using pv is much more interesting
DMGSIZE=`ls -nl "${DMGPATH}" | awk '{print $5}'`
if [[ "$DEBUG" == "YES" ]]; then
echo "dd if=\"${DMGPATH}\" 2> /dev/null | pv --size ${DMGSIZE} -e -N 'Burning USB Drive' | sudo dd of=\"${RDISKPATH}\" bs=\"${DDBSSIZE}\" >/dev/null 2>&1"
else
dd if="${DMGPATH}" | pv --size ${DMGSIZE} -e -N 'Burning USB Drive' | sudo dd of="${RDISKPATH}" bs="${DDBSSIZE}" >/dev/null 2>&1
fi
fi
# Get rid of that pesky disk inserted is not readable error
NOTIFICATION_PID=`ps axww | grep -i "[u]ser[n]otification[c]enter" | awk '{print $1}'`
if [[ "$NOTIFICATION_PID" != "" ]]; then
sudo kill "$NOTIFICATION_PID"
fi
DISK_IS_MOUNTED=`diskutil list | grep "$DEVPATH"`
if [[ "$DISK_IS_MOUNTED" == "$DEVPATH" ]]; then
# Eject the DISK
RESULT=`diskutil eject "$DEVPATH"`
echo "-> Finished. Disk is Ejected and is safe to remove."
fi
# Clear up converted DMG file if necessary
if [[ "$CONVERTED" == "YES" && -f "$DMGPATH" ]]; then
if [[ "$DEBUG" != "YES" ]]; then
rm "$DMGPATH"
fi
echo "-> Cleaned up temp dmg file"
fi
echo
echo "Note: If you want to use the disk now, please unplug and plug back in"
echo
echo "Have a nice day :-)"
exit 0