Skip to content

Instantly share code, notes, and snippets.

@tjluoma
Created November 25, 2020 17:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjluoma/f35db1861b7363e98f324a8d641f2eb6 to your computer and use it in GitHub Desktop.
Save tjluoma/f35db1861b7363e98f324a8d641f2eb6 to your computer and use it in GitHub Desktop.
backup all of your Mac App Store apps
#!/usr/bin/env zsh -f
# Purpose: Create a backup of all Mac App Store apps
# NTS: like 'backup-mas-apps.sh' but without growlnotify
# From: Timothy J. Luoma
# Mail: luomat at gmail dot com
# Date: 2019-06-01
# point this to wherever you want backups to be made.
# it will be created if it does not exist
# each app will be given its own sub-folder in this folder
BACKUP_DIR="$HOME/Local/Backups/MacAppStore"
##################################################################
## ##
## You should not have to change anything below this line ##
## ##
##################################################################
NAME="$0:t:r"
if [[ -e "$HOME/.path" ]]
then
source "$HOME/.path"
else
PATH="/usr/local/scripts:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin"
fi
if (( $+commands[mas] ))
then
# try to update Mac App Store apps before running this command
# although it cannot always tell which apps need to be updated.
mas upgrade
fi
if [[ ! -e "$BACKUP_DIR" ]]
then
mkdir -p "$BACKUP_DIR"
fi
if [[ ! -e "$BACKUP_DIR" ]]
then
echo "$NAME: failed to create '$BACKUP_DIR'." >>/dev/stderr
exit 2
fi
if (( $+commands[xz] ))
then
# if 'xz' exists, use it with tar
function my_archive {
tar -c --verbose --options='xz:compression-level=9' --xz -c --file "$BACKUP_FILENAME" "$line"
}
EXT='xz'
else
# if 'xz' does not exist, use bzip2
function my_archive {
tar -c --verbose --bzip2 --file "$BACKUP_FILENAME" "$line"
}
EXT='bz2'
fi
cd '/Applications'
find * -iname '_MASReceipt' -maxdepth 2 -print \
| sort --ignore-case \
| sed 's#/Contents/_MASReceipt$##g' \
| while read line
do
# don't try to backup Xcode, it's too big
# remove this if you want to back it up anyway
[[ "$line" == "Xcode.app" ]] && continue
# this is the name of the app with any spaces removed
SHORT="${${line:t:r}// /}"
# this is the major version number
VERSION=$(defaults read "$PWD/$line/Contents/Info" CFBundleShortVersionString 2>/dev/null || echo 'x')
# this is the build number
BUILD=$(defaults read "$PWD/$line/Contents/Info" CFBundleVersion 2>/dev/null || echo 'x')
# this is the filename that will be used
BACKUP_FILENAME="$SHORT.$VERSION.$BUILD.tar.$EXT"
# this is the full path to the backed-up file
BACKUP_FULL="$BACKUP_DIR/$SHORT/$BACKUP_FILENAME"
if [[ -e "$BACKUP_FULL" ]]
then
echo " $NAME: $line: this version is already backed up at '$BACKUP_FULL'."
else
echo "$NAME: $line: Creating new backup at '$BACKUP_FULL'"
# this will create the directory if needed
mkdir -p "$BACKUP_FULL:h"
my_archive
EXIT="$?"
if [ "$EXIT" = "0" ]
then
echo "$NAME: Successfully made '$BACKUP_FILENAME'."
mv -vf "$BACKUP_FILENAME" "$BACKUP_FULL"
else
echo "$NAME: failed to create '$BACKUP_FILENAME' (\$EXIT = $EXIT)"
if [[ -e "$BACKUP_FILENAME" ]]
then
# if the process exited with an error but left a file, move the file to the trash
mv -vf "$BACKUP_FILENAME" "$HOME/.Trash/"
fi
fi
fi
done
exit 0
#EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment