Created
November 15, 2020 20:17
-
-
Save felixbuenemann/e4df9485111dbaefd2f3ecabff5bcb20 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# pkg-remove removes macOS packages using the receipt | |
# Copyright: 2020 by Felix Buenemann | |
# License: MIT | |
set -eo pipefail | |
volume=/ | |
dryrun=false | |
force=false | |
for arg in "$@"; do | |
case $arg in | |
--volume=*) | |
volume=${arg#*=} | |
shift | |
;; | |
-v|--volume) | |
shift | |
volume=$1 | |
shift | |
;; | |
-n|--dry-run) | |
force=true | |
dryrun=true | |
shift | |
;; | |
-f|--force) | |
force=true | |
shift | |
;; | |
-h|--help) | |
echo "Usage: $0 [-n|--dry-run] [v|--volume VOLUME] PKGID [..PKGID]" | |
exit 0 | |
;; | |
-*) | |
echo "Unknown option: $arg (see -h for help)" >/dev/stderr | |
exit 1 | |
;; | |
esac | |
done | |
if $dryrun; then | |
echo "Dry-run active, simulating changes. Nothing will be removed!" >/dev/stderr | |
fi | |
for pkgid in "$@"; do | |
location=`pkgutil --volume "$volume" --pkg-info "$pkgid" | \ | |
awk -F': ' '/^(volume|location):/{printf $2}' | tr -s /` | |
root=`pkgutil --volume "$volume" --only-dirs --files "$pkgid" | head -n1 ||:` | |
echo $root | |
if [ ! -d "$location" ]; then | |
echo "Package $pkgid install location '$location' doesn't exist" >/dev/stderr | |
else | |
if ! $force; then | |
read -p "Remove package $pkgid from '$location'? (y/N) " remove | |
if [ "$remove" != "y" ]; then | |
echo "Skipping $pkgid" >/dev/stderr | |
continue | |
fi | |
else | |
echo "Removing package $pkgid from '$location'" >/dev/stderr | |
fi | |
extra= | |
if [ -d "$location/$root/Contents/_MASReceipt" ]; then | |
echo "Detected Mac AppStore receipt, adding to deleted files" >/dev/stderr | |
extra="$root/Contents/_MASReceipt\n$root/Contents/_MASReceipt/receipt\n" | |
fi | |
if $dryrun; then | |
(pkgutil --volume "$volume" --files "$pkgid" && printf "$extra") \ | |
| tail -r \ | |
| awk "{ printf \"$location/%s%c\", \$0, 0 } END { printf \"$location\" }" \ | |
| tr -s / \ | |
| xargs -0 -n1 echo rm -df | |
else | |
# use relative paths so we can do more deletes in a single rm call | |
(pkgutil --volume "$volume" --files "$pkgid" && printf "$extra") \ | |
| tail -r \ | |
| tr '\n' '\0' \ | |
| (cd "$location" && sudo xargs -0 rm -df) | |
# ignore errors when removing location (eg. /Applications) | |
sudo rm -df "$location" 2>/dev/null ||: | |
fi | |
fi | |
if ! $dryrun && [ "$root" != "" ] && [ -d "$location/$root" ]; then | |
echo "Package root directory '$location/$root' still exists!" >/dev/stderr | |
continue | |
fi | |
if ! $force; then | |
read -p "Remove package $pkgid install receipt? (y/N) " remove | |
if [ "$remove" != "y" ]; then | |
echo "Skipping $pkgid" >/dev/stderr | |
continue | |
fi | |
else | |
echo "Removing package $pkgid install receipt" >/dev/stderr | |
fi | |
if ! $dryrun; then | |
sudo pkgutil --volume "$volume" --forget "$pkgid" | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment