-
-
Save dakanji/1ab88389c7aaffe4b156db9741687b3a to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash | |
# Install_USB_Maker.sh | |
# Copyright (c) 2020 - 2025 Dayo Akanji | |
# - [email protected] | |
# Portions Copyright (c) Jeff Geerling | |
# - https://github.com/geerlingguy/macos-virtualbox-vm/blob/master/LICENSE | |
# | |
# MIT License | |
# Derived from: | |
# * https://apple.stackexchange.com/a/389830 | |
# * https://github.com/geerlingguy/macos-virtualbox-vm/blob/master/prepare-iso.sh | |
# | |
# 1. Download Lion to Monterey (Excluding Mavericks) | |
# * From : https://support.apple.com/HT211683 (Lion to Sierra or Links to App Store) | |
# * : https://github.com/corpnewt/gibMacOS (High Sierra to Monterey) | |
# 2. Use Disk Utility to format a USB stick partition: | |
# * Name : USB_Maker | |
# * Size : Easiest to assume 16 GB but see details below: | |
# * : 08 GB (Min) For Lion to Sierra (if via Install DMG) | |
# * : 16 GB (Min) For Yosemite to Sierra (if via Installer App) | |
# * : 16 GB (Min) For High Sierra to Monterey (Always Installer App) | |
# * Format : Mac OS Extended Journaled (HFS+) | |
# 3. Make the downloaded "Install" package available to this script: | |
# * For Lion to Sierra: | |
# * Run the the downloaded "Install DMG" file to mount it | |
# * For High Sierra to Monterey | |
# * or Yosemite to Sierra if using "Install App": | |
# * Place the install app in the 'Applications' folder | |
# * This can be done manually or by running the downloaded package | |
# * Placing manually in the folder containing this script also works | |
# * Installer Apps in the folder containing this script take precedence | |
# 4. Make this script executable and run it in Terminal: | |
# * Unzip the package to show the script file in Finder | |
# * Type "chmod +x" without quotes, add a space, then drag the script file from Finder unto Terminal and press "Enter" | |
# * Type "sh" without quotes, add a space, then drag the script file from Finder unto Terminal again and press "Enter" | |
# 5. Install Mac OS with the USB Installer once done | |
# * Name : Install_{{MAC_OS_NAME}} | |
## CUSTOM COLOURS ## | |
msg_status() { | |
printf "\033[0;35m$1\033[0m\n" | |
} | |
msg_info() { | |
printf "\033[0;33m$1\033[0m\n" | |
} | |
msg_error() { | |
printf "\033[0;31m$1\033[0m\n" | |
} | |
enter_msg() { | |
one=${1:-SkipNb} | |
two=${2:-SkipAs} | |
if [ "${two}" != 'WithAs' ] ; then | |
if [ "${one}" != 'WithNb' ] ; then | |
msg_info ' Type password and press "Enter" if prompted' | |
else | |
msg_info 'NB: Type password and press "Enter" if prompted' | |
fi | |
else | |
if [ "${one}" != 'WithNb' ] ; then | |
msg_info ' Type password as prompted and press "Enter"' | |
else | |
msg_info 'NB: Type password as prompted and press "Enter"' | |
fi | |
fi | |
msg_info ' Your password is not displayed while typing' | |
} | |
chill_msg() { | |
msg_info 'NB: Patience ... This takes a while to complete' | |
enter_msg ; | |
} | |
# createISO by Jeff Geerling as modified by Dayo Akanji | |
# This function creates the ISO image. | |
# Inputs: $1 = The name of the installer - located in Applications folder or local folder/PATH. | |
function createISO() { | |
local error | |
local isoName | |
local InstallAppVol | |
local SparseImageFile | |
local installerAppName | |
local InstallAppBaseSystem | |
if [ -e "${SCRIPT_DIR}/${1}" ] ; then | |
installerAppName="${SCRIPT_DIR}/${1}" | |
elif [ -e "/Applications/${1}" ] ; then | |
installerAppName="/Applications/${1}" | |
else | |
echo && echo | |
msg_info 'ERROR!!' | |
msg_error 'Could Not Find Installer App' | |
runExit 'Error' ; | |
fi | |
# Remove Spaces in 'INSTALL_NAME' and use as ISO name | |
isoName=$( echo "${INSTALL_NAME}" | sed 's/ //g' ) | |
error=0 | |
SparseImageFile="${INSTALL_TEMP}/${isoName}.sparseimage" | |
InstallAppVol='/Volumes/install_app' | |
InstallAppBaseSystem="${installerAppName}/Contents/SharedSupport/BaseSystem" | |
sudo -v | |
msg_info "Using Installer App:- '${installerAppName}'" | |
msg_status 'STEP 01 of 13: Create a Blank 16GB Single Partition Apple Partition Map ISO Image' | |
# Create INSTALL_TEMP folder | |
mkdir -p "${INSTALL_TEMP}" | |
# Just in case - delete any previous sparseimage | |
[ -e "${SparseImageFile}" ] && rm -f "${SparseImageFile}" | |
# increased size to 16G - 8G is too small for Catalina | |
hdiutil create -o "${INSTALL_TEMP}/${isoName}" -size 16g -layout SPUD -fs HFS+J -type SPARSE | |
sudo -v && echo | |
msg_status 'STEP 02 of 13: Mount Installer Image' | |
if [ "${isoName}" == 'Monterey' ] || [ "${isoName}" == 'BigSur' ] ; then | |
hdiutil attach "${SparseImageFile}" -noverify -nobrowse -mountpoint "${InstallAppVol}" | |
elif [ -e "${installerAppName}" ] ; then | |
hdiutil attach "${installerAppName}/Contents/SharedSupport/InstallESD.dmg" -noverify -nobrowse -mountpoint "${InstallAppVol}" | |
error=$? | |
else | |
error=999 | |
fi | |
if [ ${error} -ne 0 ] ; then | |
echo && echo | |
msg_info 'ERROR!!' | |
msg_error "Failed to mount the InstallESD.dmg from the installer at ${installerAppName}" | |
msg_error "Exiting on 'Error Code: ${error}'" | |
runExit 'Error' ; | |
fi | |
sudo -v && echo | |
msg_status 'STEP 03 of 13: Mount Sparse Bundle for Package Addition' | |
if [ "${isoName}" == 'Monterey' ] || [ "${isoName}" == 'BigSur' ] ; then | |
echo "N/A ... Skipped for ${INSTALL_NAME}" | |
else | |
hdiutil attach "${SparseImageFile}" -noverify -nobrowse -mountpoint '/Volumes/install_build' | |
fi | |
sudo -v && echo | |
msg_status 'STEP 04 of 13: Restore Base System into '${isoName}' ISO Image' | |
if [ "${isoName}" == 'Monterey' ] || [ "${isoName}" == 'BigSur' ] ; then | |
echo "N/A ... Skipped for ${INSTALL_NAME}" | |
elif [ "${isoName}" == 'Catalina' ] || [ "${isoName}" == 'Mojave' ] || [ "${isoName}" == 'HighSierra' ] ; then | |
# Note by Jeff Geerling: | |
# The asr command below returns an error. | |
# I disabled SIP and the error still occurs. | |
# This was reported in Issue #73 for Mojave. | |
# Added '|| true' to prevent the script from exiting. | |
# The steps that follow still seem to work for Catalina. | |
sudo asr restore -source "${InstallAppBaseSystem}.dmg" -target '/Volumes/install_build' -noprompt -noverify -erase || true | |
else | |
sudo asr restore -source "${InstallAppVol}/BaseSystem.dmg" -target '/Volumes/install_build' -noprompt -noverify -erase | |
fi | |
sudo -v && echo | |
msg_status 'STEP 05 of 13: Remove Package Link and Replace with Actual Files' | |
chill_msg ; | |
if [ "${isoName}" == 'Monterey' ] || [ "${isoName}" == 'BigSur' ] ; then | |
echo "N/A ... Skipped for ${INSTALL_NAME}" | |
elif [ "${isoName}" == 'Catalina' ] || [ "${isoName}" == 'Mojave' ] || [ "${isoName}" == 'HighSierra' ] ; then | |
ditto -V "${InstallAppVol}/Packages" "${VOL_BASE_DIR}/System/Installation/" | |
else | |
rm -v "${VOL_BASE_DIR}/System/Installation/Packages" | |
cp -rpv "${InstallAppVol}/Packages" "${VOL_BASE_DIR}/System/Installation/" | |
fi | |
sudo -v && echo | |
msg_status "STEP 06 of 13: Copy '${INSTALL_TARGET}' Dependencies" | |
enter_msg 'WithNb' ; | |
sudo -v | |
if [ "${isoName}" == 'Monterey' ] || [ "${isoName}" == 'BigSur' ] ; then | |
CurrentMacOS=$(sw_vers -productVersion | cut -f 1 -d .) | |
if [ "${CurrentMacOS}" -gt 10 ] ; then | |
PostSierra='True' | |
elif [ "${CurrentMacOS}" -eq 10 ] ; then | |
CurrentMacOS=$(sw_vers -productVersion | cut -f 2 -d .) | |
if [ "${CurrentMacOS}" -gt 12 ] ; then | |
PostSierra='True' | |
else | |
PostSierra='False' | |
fi | |
else | |
echo && echo | |
msg_info 'ERROR!!' | |
msg_error 'Invalid Mac OS Version' | |
runExit 'Error' ; | |
fi | |
if [ "${PostSierra}" == 'True' ] ; then | |
sudo "${installerAppName}/Contents/Resources/createinstallmedia" --volume "${InstallAppVol}" --nointeraction | |
else | |
sudo "${installerAppName}/Contents/Resources/createinstallmedia" --volume "${InstallAppVol}" --applicationpath "${installerAppName}" | |
fi | |
elif [ "${isoName}" == 'Catalina' ] || [ "${isoName}" == 'Mojave' ] || [ "${isoName}" == 'HighSierra' ] ; then | |
ditto -V "${InstallAppBaseSystem}.chunklist" "${VOL_BASE_SYS}.chunklist" | |
ditto -V "${InstallAppBaseSystem}.dmg" "${VOL_BASE_SYS}.dmg" | |
else | |
cp -rpv "${InstallAppVol}/BaseSystem.chunklist" "${VOL_BASE_SYS}.chunklist" | |
cp -rpv "${InstallAppVol}/BaseSystem.dmg" "${VOL_BASE_SYS}.dmg" | |
fi | |
sudo -v && echo | |
msg_status 'STEP 07 of 13: Unmount Installer Image' | |
if [ "${isoName}" == 'Monterey' ] || [ "${isoName}" == 'BigSur' ] ; then | |
hdiutil detach "/Volumes/Install macOS ${INSTALL_NAME}" -force # NOTE: force because "Resource busy" | |
else | |
hdiutil detach "${InstallAppVol}" | |
fi | |
sudo -v && echo | |
msg_status 'STEP 08 of 13: Unmount Sparse Bundle' | |
if [ "${isoName}" == 'Monterey' ] || [ "${isoName}" == 'BigSur' ] ; then | |
echo "N/A ... Skipped for ${INSTALL_NAME}" | |
else | |
hdiutil detach "${VOL_BASE_DIR}/" | |
fi | |
sudo -v && echo | |
msg_status "STEP 09 of 13: Resize '${isoName}' Sparse Bundle to Remove Free Space" | |
hdiutil resize -size `hdiutil resize -limits "${SparseImageFile}" | tail -n 1 | awk '{ print $1 }'`b "${SparseImageFile}" | |
echo "Resized '${isoName}' Sparse Bundle" | |
sudo -v && echo | |
msg_status "STEP 10 of 13: Convert '${isoName}' Sparse Bundle to ISO/CD Master" | |
chill_msg ; | |
hdiutil convert "${SparseImageFile}" -format UDTO -o "${INSTALL_TEMP}/${isoName}" | |
sudo rm -vf "${SparseImageFile}" | |
sudo -v && echo | |
msg_status 'STEP 11 of 13: Convert ISO/CD Master to Regular Image' | |
sudo rm -rf "${HOME}/Desktop/${INSTALL_TARGET}.iso" || true | |
sudo mv -vf "${INSTALL_TEMP}/${isoName}.cdr" "${INSTALL_TEMP}/${INSTALL_TARGET}.iso" | |
sudo -v && echo | |
msg_status "STEP 12 of 13: Rename '${INSTALL_ID}'..." | |
sudo diskutil rename "${INSTALL_ID}" "${INSTALL_TARGET}" | |
sudo -v && echo | |
msg_status 'STEP 13 of 13: Finishing' | |
chill_msg ; | |
sudo mv -vf "${INSTALL_TEMP}/${INSTALL_TARGET}.iso" "${HOME}/Desktop/${INSTALL_TARGET}.iso" | |
sudo rm -rf "${INSTALL_TEMP}" || true | |
echo 'Cleared Temp Files' | |
echo && echo | |
msg_info 'Complete' | |
echo && echo | |
msg_status 'NB: Use a tool such as BalenaEtcher to create bootable USB' | |
msg_status " From: '${HOME}/Desktop/${INSTALL_TARGET}.iso'" | |
runExit ; | |
} | |
# installerExists by Jeff Geerling | |
# Returns 0 if the installer was found locally or in '/Applications'. 1 if not. | |
function installerExists() { | |
local installerAppName | |
local result | |
result=1 | |
installerAppName="${1}" | |
if [ -e "${SCRIPT_DIR}/${installerAppName}" ] ; then | |
result=0 | |
elif [ -e "/Applications/${installerAppName}" ] ; then | |
result=0 | |
fi | |
return ${result} | |
} | |
function ErrClearAll() { | |
if [ -d "${INSTALL_TEMP}" ] ; then | |
sudo rm -rf "${INSTALL_TEMP}" | |
fi | |
if [ -d "${INSTALL_STICK}" ] ; then | |
sudo rm -rf "${INSTALL_STICK}" | |
fi | |
} | |
## EXIT HANDLER ## | |
runExit() { | |
flag=${1:-Norm} | |
if [ "${flag}" != 'Norm' ] ; then | |
ErrClearAll ; | |
echo && echo | |
msg_info "Exit on Error" | |
msg_info "Create Installer Aborted" | |
echo && echo | |
exit 1 | |
else | |
echo && echo | |
msg_info 'All Done!' | |
echo && echo | |
msg_info '################################' | |
msg_info ' ## Create Mac OS Install USB ##' | |
msg_info ' ################################' | |
echo && echo | |
exit 0 | |
fi | |
} | |
## ERROR HANDLER ## | |
runErr() { | |
ErrClearAll ; | |
echo && echo | |
msg_info "Runtime Error" | |
msg_error "Create Installer Failed" | |
echo && echo | |
exit 1 | |
} | |
trap runErr ERR | |
## | |
## Start Procedural Code | |
## | |
INSTALL_TARGET='NotSet' | |
INSTALL_BASIC='Install OS X' | |
INSTALL_TYPE='NotSet' | |
INSTALL_NAME='NotSet' | |
INSTALL_TEMP='/tmp/VersionOSX' | |
INSTALL_BASE='OS X Base System' | |
INSTALL_APP='Mac OS Install' | |
INSTALL_XYZ='NotSet' | |
INSTALL_ESD='/Volumes/TMP_ESD' | |
INSTALL_ID='USB_Maker' | |
INSTALL_X='InstallMacOSX' | |
TYPE_OSX="macOS" | |
TMP_STR='NotSet' | |
USE_APP='NotSet' | |
VOL_BASE_SYS='NotSet' | |
VOL_BASE_DIR='NotSet' | |
if [ ! -d "/Volumes/${INSTALL_ID}" ] ; then | |
err_msg="Connect a correctly sized USB stick labelled as '${INSTALL_ID}' and rerun this script" | |
echo && echo | |
msg_info 'ERROR!!' | |
msg_error "${err_msg}" | |
echo && echo | |
exit 1 | |
fi | |
# Resolve TMP_SOURCE until the file is no longer a symlink | |
TMP_SOURCE=${BASH_SOURCE[0]} | |
while [ -L "${TMP_SOURCE}" ] ; do | |
DIR=$( cd -P "$( dirname "${TMP_SOURCE}" )" >/dev/null 2>&1 && pwd ) | |
TMP_SOURCE=$(readlink "${TMP_SOURCE}") | |
# if ${TMP_SOURCE} is relative symlink, resolve relative to symlink file location | |
[[ ${TMP_SOURCE} != /* ]] && TMP_SOURCE=${DIR}/${TMP_SOURCE} | |
done | |
SCRIPT_DIR=$( cd -P "$( dirname "${TMP_SOURCE}" )" >/dev/null 2>&1 && pwd ) | |
echo && echo | |
enter_msg 'WithNb' 'WithAs' ; | |
sudo clear | |
echo && echo | |
msg_info ' ################################' | |
msg_info ' ## Create Mac OS Install USB ##' | |
msg_info '################################' | |
echo && echo | |
msg_info '## STAGE 1 of 4: Select Install Target ##' | |
msg_info '------------------------------------------' | |
msg_status 'STEP 01 of 03: Set Target Item' | |
PS3='Enter Corresponding Number for Mac OS Version or Exit:- ' | |
options=('Sequoia' 'Sonoma' 'Ventura' 'Monterey' 'Big Sur' 'Catalina' 'Mojave' 'High Sierra' 'Sierra' 'El Capitan' 'Yosemite' 'Mavericks' 'Mountain Lion' 'Lion' 'Exit') | |
select opt in "${options[@]}" | |
do | |
case $opt in | |
'Monterey' | 'Big Sur' | 'Catalina' | 'Mojave' | 'High Sierra') | |
INSTALL_NAME="${opt}" | |
USE_APP='True' | |
break | |
;; | |
'Sierra') | |
INSTALL_X='InstallOS' | |
INSTALL_NAME="${opt}" | |
USE_APP='Maybe' | |
INSTALL_BASIC='Install macOS' | |
INSTALL_APP="Install Mac OS ${INSTALL_NAME}.app" | |
break | |
;; | |
'El Capitan' | 'Yosemite') | |
INSTALL_NAME="${opt}" | |
USE_APP='Maybe' | |
INSTALL_APP="Install Mac OS X ${INSTALL_NAME}.app" | |
break | |
;; | |
'Mountain Lion') | |
INSTALL_NAME="${opt}" | |
USE_APP='False' | |
INSTALL_BASE='Mac OS X Base System' | |
INSTALL_BASIC='Install Mac OS X' | |
INSTALL_APP="Install OS X ${INSTALL_NAME}.app" | |
break | |
;; | |
'Lion') | |
INSTALL_NAME="${opt}" | |
USE_APP='False' | |
INSTALL_BASE='Mac OS X Base System' | |
INSTALL_BASIC='Install Mac OS X' | |
INSTALL_APP="Install Mac OS X ${INSTALL_NAME}.app" | |
break | |
;; | |
'Mavericks') | |
TMP_STR='Exit' | |
INSTALL_NAME="${opt}" | |
break | |
;; | |
'Sequoia' | 'Sonoma' | 'Ventura') | |
TMP_STR='Exit' | |
INSTALL_NAME="${opt}" | |
break | |
;; | |
'Exit') | |
TMP_STR='Exit' | |
break | |
;; | |
*) | |
echo && echo | |
msg_info 'ERROR!!' | |
msg_error "Invalid Selection:- '${REPLY}'" | |
echo && echo | |
exit 1 | |
;; | |
esac | |
done | |
sudo -v && echo | |
msg_status 'STEP 02 of 03: Get Target Item' | |
echo "'${INSTALL_NAME}' Selected" | |
if [ "${TMP_STR}" == 'Exit' ] ; then | |
if [ "${INSTALL_NAME}" != 'NotSet' ] ; then | |
echo && echo | |
msg_error "${INSTALL_NAME} *IS NOT* Supported" | |
echo | |
if [ "${INSTALL_NAME}" != 'Mavericks' ] ; then | |
echo "You might be able to get ${INSTALL_NAME} via the OCLP" | |
echo 'See https://github.com/dortania/OpenCore-Legacy-Patcher' | |
else | |
echo 'You might be able to get Mavericks by running this command:' | |
echo 'curl https://mavericks.wowfunhappy.workers.dev/ | sh' | |
echo 'See https://forums.macrumors.com/threads/2444350' | |
fi | |
fi | |
runExit 'Exit' ; | |
fi | |
sudo -v && echo | |
msg_status 'STEP 03 of 03: Vet Target Item' | |
read -r -p "Overwrite 'USB_Maker' with '${INSTALL_NAME}' Installer? [y/N] ... " response | |
case "$response" in | |
[yY][eE][sS]|[yY]) | |
echo "Confirmed" | |
;; | |
*) | |
runExit ; | |
;; | |
esac | |
sudo -v && echo | |
msg_info 'Completed Stage 1' | |
echo && echo | |
msg_info '## STAGE 2 of 4: Validate Prerequisites ##' | |
msg_info '-----------------------------------------' | |
msg_status 'STEP 01 of 02: Validate Installer Name...' | |
INSTALL_TARGET=$( echo "Install_${INSTALL_NAME}" | sed 's/ //g' ) | |
INSTALL_STICK="/Volumes/${INSTALL_TARGET}" | |
if [ ! -d "${INSTALL_STICK}" ] ; then | |
gotError='False' | |
echo 'Validated' | |
else | |
err_msg="Unmount conflicting '${INSTALL_TARGET}' volume and rerun this script" | |
gotError='True' | |
fi | |
TMP_STR='NotSet' | |
if [ "${gotError}" == 'False' ] ; then | |
sudo -v && echo | |
msg_status 'STEP 02 of 02: Validate Misc Other...' | |
# Check if using installer app for Yosemite to Sierra | |
if [ "${USE_APP}" == 'Maybe' ] ; then | |
USE_APP='False' | |
if [ "${INSTALL_NAME}" == 'Sierra' ] ; then | |
TMP_STR='macOS' | |
elif [ "${INSTALL_NAME}" == 'El Capitan' ] || [ "${INSTALL_NAME}" == 'Yosemite' ] ; then | |
TMP_STR='OS X' | |
fi | |
if [ "${TMP_STR}" != 'NotSet' ] ; then | |
if installerExists "Install ${TMP_STR} ${INSTALL_NAME}.app" ; then | |
USE_APP='True' | |
fi | |
fi | |
fi | |
TMP_STR='NotSet' | |
if [ "${USE_APP}" == 'False' ] ; then | |
# Ensure DMG is mounted | |
if [ ! -d "/Volumes/${INSTALL_BASIC}" ] ; then | |
err_msg="Mount the ${INSTALL_NAME} '${INSTALL_X}.dmg' file and rerun this script" | |
gotError='True' | |
fi | |
else | |
# Note by Jeff Geerling: | |
# Eject installer disks in case opened after download from App Store | |
# grep "partition_scheme" because "partition" finds too many lines | |
for disk in $(hdiutil info | grep /dev/disk | grep partition_scheme | cut -f 1) ; do | |
hdiutil detach -force "${disk}" || true | |
done | |
fi | |
fi | |
# Error/Exit Handling | |
if [ "${gotError}" == 'False' ] ; then | |
echo 'Validated' | |
else | |
echo && echo | |
msg_info 'ERROR!!' | |
msg_error "${err_msg}" | |
runExit 'Error' ; | |
fi | |
sudo -v && echo | |
msg_info 'Completed Stage 2' | |
if [ "${USE_APP}" == 'True' ] ; then | |
echo && echo | |
msg_info '## STAGE 3 of 4: Find Installer ##' | |
msg_info '----------------------------------' | |
msg_status 'STEP 01 of 01: Checking for Installer App...' | |
if [[ "${INSTALL_NAME}" == 'Monterey' || "${INSTALL_NAME}" == 'Big Sur' || "${INSTALL_NAME}" == 'Catalina' || "${INSTALL_NAME}" == 'Mojave' ]] ; then | |
if installerExists "Install macOS ${INSTALL_NAME}.app" ; then | |
INSTALL_TYPE='macOS' | |
TYPE_OSX='macOS' | |
fi | |
elif [[ "${INSTALL_NAME}" == 'High Sierra' || "${INSTALL_NAME}" == 'Sierra' ]] ; then | |
# DA-TAG: The Sierras are odd with 'macOS' app name but 'OS X' elsewhere | |
if installerExists "Install macOS ${INSTALL_NAME}.app" ; then | |
INSTALL_TYPE='macOS' | |
TYPE_OSX='OS X' | |
fi | |
elif [[ "${INSTALL_NAME}" == 'El Capitan' || "${INSTALL_NAME}" == 'Yosemite' ]] ; then | |
if installerExists "Install OS X ${INSTALL_NAME}.app" ; then | |
INSTALL_TYPE='OS X' | |
TYPE_OSX='OS X' | |
fi | |
fi | |
if [ "${TYPE_OSX}" == 'NotSet' ] ; then | |
echo && echo | |
msg_info 'ERROR!!' | |
msg_error "Could not find valid installer app file" | |
runExit 'Error' ; | |
fi | |
echo "Found Installer App for ${INSTALL_NAME}" | |
VOL_BASE_DIR="/Volumes/${TYPE_OSX} Base System" | |
VOL_BASE_SYS="${VOL_BASE_DIR}/BaseSystem" | |
TMP_STR='NotSet' | |
sudo -v && echo | |
msg_info 'Completed Stage 3' | |
echo && echo | |
msg_info '## STAGE 4 of 4: Create ISO Image ##' | |
msg_info '------------------------------------' | |
createISO "Install ${INSTALL_TYPE} ${INSTALL_NAME}.app" | |
else | |
echo && echo | |
msg_info '## STAGE 3 of 4: Deconstruct Installer ##' | |
msg_info '-----------------------------------------' | |
msg_status 'STEP 01 of 02: Creating Temp Store...' | |
chill_msg ; | |
sudo rm -rfv "${INSTALL_TEMP}" | |
pkgutil --expand "/Volumes/${INSTALL_BASIC}/${INSTALL_X}.pkg" "${INSTALL_TEMP}" | |
echo 'Created Temp Store' | |
sudo -v && echo | |
msg_status 'STEP 02 of 02: Ejecting Install DMG...' | |
sudo diskutil eject "${INSTALL_BASIC}" | |
sudo -v && echo | |
msg_info 'Completed Stage 3' | |
echo && echo | |
msg_info '## STAGE 4 of 4: Repackage Installer ##' | |
msg_info '---------------------------------------' | |
msg_status 'STEP 01 of 08: Attaching InstallESD...' | |
hdiutil attach "${INSTALL_TEMP}/${INSTALL_X}.pkg/InstallESD.dmg" -noverify -nobrowse -mountpoint "${INSTALL_ESD}" | |
sudo -v && echo | |
msg_status 'STEP 02 of 08: Preparing Target Disk...' | |
chill_msg ; | |
sudo asr restore -source "${INSTALL_ESD}/BaseSystem.dmg" -target "/Volumes/${INSTALL_ID}" -noprompt -noverify -erase || true | |
diskutil rename "${INSTALL_BASE}" "${INSTALL_TARGET}" | |
sudo -v && echo | |
msg_status 'STEP 03 of 08: Reconstituting Installation Packages...' | |
chill_msg ; | |
get_dir="${INSTALL_ESD}/Packages" | |
put_dir="${INSTALL_STICK}/System/Installation" | |
total_files=$(find "$get_dir" -type f | wc -l) | |
if [[ $total_files -eq 0 ]]; then | |
echo && echo | |
msg_info 'ERROR!!' | |
msg_error "Could not find installation packages" | |
runExit 'Error' ; | |
fi | |
counter=0 | |
rm -v "${INSTALL_STICK}/System/Installation/Packages" | |
find "$get_dir" -type f | while read -r file; do | |
sudo -v | |
counter=$((counter + 1)) | |
rel_path="${file#$get_dir/}" | |
dest_path="$put_dir/$rel_path" | |
mkdir -p "$(dirname "$dest_path")" | |
cp -pv "$file" "$dest_path" | |
done | |
sudo -v && echo | |
msg_status 'STEP 04 of 08: Reconstituting BaseSystem...' | |
chill_msg ; | |
cp -rpv "${INSTALL_ESD}/BaseSystem.dmg" "${INSTALL_STICK}/" | |
cp -rpv "${INSTALL_ESD}/BaseSystem.chunklist" "${INSTALL_STICK}/" | |
sudo -v && echo | |
msg_status 'STEP 05 of 08: Detaching InstallESD...' | |
hdiutil detach "${INSTALL_ESD}" || true | |
sudo -v && echo | |
msg_status 'STEP 06 of 08: Updating VolumeIcon...' | |
INSTALL_XYZ="${INSTALL_APP}" | |
InstallIcon="${INSTALL_STICK}/${INSTALL_XYZ}/Contents/Resources/InstallAssistant.icns" | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_STICK}/Install OS X ${INSTALL_NAME}.app" | |
InstallIcon="${INSTALL_XYZ}/Contents/Resources/InstallAssistant.icns" | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_STICK}/Install Mac OS X ${INSTALL_NAME}.app" | |
InstallIcon="${INSTALL_XYZ}/Contents/Resources/InstallAssistant.icns" | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_STICK}/Install Mac OS ${INSTALL_NAME}.app" | |
InstallIcon="${INSTALL_XYZ}/Contents/Resources/InstallAssistant.icns" | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_STICK}/Install macOS ${INSTALL_NAME}.app" | |
InstallIcon="${INSTALL_XYZ}/Contents/Resources/InstallAssistant.icns" | |
fi | |
fi | |
fi | |
fi | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_APP}" | |
InstallIcon="${INSTALL_STICK}/${INSTALL_XYZ}/Contents/Resources/ProductPageIcon.icns" | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_STICK}/Install OS X ${INSTALL_NAME}.app" | |
InstallIcon="${INSTALL_XYZ}/Contents/Resources/ProductPageIcon.icns" | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_STICK}/Install Mac OS X ${INSTALL_NAME}.app" | |
InstallIcon="${INSTALL_XYZ}/Contents/Resources/ProductPageIcon.icns" | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_STICK}/Install Mac OS ${INSTALL_NAME}.app" | |
InstallIcon="${INSTALL_XYZ}/Contents/Resources/ProductPageIcon.icns" | |
if [ ! -f "${InstallIcon}" ] ; then | |
INSTALL_XYZ="${INSTALL_STICK}/Install macOS ${INSTALL_NAME}.app" | |
InstallIcon="${INSTALL_XYZ}/Contents/Resources/ProductPageIcon.icns" | |
fi | |
fi | |
fi | |
fi | |
fi | |
if [ -f "${InstallIcon}" ] ; then | |
cp -v "${InstallIcon}" "${INSTALL_STICK}/.VolumeIcon.icns" | |
else | |
echo 'Skipped VolumeIcon Update ... Not Found' | |
fi | |
sudo -v && echo | |
msg_status 'STEP 07 of 08: Labelling Installer...' | |
sudo bless --folder "${INSTALL_STICK}/System/Library/CoreServices" --label "${INSTALL_TARGET}" | |
echo "Labelled as '${INSTALL_TARGET}'" | |
sudo -v && echo | |
msg_status 'STEP 08 of 08: Cleaning Up...' | |
cd "${HOME}" || true | |
sudo rm -rf "${INSTALL_TEMP}" || true | |
echo 'Cleared Temp Store' | |
echo | |
msg_info 'Completed Stage 4' | |
runExit ; | |
fi |
Dayo why did you skip Mavericks? Some people have legitimate Mavericks apps.
Hi ... Didn't have one at the time but IIRC, the one I did get had a different structure and initial attempts failed.
Didn't try too hard to sort it out and moved on given that Apple was not offering it like the others anyway.
Is this path existing:
/Volumes/Lion Installer/Install OS X Lion/Contents/Resources/InstallAssistant.icns
@onekingnqueen ... Thanks for the report.
Should be fixed now.
Just wanted to say thanks @daaku
Hi
I tried creating a Lion USB installer.
The script failed as below, any help?
Screen Log Output
STEP 02 of 04: Reconstituting ESD...
NB: Patience ... This takes a while to complete
Type password and press "Enter" if prompted
Your password is not displayed while typing
/Volumes/Install_Lion/System/Installation/Packages
/Volumes/TMP_ESD/BaseSystem.dmg -> /Volumes/Install_Lion/BaseSystem.dmg
/Volumes/TMP_ESD/BaseSystem.chunklist -> /Volumes/Install_Lion/BaseSystem.chunklist
/Volumes/TMP_ESD/Packages -> /Volumes/Install_Lion/System/Installation/Packages
/Volumes/TMP_ESD/Packages/AdditionalEssentials.pkg -> /Volumes/Install_Lion/System/Installation/Packages/AdditionalEssentials.pkg
/Volumes/TMP_ESD/Packages/AdditionalSpeechVoices.pkg -> /Volumes/Install_Lion/System/Installation/Packages/AdditionalSpeechVoices.pkg
/Volumes/TMP_ESD/Packages/AddressBook.pkg -> /Volumes/Install_Lion/System/Installation/Packages/AddressBook.pkg
/Volumes/TMP_ESD/Packages/Arabic.pkg -> /Volumes/Install_Lion/System/Installation/Packages/Arabic.pkg
/Volumes/TMP_ESD/Packages/AsianLanguagesSupport.pkg -> /Volumes/Install_Lion/System/Installation/Packages/AsianLanguagesSupport.pkg
/Volumes/TMP_ESD/Packages/Automator.pkg -> /Volumes/Install_Lion/System/Installation/Packages/Automator.pkg
/Volumes/TMP_ESD/Packages/BaseSystemBinaries.pkg -> /Volumes/Install_Lion/System/Installation/Packages/BaseSystemBinaries.pkg
/Volumes/TMP_ESD/Packages/BaseSystemResources.pkg -> /Volumes/Install_Lion/System/Installation/Packages/BaseSystemResources.pkg
/Volumes/TMP_ESD/Packages/BootCamp.pkg -> /Volumes/Install_Lion/System/Installation/Packages/BootCamp.pkg
/Volumes/TMP_ESD/Packages/BrazilianPortuguese.pkg -> /Volumes/Install_Lion/System/Installation/Packages/BrazilianPortuguese.pkg
/Volumes/TMP_ESD/Packages/BSD.pkg -> /Volumes/Install_Lion/System/Installation/Packages/BSD.pkg
/Volumes/TMP_ESD/Packages/Catalan.pkg -> /Volumes/Install_Lion/System/Installation/Packages/Catalan.pkg
/Volumes/TMP_ESD/Packages/Croatian.pkg -> /Volumes/Install_Lion/System/Installation/Packages/Croatian.pkg
/Volumes/TMP_ESD/Packages/Czech.pkg -> /Volumes/Install_Lion/System/Installation/Packages/Czech.pkg
/Volumes/TMP_ESD/Packages/Danish.pkg -> /Volumes/Install_Lion/System/Installation/Packages/Danish.pkg
/Volumes/TMP_ESD/Packages/Dutch.pkg -> /Volumes/Install_Lion/System/Installation/Packages/Dutch.pkg
/Volumes/TMP_ESD/Packages/DVDPlayer.pkg -> /Volumes/Install_Lion/System/Installation/Packages/DVDPlayer.pkg
cp: /Volumes/Install_Lion/System/Installation/Packages/Essentials.pkg: fcopyfile failed: Input/output error
cp: /Volumes/Install_Lion/System/Installation/Packages/Essentials.pkg: fchmod failed: No such file or directory
cp: utimensat: /Volumes/Install_Lion/System/Installation/Packages/Essentials.pkg: No such file or directory
cp: fchown: /Volumes/Install_Lion/System/Installation/Packages/Essentials.pkg: Bad file descriptor
cp: fchmod: /Volumes/Install_Lion/System/Installation/Packages/Essentials.pkg: No such file or directory
cp: chflags: /Volumes/Install_Lion/System/Installation/Packages/Essentials.pkg: No such file or directory
cp: /Volumes/TMP_ESD/Packages/Essentials.pkg: could not copy ACL to /Volumes/Install_Lion/System/Installation/Packages/Essentials.pkg: Bad file descriptor
cp: /Volumes/Install_Lion/System/Installation/Packages/Finnish.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/French.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/German.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Greek.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Hebrew.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Hungarian.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/iCal.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/iChat.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Italian.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/iTunes.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Japanese.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/JavaEssentials.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/JavaTools.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Korean.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Mail.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/MediaFiles.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/MigrationAssistant.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Norwegian.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/OSInstall.mpkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/OSInstall.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/OSUpgrade.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/OxfordDictionaries.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/PodcastCapture.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Polish.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Portuguese.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/RemoteDesktop.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Romanian.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Russian.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Safari.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/SimplifiedChinese.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/SIUResources.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Slovak.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Spanish.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Swedish.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Thai.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/TraditionalChinese.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Turkish.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/Ukrainian.pkg: No such file or directory
cp: /Volumes/Install_Lion/System/Installation/Packages/X11User.pkg: No such file or directory
cp: utimensat: /Volumes/Install_Lion/System/Installation/Packages: No such file or directory
cp: chown: /Volumes/Install_Lion/System/Installation/Packages: No such file or directory
cp: chmod: /Volumes/Install_Lion/System/Installation/Packages: No such file or directory
cp: chflags: /Volumes/Install_Lion/System/Installation/Packages: No such file or directory
cp: /Volumes/TMP_ESD/Packages: unable to copy ACL to /Volumes/Install_Lion/System/Installation/Packages: No such file or directory
Password:
Runtime Error!!
Could Not Create USB Installer
tony@Mac USB script %
Hi.
Please avoid pasting long log or similar outputs into any forum or similar post in future.
Either put into a file and attach that or use format options to collapse the output as I have done with your post
On your issue, you need to look into your setup.
I just downloaded and created an installer for Lion a few minutes ago using a copy of the script I also just got from here.
That is, it works for me
Thanks
Apologies for the bad formatting. I did try to insert it in a "code" section but it did not work. Eventually I gave up but I didn't think of attaching a small file, apologies.
And sorry for wasting your time - it turned out a bad USB hub was probably removing the USB stick from the system. I plugged the USB directly into my dock and I could complete the script.
Thanks again!
Okay. Good to know.
this is super handy, especially for Lion. very kind. many thanks!
This worked great for creating a bootable USB for OSX Lion for an old 2013 Macbook Air. The process was smooth, easy to follow, and comprehensive. Would be happy to send you some $$$ as a tip if you accept that. Thank you for building and sharing this!