Mac OS X

From HerzbubeWiki
Jump to navigation Jump to search

A wild assortment of information about macOS (formerly Mac OS X), accumulated over many years. Be prepared to meet wildly out of date information.

Sections that were clearly obsolete have been removed - check the page history

Information & Tools


  • GetFileInfo displays type/creator and various other attributes
  • SetFile can be used to change type/creator, e.g. SetFile -c -t

Note: I think these utilities are from the Developer Tools.

Copy resource forks in

The following command copies an entire directory tree, including any resource forks and other HFS meta data:

ditto -rsrc /source-dir /dest-dir

Another possibility is CpMac from the Command Line Developer Tools. Currently no example is available.

Clear the immutable flag

On older versions of Mac OS X it often happened that there were files/directories in the Trash that prevented emptying the Trash. This was caused by these files/directories having set the so-called "user immutable" flag (or "uchg" flag).

/usr/bin/chflags can be used to clear the user immutable flag, and manipulate other flags as well, in

# cd ~/.Trash
# sudo /usr/bin/chflags -R nouchg *


  • Jedes Volume hat einen eigenen Ordner .Trashes. Der Ordner .Trashes des System-Volumes scheint dabei aber nicht benutzt zu werden, statt dessen wird der Ordner .Trash im Home-Verzeichnis des gerade eingeloggten Users verwendet (bei root: /private/var/root/.Trash)
  • in den Ordnern .Trashes wird fuer jeden User ein Unterverzeichnis mit seiner User-ID als Namen angelegt. Fuer das Startvolume ist dies nicht noetig, da hier fuer jeden User ein eigener Ordner $HOME/.Trash verwendet wird (entweder in /Users fuer normale User, oder in /private/var/root fuer root)
  • falls eine Datei gleichen Namens mehrmals auf dem gleichen Volume geloescht wird, wird die zweite geloeschte Datei dagegen mit dem Anhaengsel "Kopie" versehen und in $HOME/.Trash verschoben; die dritte geloeschte Datei erhaelt das Anhaengsel "Kopie 2"; etc.. Beim Rueckgaengig-Machen des Loeschens ab der zweiten Datei geraet MacOS? X ins Schleudern und erzeugt am Original-Ort 2 Dateien: die Datei mit dem richtigen Original-Namen ist leer (!!!) vorhanden, die Datei mit dem Anhaengsel existiert jetzt aber ebenfalls am Original-Ort und hat den richtigen Inhalt.Offenbar wird hier die Datei mit dem Anhaengsel zuerst aus dem Trash an den Original-Ort zurueckverschoben und soll dann auf den Original-Namen umkopiert werden. Das Umkopieren schlaegt aber aus irgendeinem Grund fehl, es bleibt einzig eine leere Datei mit dem Original-Namen zurueck. Diese Datei kann nun uebrigens auch nicht mehr geloescht werden, es wird eine Fehlermeldung ausgegeben! (dies geschieht nicht, wenn man eine normal erzeugte, leere Datei zu loeschen versucht, die den gleichen Namen wie eine Datei im Trash hat)

Deutsche Tastaturbelegung auf der Shell

Damit Umlaute der deutschen Tastaturbelegung auf der Shell (bash) funktionieren, müssen folgende Einstellungen gemacht werden:

  1. Terminal Preferences ("Fenstereinstellungen"):
    • Im Bereich "Monitor" die Zeichensatz-Kodierung auf UTF-8 setzen
  2. In $DIRETC/setenv folgende Einstellung vornehmen (Kommentar stammen von der man Page von stty):
# cs8: set character size
# -istrip: do not strip input characters to 7 bits
# -parenb: disable parity generation and detection
stty cs8 -istrip -parenb
  1. In $DIRETC/linked.inputrc folgende Einstellungen vornehmen (Kommentare stammen aus der man Page von bash). Hinweis: in Tat und Wahrheit sind nicht alle 3 Settings nötig, aber ich weiss nicht wirklich, welches Setting welche Auswirkung hat. Wenn alle 3 Settings gemacht werden, dann funktioniert's jedenfalls:
