Skip to content

Instantly share code, notes, and snippets.

@durkinza
Forked from afgomez/dmginstall.sh
Last active May 23, 2025 20:04
Show Gist options
  • Select an option

  • Save durkinza/ca7e1aa02bd4901c08c496d97d2e0daa to your computer and use it in GitHub Desktop.

Select an option

Save durkinza/ca7e1aa02bd4901c08c496d97d2e0daa to your computer and use it in GitHub Desktop.
Download and install a .dmg
#!/bin/bash --login
# Installs an application from .dmg from a URL or path
#
# For example, for installing wireshark version 3.0.2
# $ dmginstall -u https://1.na.dl.wireshark.org/osx/Wireshark%203.0.2%20Intel%2064.dmg
# or for firefox version 68.0
# $ dmginstall -u https://download-installer.cdn.mozilla.net/pub/firefox/releases/68.0/mac/en-US/Firefox%2068.0.dmg
# for backblaze
# $ dmginstall -u https://secure.backblaze.com/groups/install_backblaze.dmg -s Backblaze\ Installer.app/Contents/MacOS/bzinstall_mate -- -nogui -createaccount_or_signinaccount <email> <groupid> <grouptoken>
VERBOSE=false
Failed=false
apps_folder='/Applications'
execute_file=''
URL=''
file_path=''
args=()
function usage() { echo "Usage: $0 [-v] [-h] [-s] (-f <path_to_package> | -u <url_to_package>) -- [<additional args to pass to dmg file>]
-h This help menu
-u The URL to the dmg to pull.
-f The local dmg file to use.
-s (optional) Run specific script in .dmg. Default the .app in the dmg will be copied over to applications directory.
-v Verbose mode, show debugging info" 1>&2; exit 1; }
while getopts "vhu:f:s:" opts; do
case ${opts} in
v) VERBOSE=true ;;
h) usage ;;
u) URL=$OPTARG;;
f) file_path=$OPTARG;;
s) execute_file=$OPTARG;;
*) usage ;;
esac
done
# Shift off the options and the `--`
shift $((OPTIND - 1))
if [[ "$1" == "--" ]]; then
shift
fi
# some functions to use for output.
function Announce(){
Spacer='\n=======================================\n'
printf "\n$Spacer$*$Spacer"
}
function Say(){
Spacer='\n---------------------------------------\n'
printf "\n$Spacer$*$Spacer"
}
function Debug(){
if $VERBOSE; then
printf "\nDEBUG: $*\n"
fi
}
# Generate a random file name
tmp_file=/tmp/`openssl rand -base64 10 | tr -dc '[:alnum:]'`.dmg
Debug "Temporary file is: $tmp_file"
# bootstrapping done, lets start intalling
if [ -n "$URL" ]; then
# Download file
Announce "Downloading."
echo "From: $URL"
curl -# -L -o $tmp_file $URL
else
if [ ! -n "$file_path" ]; then
echo "ERROR: At least one of -u or -f must be provided" >&2;
exit 1
fi
Announce "Using: $file_path"
cp $file_path $tmp_file
fi
Announce "Mounting image."
# Mount the package and save disk and volume locations
app_location=$(hdiutil attach $tmp_file | tail -n 1)
# Get disk of the mounted package. e.x. /dev/disk3s3
app_disk=$(echo $app_location | awk '{print $1}')
# Get the Volume of the package. e.x. /Volumes/Wireshark
app_volume=$(echo $app_location | awk '{$1="";$2="";print $0}' | xargs)
# Determine the file we want to install and get file type of that file
file_type=$(find "$app_volume/" -regex '.*.[app|pkg]' -maxdepth 1 | head -n 1 | tr "." "\n" | tail -n 1)
# Some Debugging to make sure we're on the right track.
Debug "App Location: $app_location"
Debug "App Disk: $app_disk"
Debug "App Volume: $app_volume"
if [ -n "$execute_file" ]; then
Debug "Execute File: $app_volume/$execute_file"
fi
Debug "Execute Args: $@"
Announce "Installing."
if [ -n "$execute_file" ]; then
Say "Calling $execute_file $@"
"$app_volume/$execute_file" $@
elif [ ! $file_type != 'pkg' ]; then
echo "Installing pkg..."
# pkg can be installed with mac's built in installer
/usr/sbin/installer -pkg "$app_volume/*.pkg" -target /
elif [ ! $file_type != 'app' ]; then
echo "Installing app..."
# app can be installed by copying directory over to applications directory
app=`find "$app_volume/." -name *.app -maxdepth 1 -type d -print0`
cp -ir "$app" $apps_folder
else
echo "Installation failed." >&2;
echo "Error: $file_type is not supported." >&2;
Failed=true
fi
Announce "Cleaning up..."
Debug "un-mounting image"
detach=$(hdiutil detach $app_disk)
Debug "Removing temp file"
rm $tmp_file
# Wait until after un-mounting to throw error
if $Failed; then
echo "Error installing."
exit 1;
else
Announce "Install Completed"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment