Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

crjackson2134

macrumors 601
Mar 6, 2013
4,825
1,949
Charlotte, NC
I used a modified script that produces an auto-sized ISO image.

For the 10.11 installation the size of the ISO is only 7502405632 bytes.

It seems to work, but feel free to make improvements!


Code:
#!/bin/bash

# Mount the installer image
hdiutil attach /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app

# Create a ElCapitan blank ISO image of 9900mb with a Single Partition - Apple Partition Map
hdiutil create -o /tmp/ElCapitan.cdr -size 9900m -layout SPUD -fs HFS+J

# Mount the ElCapitan blank ISO image
hdiutil attach /tmp/ElCapitan.cdr.dmg -noverify -nobrowse -mountpoint /Volumes/install_build

# Restore the Base System into the ElCapitan blank ISO image
asr restore -source /Volumes/install_app/BaseSystem.dmg -target /Volumes/install_build -noprompt -noverify -erase

# Remove Package link and replace with actual files
rm /Volumes/OS\ X\ Base\ System/System/Installation/Packages
cp -rp /Volumes/install_app/Packages /Volumes/OS\ X\ Base\ System/System/Installation/

# Copy El Capitan installer dependencies
cp -rp /Volumes/install_app/BaseSystem.chunklist /Volumes/OS\ X\ Base\ System/BaseSystem.chunklist
cp -rp /Volumes/install_app/BaseSystem.dmg /Volumes/OS\ X\ Base\ System/BaseSystem.dmg

# Unmount the installer image
hdiutil detach /Volumes/install_app

# Unmount the ElCapitan ISO Image
hdiutil detach /Volumes/OS\ X\ Base\ System/

# Create a sparseimage and auto-size it
hdiutil convert /tmp/ElCapitan.cdr.dmg -format UDSP -o /tmp/ElCapitan
hdiutil resize -size `hdiutil resize -limits /tmp/ElCapitan.sparseimage | tail -n 1 | awk '{ print $1 }'`b /tmp/ElCapitan.sparseimage

# Convert the ElCapitan sparseimage to ISO/CD master
hdiutil convert /tmp/ElCapitan.sparseimage -format UDTO -o /tmp/ElCapitan

# Remove the unwanted images
rm /tmp/ElCapitan.cdr.dmg
rm /tmp/ElCapitan.sparseimage

# Rename the ElCapitan ISO image and move it to the desktop
mv /tmp/ElCapitan.cdr ~/Desktop/ElCapitan.iso

And this iso is burnable, bootable, and installable?
 

anton1s

macrumors member
Jun 17, 2012
59
0
I used a modified script that produces an auto-sized ISO image.

For the 10.11 installation the size of the ISO is only 7502405632 bytes.

It seems to work, but feel free to make improvements!

It doesn't seem to work for me. i always get "Not enough free space on OS X Base System". Any ideas?

Thanks
 

anton1s

macrumors member
Jun 17, 2012
59
0
Just to confirm, you've created the iso and then created a new virtual machine (I am using virtual box) by setting it as mac (el capitan) and creating a new virtual disk. You then added a CD/DVD and selected that image right?
 

wionda92

macrumors newbie
Original poster
Oct 1, 2015
15
1
Yes, that's how it worked for me. The ISO was produced and I used it in the manner you described. I did not use vbox. If my script did not work for you, maybe you could try the one by colt2 in post #46 above.
 

ssn637

macrumors 6502
Feb 12, 2009
452
48
Switzerland
Somewhat off the subject, but a related question that probably needs a couple more commands in Terminal:

Could someone provide instructions on how to create a recovery partition in El Capitan to include the complete installer? This would make clean installations (and SIP enabling or disabling) much easier than using a USB Flash Drive. I've tried using the Recovery Editor and other methods that worked with Yosemite but haven't been able to complete the process.
 

tywebb13

macrumors 68030
Apr 21, 2012
2,948
1,636
Somewhat off the subject, but a related question that probably needs a couple more commands in Terminal:

Could someone provide instructions on how to create a recovery partition in El Capitan to include the complete installer? This would make clean installations (and SIP enabling or disabling) much easier than using a USB Flash Drive. I've tried using the Recovery Editor and other methods that worked with Yosemite but haven't been able to complete the process.

Yeah. It's off topic. So I reckon you should start your own thread on this. But to get you started, here is an old thread to make recovery partitions containing the full installer. Not sure if it will work with El Capitan though.

https://forums.macrumors.com/threads/edit-the-recovery-partition-without-breaking-it.1598564/
 
  • Like
Reactions: crjackson2134

ssn637

macrumors 6502
Feb 12, 2009
452
48
Switzerland
OK, I should probably start a new thread.

Thanks for your help, but I had already tried to create a Recovery Partition in El Capitan using the instructions provided in the link you forwarded and couldn't get it to work.

Terminal returned the following error message:

Error (async): The new recovery partition would be too large (-69668)
 

Karlson2k

macrumors newbie
Nov 2, 2015
2
1
I wrote small script for this task. Can produce bootable .iso by three ways.
Save this script in any local file ("create_osx_install_iso.sh" for example) or download and unpack attached file.
Mark file as executable by "chmod +x 'create_osx_install_iso.sh'" and run.
Code:
#!/bin/bash

# Script for building bootable .iso images from downloaded OS X upgrade
# Copyright (C) 2015 Karlson2k (Evgeny Grin)
#
# You can run, copy, modify, publish and do whatever you want with this
# script as long as this message and copyright string above are preserved.
# You are also explicitly allowed to reuse this script under any LGPL or
# GPL license or under any BSD-style license.
#
#
# Latest version:
# https://raw.githubusercontent.com/Karlson2k/k2k-OSX-Tools/master/Create_osx_install_iso/create_osx_install_iso.sh
#
# Version 1.0.0

readonly script_org_name='create_osx_install_iso.sh' || exit 127
unset work_dir script_name tmp_dir OSX_inst_name OSX_inst_inst_dmg_mnt \
    OSX_inst_img_rw_mnt OSX_inst_img_rw_dev || exit 127
work_dir="$PWD"
save_IFS="$IFS" || exit 127
export LANG='en_US.UTF-8' # prevent localizaion of output, not really required

[[ `ps -o comm -p $$ | tail -n1 2>/dev/null` =~ bash$ ]] || {
    echo "Script is designed to be run only with bash"
    exit 127
}
[[ "$(uname -s)" == Darwin ]] || {
    echo "Script can be run only on Mac OS X"
    exit 127
}

cleanup() {
    trap - SIGHUP SIGTERM SIGQUIT SIGINT SIGSTOP SIGTSTP EXIT
    if [[ -n $tmp_dir ]] && [[ -e "$tmp_dir" ]]; then
        if [[ -e "$OSX_inst_img_rw_dev" ]]; then
            echo "Unmounting writable image..."
            hdiutil detach "$OSX_inst_img_rw_dev" -force
        fi
        if [[ -e "$OSX_inst_img_rw_mnt" ]]; then
            echo "Unmounting writable image..."
            hdiutil detach "$OSX_inst_img_rw_mnt" -force
        fi
        if [[ -e "$OSX_inst_inst_dmg_mnt" ]]; then
            echo "Unmounting temporary mounted source image..."
            hdiutil detach "$OSX_inst_inst_dmg_mnt" -force
        fi
        echo "Removing temporary files..."
        rm -fdR "$tmp_dir"
    fi
}

trap '{ exit_code="$?"; cleanup; exit $exit_code; }' EXIT

echo_term_ansi_m() {
    local n_param=''
    if [[ "$1" == "-n" ]]; then
        n_param="$1"
        shift
    elif [[ -z "$1" ]]; then shift
    fi
    local m_code="$1"
    shift
    if [[ -t 1 ]]; then
        echo $n_param $'\e['"${m_code}m$@"$'\e[0m'
    else
        echo $n_param "$@"
    fi
}

echo_neutral() {
    echo "$@"
}

echo_enh() {
    echo_term_ansi_m '1;97' "$@"
}

echo_enh_n() {
    echo_term_ansi_m -n '1;97' "$@"
}

echo_positive() {
    echo_term_ansi_m '1;92' "$@"
}

echo_positive_n() {
    echo_term_ansi_m -n '1;92' "$@"
}

echo_warning() {
    echo_term_ansi_m '1;93' "$@"
}

echo_warning_n() {
    echo_term_ansi_m -n '1;93' "$@"
}

echo_error() {
    echo_term_ansi_m '1;91' "$@" 1>&2
}
echo_error_n() {
    echo_term_ansi_m -n '1;91' "$@" 1>&2
}

exit_with_error() {
    trap - SIGHUP SIGTERM SIGQUIT SIGINT SIGSTOP SIGTSTP EXIT
    if [[ -n $1 ]]; then
        echo_error "Error: $1"
    else
        echo_error "Error."
    fi
    cleanup
    [[ $2 > 0 ]] && exit $2
    exit 1
}

trap '{ exit_with_error "unexpected interrupt at line $LINENO"; exit 255; }' SIGHUP SIGTERM SIGQUIT SIGINT SIGSTOP SIGTSTP

# trap 'echo "Line number: $LINENO"; read -p "\"Enter\" to continue" ' DEBUG

stage_start() {
    echo_enh_n "$@... "
}

stage_start_nl() {
    stage_start "$@"
    echo ''
}

stage_end_ok() {
    if [[ -z "$@" ]]; then
        echo_positive "OK"
    else
        echo_positive "$@"
    fi
}

stage_end_warn() {
    if [[ -z "$@" ]]; then
        echo_warning "OK, but with warnings"
    else
        echo_warning "$@"
    fi
}

is_answer_valid() {
    local answ="$1"
    shift
    while [[ -n $1 ]]; do
        [[ "$answ" == "$1" ]] && return 0
        shift
    done
    return 1
}

script_name="$(basename "${BASH_SOURCE[0]}" 2>/dev/null)"
[[ -n "$script_name" ]] || script_name="${0##*/}" # fallback
[[ -n "$script_name" ]] || script_name="${script_org_name}" # second fallback

script_version="$(sed -n -e '\|^# Version| {s|^# Version \(.*$\)|\1|p; q;}' "${BASH_SOURCE[0]}" 2>/dev/null)" || unset script_version
[[ -n "$script_version" ]] || script_version="Unknown"

print_help() {
    echo "\
Script for creating .iso images from downloaded OS X Install application.
Usage:"
    echo_enh_n "      $script_name"; echo " [options]

Valid options are:
      -a, --app[lication] <OS X Install app>
                   Path and name of OS X install application.
                   Path can be omitted if application located at default path.
      -i, --iso <path with name for .iso>
                   Path with optional name for output .iso
      -m, --method <D>
                   Use method number D to create installation image:
                   Method 1 create image that most close to Apple's image,
                   but potentially less compatible with some BIOSes/EFI.
                   Method 2 create more BIOS/EFI-friendly images, but
                   require more disk space for conversion.
                   Method 3 can produce bootable images without super
                   user rights.
      -n, --nosudo
                   Do not use sudo command
      -v, --verify
                   Do not skip verifications (slow down image creation)
      -h, --help   Print this message and exit
      -V, --version
                   Print version information and exit"
                
}

print_version() {
    echo "${script_org_name} version $script_version"
}

exit_with_cmd_err() {
    echo_error "$@"
    print_help 1>&2
    exit 32
}

unset cmd_par_app cmd_par_iso test_name ver_opt cr_method || exit_with_error "Can't unset variable"
allow_sudo='yes' && ver_opt='--noverify' || exit_with_error "Can't set variable"
while [[ -n "$1" ]]; do
    case "$1" in
        -a | --app | --application ) cmd_par_app="$2"
            [[ -n "$cmd_par_app" ]] && [[ "$cmd_par_app" != "--iso" ]] || exit_with_cmd_err "No Application name given for $1"
            shift 2 ;;
        -i | --iso ) cmd_par_iso="$2"
            [[ -n "$cmd_par_iso" ]] && [[ "$cmd_par_iso" != "--app" ]] || exit_with_cmd_err "No .iso name given for $1"
            shift 2 ;;
        -m | --method ) [[ -z "$2" ]] && exit_with_cmd_err "Method not specified for $1"
            cr_method="method${2}"
            shift 2 ;;
        -m* ) cr_method="method${1#-m}"; shift ;;
        --method* ) cr_method="method${1#--method}"; shift ;;
        -n | --nosudo ) allow_sudo='no'; shift ;;
        -v | --verify ) unset ver_opt; shift ;;
        -h | --h | --help ) print_help; exit 0 ;;
        -V | --version ) print_version; exit 0 ;;
        *) exit_with_cmd_err "Unknown option \"$1\""
    esac