# If set to "on", readline converts 8-bit characters
# to 7-bit characters (i.e. remove the 8th bit) and
# prefix the character with an escacpe character
set convert-meta off
# If set to "on", readline enables 8-bit input
# (i.e. it doesn't strip the 8th bit from the input)
# regardless of what the terminal claims it can
# support
set input-meta on
# If set to "on", readline displays 8-bit characters
# directly instead of as an escape sequence
set output-meta on
  1. In $HOME/.vimrc folgende Einstellung machen:
set encoding=utf-8

Probleme mit Disks

Als root:

pdisk /dev/rdisk[012...] -dump

gibt die Partitions-Tabelle der "raw disk" 0, 1, 2, ... aus. Nummer 0 ist dabei die eingebaute Disk, 1 das interne DVD, 2 z.B. die externe FireWire Disk. Um vom Output auf das effektive raw device zu kommen, einfach die in Spalte "#" aufgelistete Nummer für die gewünschte Partition verwenden, also z.B. /dev/rdisk0s2


Set environment variables for all processes spawned by a user's login session


There is a special environment file which loginwindow searches for each time a user logs in. The environment file is:


For each environment variable add a sibling to the plist file with a key of class string.

Update: This can be comfortably managed with the RCEnvironment preference pane.

Eject CD-ROM in

To eject a disk (replace "#" with the correct disk number for the CD-ROM drive):

diskutil -eject /path/to/device

To list all disks currently mounted:

diskutil list

Manage DNS cache

In Mac OS X 10.5 and later the utility is dscacheutil, in Mac OS X 10.4 and earlier the utility is lookupd.

For instance, to flush the cache:

dscacheutil -flushcache   # 10.5 and later
lookupd -flushcache       # 10.4 and earlier

Manipulate firmware NVRAM variables

Note: See the man page of the nvram utility for more details.

Print all firmware NVRAM variables:

nvram -p

See the value of a specific variable:

nvram variable-name
nvram boot-args   # displays boot arguments

Set the value of a variable:

nvram variable-name = value
nvram boot-args = "-v"   # always boot in verbose mode

Remove a variable:

nvram -d variable-name

Known variables and values:

  • TODO
  • SystemAudioVolume

Execute AppleScripts from the command line

Use osascript to execute an AppleScript from the command line in a fashion similar to how you would run an awk program:

osascript -e 'return "hello world"'
osascript helloworld.scpt
cat helloworld.scpt | osascript

Use osacompile to generate a compiled version of a script:

osacompile -o helloworld.scpt

See each command's man page for more details.

Running things automatically


I have started writing this chapter out of irritation with the multitude of options there are on Mac OS X when something should be made to run in an automated way. Startup Items, Login Items, Login Hooks, launchd, cron? On one hand, it is always good to have options, on the other hand, having too many options just makes the world more confusing. This is especially true if one needs to remember which options are valid on which versions of the operation system.


[1] TN2083
Technical Note TN2083 - Daemons and Agents.
[2] Introduction to System Startup Programming Topics
Interesting document for writing software that needs to be launched at boot time or at user login time. Also contains a detailed description of the boot process.
[3] Introduction to Multiple User Environments
Background information about the multiple user environment of Mac OS X. Especially interesting is the "Root and Login Sessions" chapter.


The Mach initialization process. mach_init on 10.3 and earlier, launchd on 10.4 and later.
Created and managed by mach_init. mach_init assigns each new process to a session. The main types are root session and login session.
Background program
A program that runs in the background, without presenting any significant GUI. There are two types of background programs: Daemons and Agents.
A system wide background program that is not associated with a specific user. Note that a daemon process is not necessarily a "daemonized" process.
A background program that works on behalf of a specific user. As opposed to a daemon, an agent can connect to the window server and has access to the user's home directory.
Daemonization, daemonize
A process that is daemonized has been detached from its parent process and the environment it provides (e.g. it is no longer attached to a tty). The daemonized process is now a child of the top-level launchd process. The process is still owned by whoever started it (unless the process itself changes its uid).
launchd daemon
A daemon launched by launchd (yeah, I know...).
launchd agent
An agent launched by launchd on behalf of a specific user.
Login Item
A program that is launched when a user logs in using the GUI. There are global login items (deprecated, see System Login Item) and per-user login items.
Startup Item
A daemon launched during system startup by the SystemStarter program. Deprecated in favour of launchd.
mach_init daemon
A daemon launched by mach_init from the /etc/mach_init.d. Deprecated in favour of launchd, and unsupported by Apple in the first place.
mach_init agent
An agent launched on behalf of a specific user by loginwindow from the /etc/mach_init_per_user.d. Deprecated in favour of launchd, and unsupported by Apple in the first place.
inetd/xinetd daemon
A daemon launched by the "Internet Super Server" (originally inetd and later xinetd). Deprecated in favour of launchd.
System Login Item
A global login item that is launched in each GUI login session before the user logs in. Deprecated in favour of launchd.


[1] and also [2]: mach_init refers to the Mach initialization process. This has been the mach_init process on 10.3 and earlier, and is now the launchd process on 10.4 and later.

[3] "mach_init program": Although I have not found a definitive statement, I assume that references to the "mach_init program" once were meant to talk about the actual mach_init process, but nowadays should be read as references to launchd.

[1] "mach_init daemon": A mach_init daemon is launched by the Mach initialization process. A mach_init daemon is installed by placing a property list file in the /etc/mach_init.d directory. Apple does not support third party development of mach_init daemons. Starting with 10.5, mach_init daemons are deprecated in favor of launchd daemons.



Information in this section comes from [3].

Processes are associated with either the root session or a login session. mach_init assigns each new process to an appropriate session based on factors such as who created the process and when.

Root session

The root session is the first session to be created and the last to be destroyed. Only one root session ever exists on the system, and it is where most boot-time processes and daemons live. Processes in the root session are allowed to provide services to all users of the system. For example, lookupd and the mDNSResponder process both run in the root session.

As the window server does not live in the root session, a daemon or other program that runs in the root session does not have access to the window server. For this reason, no system frameworks that rely on the window server can be used to implement a program that is intended to run in the root session.

Login sessions

A new login session is created when a user logs in, either locally through the login window (a so-called "console login") or remotely through ssh. Processes launched by a user or for a user's benefit live in a login session. Each login session is associated with an authenticated user. The system may have multiple login sessions active at any given time. Console login sessions include processes such as the Finder and Dock, while remote login sessions contain only shell-level processes. Most of the communication between different login sessions is restricted by mach_init. Communication is still possible but generally requires creating an explicit, and trusted, connection.

A login session remains in existence until all processes that belong to it are terminated. When a user logs out, the system attempts to terminate the processes in that user's login session. When the last process in a login session dies, the system closes out the login session and reclaims its memory. If a user process daemonizes itself prior to logout, it can live past the end of the user logout and prolong the existence of the login session. Some system services, such as the Apache web server, do this to avoid being shut down during a logout. Processes that survive the user logout continue to run in the login session. However, they must be able to run without the existence of the window server, which is terminated when the user logs out.

A login session is identified by a unique ID. This ID is the security session ID, often referred to simply as the session ID. Applications can use the session ID to distinguish among resources allocated in different login sessions. Session IDs are not persistent between user logins. Each session ID is valid only for the duration of the current login session, and it is valid for all processes in that login session. If a user logs out and logs back in, a different session ID is asssigned to the new login session. Session information is available from the Security framework (e.g. session ID) and the Core Graphics framework.

Execution Contexts


Information in this section comes from [1].

The execution context of a process determines the "capabilities" of the process, or, in other words: What the process is allowed to do. The execution context consists of several parts that affect the process in different ways:

  • UIDs and GUIDs : Determines, for instance, what files a process can open.
  • Bootstrap Namespace : Determines what services (e.g. the Dock) a process can use because it restricts how Mach messages can be sent.
  • Security Context : It appears that this is the "session" discussed in the previous chapter. Usually (but not always) for every bootstrap namespace there is also a session.

UIDs and GIDs


Bootstrap Namespace


Security Context


From boot to shutdown