done

[[ "${cr_method-notset}" == "notset" ]] || [[ "$cr_method" =~ ^"method"[1-3]$ ]] || exit_with_cmd_err "Unknown creation method specified: ${cr_method#method}"

check_intall_app() {
    [[ -n "$1" ]] || return 3
    [[ -d "$1" ]] || return 2
    [[ -e "$1/Contents/SharedSupport/InstallESD.dmg" ]] || return 1
    return 0
}

if [[ -z "$cmd_par_app" ]]; then
    stage_start "Looking for downloaded OS upgrades"
    unset test_name || exit_with_error
    IFS=$'\n'
    dirlist=(`ls -1d "/Applications/Install OS X "*".app/" | sed -n -e 's|^\(/Applications/Install OS X .*\.app\)/$|\1|p' `) || exit_with_error "Can't find downloaded OS X upgrade"
    IFS="$save_IFS"
    [[ ${#dirlist[@]} -eq 0 ]] && exit_with_error "Can't find downloaded OS X upgrade"
    stage_end_ok "found"
    if [[ ${#dirlist[@]} -gt 1 ]]; then
        echo "Several OS upgrades were found."
        echo "Which one OS upgrade do you want to use?"
        valid_answers=()
        unset test_name || exit_with_error
        for ((i=0;i<${#dirlist[@]};i++)); do
            test_name="${dirlist[$i]#/Applications/Install }"
            echo "$((i+1))) ${test_name%.app}"
            valid_answers[$i]="$((i+1))"
        done
        read -n 1 -p "[1-$i, q for quit]: " answer
        echo ''
        until is_answer_valid $answer ${valid_answers[@]} 'q'; do
            echo "'$answer' is incorrect response"
            read -n 1 -p "Select ""$(seq -s ', ' -t '\b\b' 1 $i)"" or q for quit: " answer
            echo ''
        done
        [[ "$answer" == "q" ]] && { echo_warning "Aborted."; exit 2; }
        OSX_inst_app="${dirlist[$((answer-1))]}"
    else
        OSX_inst_app="${dirlist[0]}"
    fi
    echo_enh "Using \"$OSX_inst_app\"."
else
    stage_start "Checking for specified OS upgrade"
    unset OSX_inst_app || exit_with_error
    if check_intall_app "${cmd_par_app%/}"; then
        # direct location with path
        if [[ "${cmd_par_app:0:1}" == "/" ]]; then
            OSX_inst_app="${cmd_par_app%/}" # absolute path
        else
            OSX_inst_app="$(pwd)/${cmd_par_app%/}" # relative path
            test_name="$(cd "$OSX_inst_app/" 2>/dev/null && pwd)" || unset test_name || exit_with_error
            [[ -n "$test_name" ]] && OSX_inst_app="$test_name" # use absolute path if possible
        fi
    elif [[ "${cmd_par_app%%/*}" == "${cmd_par_app%/}" ]]; then
        # check /Applications
        test_name="${cmd_par_app%/}"
        test_name="${test_name%.app}.app"
        if check_intall_app "/Applications/${test_name}"; then
            OSX_inst_app="/Applications/${test_name}"
        elif check_intall_app "/Applications/Install ${test_name}"; then
            OSX_inst_app="/Applications/Install ${test_name}"
        elif check_intall_app "/Applications/Install OS X ${test_name}"; then
            OSX_inst_app="/Applications/Install OS X ${test_name}"
        fi
    fi
    [[ -n "$OSX_inst_app" ]] || exit_with_error "\"$cmd_par_app\" is not valid OS X Install application"
    stage_end_ok "found"
    echo_enh "Using \"$OSX_inst_app\"."
fi

stage_start "Detecting OS X name for installation"
unset test_name OSX_inst_prt_name || exit_with_error
test_name=$(sed -n -e '\|<key>CFBundleDisplayName</key>| { N; s|^.*<string>\(.\{1,\}\)</string>.*$|\1|p; q; }' \
     "$OSX_inst_app/Contents/Info.plist" 2>/dev/null) || unset test_name
if [[ -n "$test_name" ]]; then
    OSX_inst_name="${test_name#Install }"
    OSX_inst_prt_name="Install $OSX_inst_name"
    stage_end_ok "$OSX_inst_name"
else
    OSX_inst_name=$(echo "$OSX_inst_app"|sed -n -e's|^.*Install \(OS X .\{1,\}\)\.app.*$|\1|p' 2>/dev/null) || unset OSX_inst_name || exit_with_error
    [[ -z "$OSX_inst_name" ]] && OSX_inst_name="OS X"
    OSX_inst_prt_name="Install $OSX_inst_name"
    stage_end_warn "guessed \"$OSX_inst_name\""
fi

stage_start "Creating temporary directory"
tmp_dir="$(mktemp -d -t osx_iso_tmpdir)" || exit_with_error "Can't create tmp directory"
# mkdir "tmp-tmp"
# tmp_dir=$(cd tmp-tmp && pwd) || exit_with_error "Can't create tmp directory"
stage_end_ok "succeed"

stage_start_nl "Mounting InstallESD.dmg"
OSX_inst_inst_dmg="$OSX_inst_app"'/Contents/SharedSupport/InstallESD.dmg'
OSX_inst_inst_dmg_mnt="$tmp_dir/InstallESD_dmg_mnt"
hdiutil attach "$OSX_inst_inst_dmg" -kernel -readonly -nobrowse ${ver_opt+-noverify} -mountpoint "$OSX_inst_inst_dmg_mnt" || exit_with_error "Can't mount installation image"
OSX_inst_base_dmg="$OSX_inst_inst_dmg_mnt/BaseSystem.dmg" || exit_with_error
stage_end_ok "Mounting succeed"

stage_start "Calculating required image size"
unset OSX_inst_inst_dmg_used_size OSX_inst_base_dmg_real_size OSX_inst_base_dmg_size || exit_with_error "Can't unset variables"
OSX_inst_inst_dmg_used_size=$(hdiutil imageinfo "$OSX_inst_inst_dmg" -plist | \
    sed -En -e '\|<key>Total Non-Empty Bytes</key>| { N; s|^.*<integer>(.+)</integer>.*$|\1|p; q; }') || unset OSX_inst_inst_dmg_used_size
OSX_inst_base_dmg_real_size=$(hdiutil imageinfo "$OSX_inst_base_dmg" -plist | \
    sed -En -e '\|<key>Total Bytes</key>| { N; s|^.*<integer>(.+)</integer>.*$|\1|p; q; }') || unset OSX_inst_base_dmg_real_size
OSX_inst_base_dmg_size=$(stat -f %z "$OSX_inst_base_dmg") || unset OSX_inst_base_dmg_size
((OSX_inst_base_dmg_size=(OSX_inst_base_dmg_size/512)*512)) # round to sector bound
if !((OSX_inst_inst_dmg_used_size)) || !((OSX_inst_base_dmg_real_size)) || !((OSX_inst_base_dmg_size)); then
    ((OSX_inst_img_rw_size=10*1024*1024*1024))
    stage_end_warn "Can't calculate, will use $OSX_inst_img_rw_size ($((OSX_inst_img_rw_size/(1024*1024))) MiB)"
else
    ((OSX_inst_img_rw_size=OSX_inst_base_dmg_real_size+(OSX_inst_inst_dmg_used_size-OSX_inst_base_dmg_size) ))
    ((OSX_inst_img_rw_size+=OSX_inst_img_rw_size/10)) # add 10% for overhead, no need to be precise
    ((OSX_inst_img_rw_size=(OSX_inst_img_rw_size/512 + 1)*512)) # round to sector bound
    stage_end_ok "$OSX_inst_img_rw_size ($((OSX_inst_img_rw_size/(1024*1024))) MiB)"
fi

stage_start "Checking for available disk space"
unset tmp_dir_free_space || exit_with_error
tmp_dir_free_space="$(df -bi "$tmp_dir" | \
    sed -nE -e 's|^.+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+([0-9]+)[[:space:]]+[0-9]{1,3}%[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]{1,3}%[[:space:]]+/.*$|\1|p' )" || unset tmp_dir_free_space
if [[ "${tmp_dir_free_space-notset}" == "notset" ]] || ( [[ -n "$tmp_dir_free_space" ]] && !((tmp_dir_free_space)) ); then
    tmp_dir_free_space='0'
    stage_end_warn "Can't determinate"
else
    ((tmp_dir_free_space*=512))
    if ((tmp_dir_free_space < OSX_inst_img_rw_size)); then
        stage_end_warn "$tmp_dir_free_space ($((tmp_dir_free_space/(1024*1024))) MiB), image creation may fail"
    else
        stage_end_ok "$tmp_dir_free_space ($((tmp_dir_free_space/(1024*1024))) MiB)"
    fi
fi

stage_start "Checking for super user rights"
unset have_su_rights use_sudo sudo_prf || exit_with_error "Can't unset variables"
if [[ `id -u` != '0' ]]; then
    have_su_rights='no'
else
    have_su_rights='yes'
fi
if [[ "$have_su_rights" == "yes" ]] || [[ "$allow_sudo" != "yes" ]]; then
    use_sudo='no'
    sudo_prf=''
else
    use_sudo='yes'
    sudo_prf='sudo'
fi  
if [[ "$have_su_rights" == "yes" ]]; then
    stage_end_ok 'Owned'
else
    stage_end_warn "Not owned"
fi

stage_start "Choosing creation method"
if [[ -n "$cr_method" ]]; then
    stage_end_ok "Method ${cr_method#method}, specified on command line"
    if [[ "$cr_method" != "method3" ]] && [[ "$have_su_rights" != "yes" ]] && [[ "$allow_sudo" != "yes" ]]; then
        echo_warning "Resulting image probably will be unbootable as method ${cr_method#method} require super user rights and sudo was disabled by command line"
    fi
elif [[ "$have_su_rights" != 'yes' ]]; then
    cr_method="method3"
    stage_end_ok "Method 3 as safest without super user right"
elif ((tmp_dir_free_space < OSX_inst_img_rw_size*3)); then
    cr_method="method1"
    stage_end_ok "Method 1 due to limited disk space"
else
    cr_method="method2"
    stage_end_ok "Method 2"
fi
  
unset img_bootable || exit_with_error
if [[ "$cr_method" == "method1" ]] || [[ "$cr_method" == "method2" ]]; then
    if [[ "$cr_method" == "method1" ]]; then
        stage_start_nl "Converting BaseSystem.dmg to writable image"
        OSX_inst_img_rw="$tmp_dir/OS_X_Install.sparsebundle"
        hdiutil convert "$OSX_inst_base_dmg" -format UDSB -o "$OSX_inst_img_rw" -pmap || exit_with_error "Can't convert to writable image"
        stage_end_ok "Converting succeed"
    elif [[ "$cr_method" == "method2" ]]; then
        stage_start_nl "Creating installation image from BaseSystem.dmg"
        OSX_inst_img_dmg_tmp="$tmp_dir/OS_X_Install.dmg" || exit_with_error
        hdiutil create  "${OSX_inst_img_dmg_tmp}" -srcdevice "$OSX_inst_base_dmg" -layout ISOCD || exit_with_error "Can't create writable image"
        stage_end_ok "Creating succeed"

        stage_start_nl "Converting installation image to writeable format"
        OSX_inst_img_rw="$tmp_dir/OS_X_Install.sparsebundle"
        hdiutil convert "$OSX_inst_img_dmg_tmp" -format UDSB -o "$OSX_inst_img_rw" -pmap || exit_with_error "Can't convert to writable image"
        rm -f "$OSX_inst_img_dmg_tmp"
        stage_end_ok "Converting succeed"
    fi

    stage_start "Resizing writable image"
    hdiutil resize -size "$OSX_inst_img_rw_size" "$OSX_inst_img_rw" -nofinalgap || exit_with_error "Can't resize writable image"
    stage_end_ok "Resizing succeed"

    stage_start_nl "Mounting writable image"
    OSX_inst_img_rw_mnt="$tmp_dir/OS_X_Install_img_rw_mnt"
    hdiutil attach "$OSX_inst_img_rw" -readwrite -nobrowse -mountpoint "$OSX_inst_img_rw_mnt" ${ver_opt+-noverify} || exit_with_error "Can't mount writable image"
    stage_end_ok "Mounting succeed"
elif [[ "$cr_method" == "method3" ]]; then
    stage_start_nl "Creating blank writable image"
    OSX_inst_img_rw="$tmp_dir/OS_X_Install.sparsebundle"
    OSX_inst_img_rw_tmp_name="$OSX_inst_prt_name" || exit_with_error
    hdiutil create -size "$OSX_inst_img_rw_size" "$OSX_inst_img_rw" -type SPARSEBUNDLE -fs HFS+ -layout ISOCD -volname "$OSX_inst_img_rw_tmp_name" || exit_with_error "Can't create writable image"
    stage_end_ok "Creating succeed"

    stage_start_nl "Mounting writable image"
    OSX_inst_img_rw_mnt="$tmp_dir/OS_X_Install_img_rw_mnt"
    hdiutil attach "$OSX_inst_img_rw" -readwrite -nobrowse -mountpoint "$OSX_inst_img_rw_mnt" ${ver_opt+-noverify} || exit_with_error "Can't mount writable image"
    stage_end_ok "Mounting succeed"

    stage_start "Detecting mounted image device node"
    OSX_inst_img_rw_dev=`diskutil info -plist "$OSX_inst_img_rw_mnt" | sed -n -e '\|<key>DeviceIdentifier</key>| { N; s|^.*<string>\(.\{1,\}\)</string>.*$|/dev/\1|p; q; }'` && \
        [[ -n "$OSX_inst_img_rw_dev" ]] || exit_with_error "Can't find device node"
    stage_end_ok "$OSX_inst_img_rw_dev"

    stage_start_nl "Restoring BaseSystem.dmg to writable image"
    asr restore --source "$OSX_inst_base_dmg" --target "$OSX_inst_img_rw_dev" --erase --noprompt $ver_opt --buffers 1 --buffersize 64m || exit_with_error "Can't restore BaseSystem.dmg to writable image"
    unset OSX_inst_img_rw_mnt || exit_with_error # OSX_inst_img_rw_mnt is no valid anymore as image was remounted to different mountpoint
    img_bootable='yes'
    stage_end_ok "Restoring succeed"

    stage_start "Detecting re-mounted image volume name"
    unset OSX_inst_img_rw_volname || exit_with_error
    OSX_inst_img_rw_volname=`diskutil info -plist "$OSX_inst_img_rw_dev" | sed -n -e '\|<key>VolumeName</key>| { N; s|^.*<string>\(.\{1,\}\)</string>.*$|\1|p; q; }'` || unset OSX_inst_img_rw_folname
    if [[ -z "$OSX_inst_img_rw_volname" ]]; then
        stage_end_warn "can't detect"
    else
        osascript -e "Tell application \"Finder\" to close the window \"$OSX_inst_img_rw_volname\"" &>/dev/null
        stage_end_ok "$OSX_inst_img_rw_volname"
    fi

    stage_start_nl "Remounting writable image to predefined mointpoint"
    hdiutil detach "$OSX_inst_img_rw_dev" -force || exit_with_error "Can't unmount image"
    unset OSX_inst_img_rw_dev
    OSX_inst_img_rw_mnt="$tmp_dir/OS_X_Install_img_rw_mnt"
    hdiutil attach "$OSX_inst_img_rw" -readwrite -nobrowse -mountpoint "$OSX_inst_img_rw_mnt" ${ver_opt+-noverify} || exit_with_error "Can't mount writable image"
    stage_end_ok "Remounting succeed"
else
    exit_with_error "Unknown creation method"
fi  

stage_start "Detecting OS X version on image"
unset OSX_inst_ver || exit_with_error "Can't unset variable"
OSX_inst_img_rw_ver_file="$OSX_inst_img_rw_mnt/System/Library/CoreServices/SystemVersion.plist" || exit_with_error "Can't set variable"
OSX_inst_ver=`sed -n -e '\|<key>ProductUserVisibleVersion</key>| { N; s|^.*<string>\(.\{1,\}\)</string>.*$|\1|p; q; }' "$OSX_inst_img_rw_ver_file"` || unset OSX_inst_ver
if [[ -z "$OSX_inst_ver" ]]; then
    stage_end_warn "not detected"
else
    stage_end_ok "$OSX_inst_ver"
fi

[[ "$OSX_inst_ver" != "10.11" ]] && echo_warning "This script is tested only with images of OS X version 10.11"

stage_start_nl "Renaming partition on writeable image"
if ! diskutil rename "$OSX_inst_img_rw_mnt" "$OSX_inst_prt_name"; then
    stage_end_warn "Partition was not renamed"
else
    unset OSX_inst_img_rw_volname
    stage_end_ok "Renamed to \"$OSX_inst_prt_name\""
fi

stage_start "Copying BaseSystem.dmg to writeable image"
#rsync -aIWEh --cache --progress "$OSX_inst_base_dmg" "$OSX_inst_img_rw_mnt/" || exit_with_error "Copying BaseSystem.dmg failed"
cp -p "$OSX_inst_base_dmg" "$OSX_inst_img_rw_mnt/" || exit_with_error "Copying BaseSystem.dmg failed"
cp -p "${OSX_inst_base_dmg%.dmg}.chunklist" "$OSX_inst_img_rw_mnt/" || exit_with_error "Copying BaseSystem.chunklist failed"
stage_end_ok

stage_start "Replacing Packages symlink with real files"
rm -f "$OSX_inst_img_rw_mnt/System/Installation/Packages" || exit_with_error "Deleting Packages symlink failed"
cp -pPR "$OSX_inst_inst_dmg_mnt/Packages" "$OSX_inst_img_rw_mnt/System/Installation/" || exit_with_error "Copying Packages failed"
stage_end_ok

stage_start "Configuring image as bootable"
OSX_inst_img_rw_CoreSrv="$OSX_inst_img_rw_mnt/System/Library/CoreServices" || exit_with_error
if bless --folder "$OSX_inst_img_rw_CoreSrv" \
    --file "$OSX_inst_img_rw_CoreSrv/boot.efi" --openfolder "$OSX_inst_img_rw_mnt" --label "Install $OSX_inst_name"; then
    stage_end_ok
else
    stage_end_warn "Failed, image may not be bootable"
fi

stage_start_nl "Unmounting InstallESD.dmg"
hdiutil detach "$OSX_inst_inst_dmg_mnt" -force || exit_with_error "Can't unmount InstallESD.dmg"
unset OSX_inst_img_rw_dev
stage_end_ok "Unmointing succeed"

stage_start_nl "Unmounting writable images"
hdiutil detach "$OSX_inst_img_rw_mnt" -force || exit_with_error "Can't unmount writable image"
unset OSX_inst_img_rw_dev
stage_end_ok "Unmointing succeed"

insert_version_into_name() {
    [[ -n "$1" ]] && [[ -n "$2" ]] || return 1
    local name="$1"
    local version="$2"
    local result
    local ins_aft
    if [[ "$name" =~ (^|[[:space:]])"OS X"($|[[:space:]]) ]]; then
        ins_aft="OS X"
    elif [[ "$name" =~ (^|[[:space:]])"MacOS X"($|[[:space:]]) ]]; then
        ins_aft="MacOS X"
    fi
    if [[ -n "$ins_aft" ]]; then
        result=$(echo -n "$name" | sed -n -e 's|^\(.*[[:<:]]'"$ins_aft"'[[:>:]]\).*$|\1|p') || return 2
        [[ -z "$result" ]] && return 2
        result+=" $version" # allow any regex/special symbols in $version
        result+=$(echo -n "$name" | sed -n -e 's|^.*[[:<:]]'"$ins_aft"'[[:>:]]\(.*\)$|\1|p') || return 2
    else
        result="$name (OS X $version)"
    fi
    [[ -z "$result" ]] && return 1
    echo "$result"
    return 0
}

stage_start "Checking for output directory and image name"
unset iso_name out_dir test_name || exit_with_error
if [[ -z "$cmd_par_iso" ]]; then
    iso_name="$(insert_version_into_name "$OSX_inst_name" "$OSX_inst_ver")" || exit_with_error "Script internal error"
    iso_name="Install_${iso_name// /_}.iso"
    if [[ -z "$work_dir" ]] || [[ ! -w "$work_dir/" ]]; then
        [[ -n "$HOME" ]] &&    out_dir="$HOME/Desktop" # use Desktop as fallback
        if [[ -z "$out_dir" ]] || [[ ! -w "$out_dir/" ]]; then
            # use script location directory as fallback
            script_path="$(dirname "${BASH_SOURCE[0]}" 2>/dev/null)"
            [[ -n "$script_path" ]] || script_path="${0%/*}"
            [[ -n "$script_path" ]] && out_dir="$(cd "$script_path"2 2>/dev/null && pwd)"
        fi
        [[ -n "$out_dir" ]] && [[ -w "$out_dir/" ]] || out_dir="${0%/*}"
        [[ -n "$out_dir" ]] && [[ -w "$out_dir/" ]] || exit_with_error "Can't find writable output directory"
        stage_end_warn "Directory \"$work_dir\" seems to be unwritable, \"$out_dir/$iso_name\" will be used for output"
    else
        out_dir="$work_dir"
        stage_end_ok "$work_dir/$iso_name"
    fi
else
    test_name="${cmd_par_iso}"
    [[ "${test_name:0:1}" == "/" ]] || test_name="$work_dir/$test_name"
    if [[ -d "$test_name" ]] || [[ "${test_name%/}" != "${test_name}" ]]; then
        # cmd_par_iso is output directory without filename
        out_dir="${cmd_par_iso%/}"
    else
        iso_name="${cmd_par_iso##*/}"
        if [[ "$iso_name" == "$cmd_par_iso" ]]; then
            out_dir="$work_dir"
        else
            out_dir="${cmd_par_iso%/*}"
        fi
    fi

    if [[ -z "$iso_name" ]]; then
        iso_name="$(insert_version_into_name "$OSX_inst_name" "$OSX_inst_ver")" || exit_with_error "Script internal error"
        iso_name="Install_${OSX_inst_name// /_}.iso"
    fi
    iso_name="${iso_name%.iso}.iso"
      
    [[ "${out_dir:0:1}" == "/" ]] || [[ -z "$out_dir" ]] || out_dir="$work_dir/${out_dir}" # relative path
    [[ -d "$out_dir/" ]] || mkdir "$out_dir/" || exit_with_error "Can't create specified output directory."
    unset test_name || exit_with_error
    test_name="$(cd "$out_dir/" 2>/dev/null && pwd)"
    [[ -n "$test_name" ]] && out_dir="$test_name" # replace with absolute path if possible
    stage_end_ok "specified on command line: \"$out_dir/$iso_name\""
fi

stage_start_nl "Converting editable image to .iso"
unset iso_created || exit_with_error
OSX_inst_result_image_ro="$out_dir/$iso_name" || exit_with_error
OSX_inst_result_flag="$tmp_dir/output_image_is_ready" || exit_with_error
rm -f "$OSX_inst_result_flag" || exit_with_error
[[ -e "$OSX_inst_result_image_ro" ]] && exit_with_error "\"$OSX_inst_result_image_ro\" already exist"
makehybrid_errout="$tmp_dir/hdiutil_makehybrid_erroutput" || exit_with_error
{ { hdiutil makehybrid -o "$OSX_inst_result_image_ro" "$OSX_inst_img_rw" -hfs -udf -default-volume-name "$OSX_inst_prt_name" 2>&1 1>&3 && \
    touch "$OSX_inst_result_flag"; } | tee "$makehybrid_errout"; } 3>&1 1>&2 # output stderr to stderr and save it to file at the same time
if ! [[ -e "$OSX_inst_result_flag" ]]; then
    if fgrep -Fiqs -e 'Operation not permitted' "$makehybrid_errout" && [[ "$have_su_rights" != "yes" ]]; then
        echo_warning "Creation of optimal .iso image failed without super user rights."
        if [[ "$allow_sudo" == "yes" ]]; then
            rm -f "$OSX_inst_result_image_ro"
            echo_warning "Next command will be executed with sudo, you may be asked for password."
            $sudo_prf hdiutil makehybrid -o "$OSX_inst_result_image_ro" "$OSX_inst_img_rw" -hfs -udf -default-volume-name "$OSX_inst_prt_name" && touch "$OSX_inst_result_flag"
        else
            echo_warning "Usage os sudo was disabled by command parameter"
        fi
    fi
fi
if [[ -e "$OSX_inst_result_flag" ]]; then
    img_bootable='yes'
    stage_end_ok "Converting succeed"
else
    rm -f "$OSX_inst_result_image_ro"
    stage_end_warn "Creation of optimal .iso was failed, will try to use workarounds to build usable .iso"
    [[ "$img_bootable" != 'yes' ]] && echo_warning "Resulting image may not be bootable"
  
    stage_start "Shrinking image"
    if hdiutil resize -sectors min "$OSX_inst_img_rw" -nofinalgap; then
        stage_end_ok "succeed"
    else
        stage_end_warn "failed, image remains larger than required"
    fi

    stage_start_nl "Converting image to .iso-like format"
    OSX_inst_result_tmp_image="${OSX_inst_result_image_ro%.iso}.cdr" || exit_with_error
    [[ -e "$OSX_inst_result_tmp_image" ]] && OSX_inst_result_tmp_image="$tmp_dir/tmp_cdr_img.cdr"
    hdiutil convert "$OSX_inst_img_rw" -format UDTO -o "$OSX_inst_result_tmp_image" && \
        mv -vn "$OSX_inst_result_tmp_image" "$OSX_inst_result_image_ro" && iso_created='yes'
    if [[ "$iso_created" != "yes" ]]; then
        rm -f "$OSX_inst_result_tmp_image"
        rm -f "$OSX_inst_result_image_ro"
        exit_with_error "Image converting failed"
    fi
    stage_end_ok "Converting succeed"
fi

echo_enh "
Resulting .iso location:"
echo "$OSX_inst_result_image_ro
"
[[ "$img_bootable" != 'yes' ]] && echo_warning "Resulting .iso may not be bootable"
 

Attachments

  • create_osx_install_iso.sh.zip
    7.4 KB · Views: 950
Last edited:
  • Like
Reactions: Sappharad

vikas027

macrumors newbie
Jul 30, 2014
19
1
I used a modified script that produces an auto-sized ISO image.

For the 10.11 installation the size of the ISO is only 7502405632 bytes.

It seems to work, but feel free to make improvements!

Code:
#!/bin/bash

# Mount the installer image
hdiutil attach /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app

# Create a ElCapitan blank ISO image of 9900mb with a Single Partition - Apple Partition Map
hdiutil create -o /tmp/ElCapitan.cdr -size 9900m -layout SPUD -fs HFS+J

# Mount the ElCapitan blank ISO image
hdiutil attach /tmp/ElCapitan.cdr.dmg -noverify -nobrowse -mountpoint /Volumes/install_build

# Restore the Base System into the ElCapitan blank ISO image
asr restore -source /Volumes/install_app/BaseSystem.dmg -target /Volumes/install_build -noprompt -noverify -erase

# Remove Package link and replace with actual files
rm /Volumes/OS\ X\ Base\ System/System/Installation/Packages
cp -rp /Volumes/install_app/Packages /Volumes/OS\ X\ Base\ System/System/Installation/

# Copy El Capitan installer dependencies
cp -rp /Volumes/install_app/BaseSystem.chunklist /Volumes/OS\ X\ Base\ System/BaseSystem.chunklist
cp -rp /Volumes/install_app/BaseSystem.dmg /Volumes/OS\ X\ Base\ System/BaseSystem.dmg

# Unmount the installer image
hdiutil detach /Volumes/install_app

# Unmount the ElCapitan ISO Image
hdiutil detach /Volumes/OS\ X\ Base\ System/

# Create a sparseimage and auto-size it
hdiutil convert /tmp/ElCapitan.cdr.dmg -format UDSP -o /tmp/ElCapitan
hdiutil resize -size `hdiutil resize -limits /tmp/ElCapitan.sparseimage | tail -n 1 | awk '{ print $1 }'`b /tmp/ElCapitan.sparseimage

# Convert the ElCapitan sparseimage to ISO/CD master
hdiutil convert /tmp/ElCapitan.sparseimage -format UDTO -o /tmp/ElCapitan

# Remove the unwanted images
rm /tmp/ElCapitan.cdr.dmg
rm /tmp/ElCapitan.sparseimage

# Rename the ElCapitan ISO image and move it to the desktop
mv /tmp/ElCapitan.cdr ~/Desktop/ElCapitan.iso

Awesome, thank you so much for sharing the details steps. I followed these steps on my OS X 10.7 VM and the ISO created from "Install OS X El Capitan.app.dmg" worked perfectly on VMware Fusion 8.0.1.
 

foobatbar

macrumors newbie
Nov 22, 2015
3
0
The ISO image I create using the provided scripts don't seem to be bootable in either vmware or virtualbox. Gnu File doesn't show that the iso is bootable.

What am I doing wrong?
 

flowrider

macrumors 604
Nov 23, 2012
7,240
2,965
Even though the el capitan installer says it is 6.08 GB which would make you think it should fit onto a dual layer dvd just like it can be done for yosemite, there is other invisible stuff copied over making it bootable which would make it much bigger than 6.08 GB. So will it even fit onto a dual layer dvd - replete with all this other stuff? Maybe. Maybe not.

So if I fail to fit el capitan with all the other invisible files too onto dvd I might make a bootable bluray instead.

I made an El Cap installer using an 8GB Flash Drive. I just plugged it in and checked how much space it consumed - It took 6.19GB, so I would assume man 8.5GB Dual Layer DVD would not be a problem.

Lou
 

heini66

macrumors newbie
Dec 9, 2015
1
0
got it booting up in a virtualbox. but: it gives me only a terminal screen and won't show up the gui for language and partitioning. what? am i doing wrong?
 

Tajmorgen

macrumors newbie
Jan 3, 2016
1
0
Here is the tweaked script I used to make an El Capitan Bootable ISO for VMware.
Using it with Workstation 12 - works great!

#!/bin/bash

# Mount the installer image
hdiutil attach /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app

# Create the ElCapitan Blank ISO Image of 7316mb with a Single Partition - Apple Partition Map
hdiutil create -o /tmp/ElCapitan.cdr -size 7316m -layout SPUD -fs HFS+J

# Mount the ElCapitan Blank ISO Image
hdiutil attach /tmp/ElCapitan.cdr.dmg -noverify -nobrowse -mountpoint /Volumes/install_build

# Restore the Base System into the ElCapitan Blank ISO Image
asr restore -source /Volumes/install_app/BaseSystem.dmg -target /Volumes/install_build -noprompt -noverify -erase

# Remove Package link and replace with actual files
rm /Volumes/OS\ X\ Base\ System/System/Installation/Packages
cp -rp /Volumes/install_app/Packages /Volumes/OS\ X\ Base\ System/System/Installation/

# Copy El Capitan installer dependencies
cp -rp /Volumes/install_app/BaseSystem.chunklist /Volumes/OS\ X\ Base\ System/BaseSystem.chunklist
cp -rp /Volumes/install_app/BaseSystem.dmg /Volumes/OS\ X\ Base\ System/BaseSystem.dmg

# Unmount the installer image
hdiutil detach /Volumes/install_app

# Unmount the ElCapitan ISO Image
hdiutil detach /Volumes/OS\ X\ Base\ System/

# Convert the ElCapitan ISO Image to ISO/CD master (Optional)
hdiutil convert /tmp/ElCapitan.cdr.dmg -format UDTO -o /tmp/ElCapitan.iso

# Rename the ElCapitan ISO Image and move it to the desktop
mv /tmp/ElCapitan.iso.cdr ~/Desktop/ElCapitan.iso

Okay but when im trying to open the install file in my Mac mavericks in virtualbox it says "This method to install of the operating system is not supported" "start the program Installer OS X El capitan.app, that you downloaded from app store"

What am i going to do here?
 

iMacDragon

macrumors 68020
Oct 18, 2008
2,360
707
UK
Thanks, script seems to be working for me.. as vmware's inbuilt installer script was failing.
 

SignedAdam

macrumors newbie
Sep 30, 2016
6
2
London
Can we have all the methods above updated for macOS Sierra,

I would like to put macOS Sierra on a dvd disk, and for anyone asking why, dvds cant be corrupted unless you mark them, which wont happen if you take care of them, where as with a usb stick, the data can be deleted, and corrupted, or even formatted, usb ports can also brake, some computers only have two, (wheres the mpuse and keyboard going to go)
 
Last edited:

tywebb13

macrumors 68030
Apr 21, 2012
2,948
1,636
Can we have all the methods above updated for macOS Sierra,

I would like to put macOS Sierra on a dvd disk, and for anyone asking why, dvds cant be corrupted unless you mark them, which wont happen if you take care of them, were as with a usb stick, the data can be deleted, and corrupted, or even formatted, usb ports can also brake, some computers only have two, (wheres the mpuse and keyboard going to go)

I already made a bootable sierra dvd installer and posted instructions here: https://forums.macrumors.com/threads/bootable-dvd-for-sierra-installer.1999385/

Furthermore I tested it out by using it to actually install sierra.

It works.
 
Last edited:

VaZ

macrumors 6502
Aug 31, 2012
317
84
Here are the commands to make it bootable on actual Mac hardware:

hdiutil attach /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app

hdiutil create -o /tmp/ElCapitan.cdr -size 7200m -layout SPUD -fs HFS+J

hdiutil attach /tmp/ElCapitan.cdr.dmg -noverify -nobrowse -mountpoint /Volumes/install_build

asr restore -source /Volumes/install_app/BaseSystem.dmg -target /Volumes/install_build -noprompt -noverify -erase

rm /Volumes/OS\ X\ Base\ System/System/Installation/Packages

cp -rp /Volumes/install_app/Packages /Volumes/OS\ X\ Base\ System/System/Installation/

cp -rp /Volumes/install_app/BaseSystem.chunklist /Volumes/OS\ X\ Base\ System/BaseSystem.chunklist

cp -rp /Volumes/install_app/BaseSystem.dmg /Volumes/OS\ X\ Base\ System/BaseSystem.dmg

hdiutil detach /Volumes/install_app

hdiutil detach /Volumes/OS\ X\ Base\ System/

hdiutil convert /tmp/ElCapitan.cdr.dmg -format UDTO -o /tmp/ElCapitan.iso

mv /tmp/ElCapitan.iso.cdr ~/Desktop/ElCapitan.iso
 
Last edited:

Poetnerd

macrumors newbie
Jun 27, 2023
2
0
Here are the commands to make it bootable on actual Mac hardware:

hdiutil attach /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app

hdiutil create -o /tmp/ElCapitan.cdr -size 7200m -layout SPUD -fs HFS+J

hdiutil attach /tmp/ElCapitan.cdr.dmg -noverify -nobrowse -mountpoint /Volumes/install_build

asr restore -source /Volumes/install_app/BaseSystem.dmg -target /Volumes/install_build -noprompt -noverify -erase

rm /Volumes/OS\ X\ Base\ System/System/Installation/Packages

cp -rp /Volumes/install_app/Packages /Volumes/OS\ X\ Base\ System/System/Installation/

cp -rp /Volumes/install_app/BaseSystem.chunklist /Volumes/OS\ X\ Base\ System/BaseSystem.chunklist

cp -rp /Volumes/install_app/BaseSystem.dmg /Volumes/OS\ X\ Base\ System/BaseSystem.dmg

hdiutil detach /Volumes/install_app

hdiutil detach /Volumes/OS\ X\ Base\ System/

hdiutil convert /tmp/ElCapitan.cdr.dmg -format UDTO -o /tmp/ElCapitan.iso

mv /tmp/ElCapitan.iso.cdr ~/Desktop/ElCapitan.iso
I'm trying to create a recovery DVD for the new owner of a legacy 13inch MacBook Pro I'm going to give away. I followed this procedure, and created a DVD. The first time I booted it, it worked (although the start-up screen was wierd). Subsequent bootups simply hang at the end. This is different from the bootable DVD I created without taking care to use Apple Partition Map or limit size. That hung too, but with the progress bar not all the way filled.

Is it possible that there's still some missing initialization?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.