This section describes the general sequence of events starting with the boot process from the time when launchd takes over, through a user login and logout, to the final system shutdown. The information comes from [2].

  1. The system boots
    1. launchd does mystical and unknown stuff
    2. launchd starts SystemStarter, which in turn starts any non-launch-on-demand daemons (i.e. StartupItems).
    3. launchd starts loginwindow
  2. The user logs in
    1. loginwindow authenticates the user and begins setting up the user environment as follows
    2. loginwindow does a lot of complicated and, in the current context, uninteresting stuff
    3. loginwindow sets up user preferences, environment variables, keychain access, etc.
    4. loginwindow launches Dock, Finder and SystemUIServer
    5. loginwindow launches Login Items (experimentally confirmed order: Login Hook, Global Login Item, per-user Login Item)
  3. The user logs out
    1. loginwindow terminates all foreground processes (i.e. GUI applications) in an orderly manner; background processes are given a courtesy warning so that they may shutdown themselves gracefully, but if they do not respond promptly are then brutally killed by sending the SIGKILL signal
    2. loginwindow launches the Logout Hook program
  4. The system shuts down
    1. Services provided by SystemStarter startup items are shut down
    2. All processes are sent the SIGTERM signal
    3. All processes that are still around after a few seconds are sent the SIGKILL signal

Startup Item

Note: Startup Items are deprecated since 10.4 in favour of launchd (launchd daemon).

Startup Items are defined in


Startup Items are launched by the SystemStarter utility (/sbin/SystemStarter, also read its man page man SystemStarter) when the system starts up.

Startup Items have the following execution context:

  • UID = root
  • bootstrap namespace = global
  • security context = global (i.e. the root session)

Login/Logout Hook

Information in this section comes from [2].

loginwindow can be configured to execute a program each time any user logs in or logs out. Only one of these hooks can be installed at a time. For this reason, login/logout scripts are not recommended for deployment and should be used only by a local system administrator who has control over the environment.

When creating your script file, keep the following in mind:

  • Place the file in a location that is accessible to all users (e.g. /Library/Management/LoginHooks)
  • The permissions for your script file should include execute privileges for the appropriate users.
  • Scripts launched by loginwindow are run as root.
  • In your script, the variable $1 returns the short name of the user who is logging in.
  • Other login/logout actions wait until your hook finishes executing. Therefore, have your script do what it needs to do quickly and then exit.

To activate the hook, issue the following command in

sudo defaults write LoginHook /path/to/script
sudo defaults write LogoutHook /path/to/script

To activate the hook, issue the following command in

sudo defaults delete LoginHook
sudo defaults delete LogoutHook

The hooks are written to / removed from the preferences file


Note: If no such plist file, this method will not work. The file notably does not exist on a fresh installation of Mac OS X, until the user changes a login window setting (such as turning on fast user switching).

Login/Logout Hooks have the following execution context:

  • UID = root
  • bootstrap namespace = ?
  • security context = ?

System Login Item

Note: System Login Items are deprecated since 10.5 in favour of launchd (pre-login agent).

Note: System Login Items are not documented [very well]. They are mentioned in [1], but there is no hint about how they are installed. One of the better threads on the subject can be found here. The thread also quotes an email from Apple Support that says that System Login Items have been entirely removed from 10.6.

A System Login Item is a Global Login Item that is launched in each GUI login session before the user logs in. A System Login Item is useful if you need to use the window server while the login screen is displayed. While the loginwindow displays, the program is run with UID 0 (root), however when the user logs in the program is terminated and then re-launched with the user's UID.

System Login Items are installed in an array named "AutoLaunchedApplicationDictionary" inside the file:


The following command lists all System Login Items (note that we use the file name without the .plist extension):

defaults read /Library/Preferences/

The following command installs a single System Login Item (note that we use the file name without the .plist extension). Warning: If other items exist they are overwritten by the command.

defaults write /Library/Preferences/ AutoLaunchedApplicationDictionary -array-add '{ "Path" = "/path/to/script"; "Hide" = 0; }'

System Login Items have the following execution context:

  • UID = root
  • bootstrap namespace = pre-login
  • security context = pre-login

Global and per-user Login Items

Note: Global Login Items have officially become available with 10.5. Prior versions may also have had such a feature, but if so it was kept under the hood. Looking at how Global Login Items work, it is reasonable to assume that System Login Items were their predecessor.

A Login Item is a program that is launched when a user logs in. Installing a Global Login Item is roughly equivalent to installing it as a per-user Login Item for all users on the system. Every time a user logs in, loginwindow launches that user's Login Items and all Global Login Items.

Global Login Items and per-user Login items are installed in an array named "AutoLaunchedApplicationDictionary" inside one of the files:

/Library/Preferences/loginwindow.plist    # global
~/Library/Preferences/loginwindow.plist   # per-user

The following command lists all Global or per-user Login Items (note that we use the file name without the .plist extension):

defaults read /Library/Preferences/loginwindow AutoLaunchedApplicationDictionary    # global
defaults read ~/Library/Preferences/loginwindow AutoLaunchedApplicationDictionary   # per-user

The following command installs a single Global or per-user Login Item (note that we use the file name without the .plist extension). Warning: If other items exist they are overwritten by the command.

# global
defaults write /Library/Preferences/loginwindow AutoLaunchedApplicationDictionary -array-add '{ "Path" = "/path/to/script"; "Hide" = 0; }'
# per-user
defaults write ~/Library/Preferences/loginwindow AutoLaunchedApplicationDictionary -array-add '{ "Path" = "/path/to/script"; "Hide" = 0; }'

Login Items have the following execution context:

  • UID = ?
  • bootstrap namespace = ?
  • security context = ? login session ?


[1]: "[...] modifying /etc/rc* is not a supported way of launching a daemon on Mac OS X. Rather, you should launch your daemon via launchd."



Command line utility that can be used to control launchd:


Load an agent after placing its .plist file into /Library/LaunchAgents

sudo launchctl load -D local -S Background

.plist File Examples

TODO man launchd.plist

System Integrity Protection (SIP)

Beginning with Mac OS X 10.11 (El Capitan), a new feature called "System Integrity Protection" (SIP, Wikipedia article) prevents even the root user from tampering with certain system-level files and folders. Notably, SIP prevents me from replacing the NTFS mount utility /sbin/mount_ntfs with my own version that uses a modified NTFS driver for providing write support.

The following file lists all files and folders that are protected by SIP:


The command line utility csrutil can be used to view and/or modify the SIP status. Modifying the SIP status only works while the system is booted in recovery mode. Disabling / enabling SIP modifies the NVRAM and affects the entire machine, i.e. all Mac OS X installations on that machine!

csrutil status
csrutil disable
csrutil enable

To modify the SIP status:

  • Restart the system
  • Press CMD + R while the system reboots
  • After the system has booted into the recovery environment, select the "Utilities > Terminal" menu item to launch a command line window
  • Now you can disable or enable SIP

I assume that while you are in recovery mode it would also be possible to modify rootless.conf, but I have not tested this.

NTFS write support

Simple solution

Important: Also read the next section about FUSE for OS X.

The simple solution looks like this: Install Homebrew, then execute these commands:

brew install ntfs-3g
sudo mv /sbin/mount_ntfs /sbin/mount_ntfs.original
sudo ln -s /usr/local/sbin/mount_ntfs /sbin/mount_ntfs

The mount_ntfs script that we are activating here is a simplified version of the script that appears in the next section. The Homebrew script mounts volumes with the ID of the user that is active at the time the device is plugged in.

Note: The ntfs-3g package includes a couple of useful NTFS command line utilities (the names all start with "ntfs").


At the time of writing this, the default Homebrew installation of ntfs-3g installs the deprecated Fuse4X as a dependency. Fuse4X is no longer developed or supported, its official successor is FUSE for OS X. Although FUSE for OS X can be installed via Homebrew Cask, the version installed at the time of writing this is 2.8.3, and that's too old because it has the following bugs:

  • A mounted NTFS volume does not show up in the sidebar of the Finder (or on the Desktop)
  • Dismounting an NTFS volume leaves a dangling mount point in /Volumes. See issue 119.

The solution is to manually install FUSE for OS X, version 3.2.0 or later, which fixes the two bugs. It's probably best to install this after ntfs-3g is installed via Homebrew. The sequence is this:

  • On the command line:
brew install ntfs-3g
brew uninstall fuse4x
  • Download and install the latest FUSE for OS X
  • Reboot

Complicated solution

Similar to the simple solution: Install Homebrew, then execute these commands:

brew install ntfs-3g
sudo mv /sbin/mount_ntfs /sbin/mount_ntfs.original
sudo touch /sbin/mount_ntfs
sudo chmod 0755 /sbin/mount_ntfs
sudo chown 0:0 /sbin/mount_ntfs
sudo vi /sbin/mount_ntfs

In this case we provide our own custom mount script. Copy & paste the following script into the editor:

USER_ID=502  # patrick
GROUP_ID=20  # staff

# stat returns the user ID of the owner of /dev/console
# - If this is user ID 0 (i.e. root), then all the complicated
#   stuff is executed to determine the user/group ID to be used
#   for the mount operation.
#   - If auto-login was used, then the auto-login user/group is
#     used for the mount operation
#   - If auto-login was not used, the script waits for a maximum
#     of TIMEOUT seconds and checks after every second if
#     /dev/console is owned by someone else than user ID 0. If
#     the owner is found, it is used for the mount operation.
#   - If after 20 seconds /dev/console is still owned by user ID 0,
#     the script falls back on a hard-coded default user/group ID
# - If /dev/console is owned not by user ID 0, then it is
#   assumed that the owner/group of /dev/console can be used for
#   the mount operation
if [ `/usr/bin/stat -f "%u" /dev/console` -eq 0 ]; then
        # First check if autologin was used. If so, then that
        # user/group is 
        USERNAME=`/usr/bin/defaults read /library/preferences/ | /usr/bin/grep autoLoginUser | /usr/bin/awk '{ print $3 }' | /usr/bin/sed 's/;//'`
        if [ "$USERNAME" = "" ]; then
                until [ `stat -f "%u" /dev/console` -ne 0 ] || [ $TIMEOUT -eq 0 ]; do
                        sleep 1
                        let TIMEOUT--
                if [ $TIMEOUT -ne 0 ]; then
                        USER_ID=`/usr/bin/stat -f "%u" /dev/console`
                        GROUP_ID=`/usr/bin/stat -f "%g" /dev/console`
                USER_ID=`/usr/bin/id -u $USERNAME`
                GROUP_ID=`/usr/bin/id -g $USERNAME`
        USER_ID=`/usr/bin/stat -f "%u" /dev/console`
        GROUP_ID=`/usr/bin/stat -f "%g" /dev/console`

echo "$(date $DATE_FORMAT) Attempting to mount ${VOLUME_NAME} with user $USER_ID, group $GROUP_ID" >>$LOGFILE
/opt/local/bin/ntfs-3g \
         -o volname="${VOLUME_NAME}" \
         -o local \
         -o negative_vncache \
         -o auto_xattr \
         -o auto_cache \
         -o noatime \
         -o windows_names \
         -o user_xattr \
         -o inherit \
         -o uid=$USER_ID \
         -o gid=$GROUP_ID \
         -o allow_other \
         "$@" >>$LOGFILE 2>&1
echo "$(date $DATE_FORMAT) ntfs-3g exit code = $ntfs3gExitCode" >>$LOGFILE
exit $ntfs3gExitCode

The script comes from this blog post (scroll down to the part that is titled "Fuse4x + NTFS-3G from MacPorts"). I added a few things to the original script:

  • Define LOGFILE variable and use that in various places instead of a hardcoded path
  • Define DATE_FORMAT variable to output a date/time prefix into the logfile
  • Print some diagnostics before and after ntfs-3g is invoked
  • Changed the redirection of stdout/stderr of ntfs-3g from &>$LOGFILE to >>$LOGFILE 2>&1 because I wanted to append to the logfile instead of clobbering it each time ntfs-3g is invoked

Apparently someone else found a way how to add write permission for all users, not just the one that triggered the mount. The comment by Michele De Pascalis contains a script that has the following 5 lines added to the ntfs-3g invocation. I have not yet tested this.

-o fmask=0111 \
-o dmask=0000 \
-o rw \
-o auto \
-o user \

Virtualizing Mac OS X

From what I've read on the net, Mac OS X 10.7 was the first version of the OS that allowed to run it as a guest OS within a virtualizer software - provided the virtualizer runs on Apple hardware, and the virtualized OS is used for personal, non-commercial use. I'm not sure which virtualizers support Mac OS X these days, here I am going to cover VirtualBox because it's easy to use and OSS.

I have tried out the following stuff for an installation of Mac OS X 10.11 (El Capitan), but I think the instructions should also work for older versions of the OS, because the InstallESD.dmg image file has been present in Mac OS X installer bundles since Mac OS X 10.8.

TODO: Complete the writeup

cites this as its source:

cites this as its source:

cites this as its source:

How to create a disk image that contains a macOS installer

First versions of Mac OS X

The first versions of Mac OS X - up to at around 10.6 or 10.7 - came with DVD discs. It was possible to create a disk image from the DVDs by using the Disk Utility app.

OS X 10.8 to around macOS 10.12

For these versions of OS X / macOS it is possible to copy the file


from the system installer app that was downloaded from the App Store. This file can then be used to either burn a bootable DVD, or create a bootable USB device. Disk Utility is used for both approaches.

  • Open Disk Utility app
  • Drag the InstallESD.dmg file into the left-hand sidebar.
  • If you're burning a DVD, insert the DVD, select the disk image in the sidebar and click the "Burn" button. Skip down to the last step to use it.
  • If you want to instead create a bootable USB device, plug in the USB device.
  • Select the device in the left-hand sidebar in Disk Utility.
  • Go to the Partition tab and select "1 Partition" from the dropdown menu. Choose "Mac OS Extended (Journaled) on the left.
  • Click the Options button under the partition table and choose "GUID Partition Table". This is needed to make the device bootable.
  • Click the Apply button to format the device. This will erase everything on the device.
  • Select the "Restore" tab, choose the InstallESD.dmg file as the source and the USB device as the destination.
  • Click the Apply button to write the image content onto the USB device.
  • Reboot into Mac OS X and hold the option key when you hear the startup chime. You can boot into your DVD or flash drive from there.

Since OS X 10.11 - today

Starting with OS X 10.11 the system installer app that is downloaded from the App Store contains the tool


The location within the installer app bundle varies, but the important thing is that this tool can be used to create a bootable installer, typically on an external USB device, that is capable of installing OS X / macOS on a target machine. This is even described officially by Apple in this support document. Instead of a physical USB device the installer can also be created inside a DMG image, which can then be converted to an ISO usable for booting up a virtual machine.

These are the steps (taken from that I used for creating an installer for macOS 13 (Ventura).

  • Download the installer for macOS via App Store / Software Update. The result is an installer app in /Applications.
  • Create a DMG file with sufficient size to hold the installer. Older versions of macOS used to be content with 8GB, but recent versions require up to 16GB.
hdiutil create -o Foo -size 14000m -volname Foo -layout SPUD -fs HFS+J
  • Mount the DMG file.
hdiutil attach Foo.dmg -noverify -mountpoint /Volumes/Foo
  • Write the installer data to the image. Note that the path of the createinstallmedia executable within the installer bundle varies.
sudo /Applications/Install\ macOS\ --volume /Volumes/Foo
  • Unmount the DMG file (it has a new name after createinstallmedia has written its data):
hdiutil detach /Volumes/Install\ macOS\ Foo
  • Convert the DMG file to an ISO file:
hdiutil convert Foo.dmg -format UDTO -o Foo.cdr
mv Foo.cdr Foo.iso

As mentioned above, the ISO image can now be used to mount the installer in a virtual machine, but it can also be written onto a USB device from which a real machine can be installed.

Transfer photos from iPhone to Mac

1. Connect iPhone to Mac computer 1. Launch the "Image Capture" app. The app now displays all photos that are on the iPhone. This works because iOS presents the iPhone as a camera to interested applications. 1. Select the destination folder on the Mac 1. Select "Import all"

"Image Capture" communicates with the iPhone via the so-called Picture Transfer Protocol (PTP).