2

I’m using MacKeeper to uninstall apps from the command line in terminal.app.

Error message shown

When I try to run the Terminal command to uninstall an application completely, I get the error message "command not found" but it is documented by others in different forums that the command is commonly used to uninstall apps.

Does anyone know any other way and if that command is not supported/used anymore

1
  • To best of my knowledge, there has never been an uninstall command in macOS. Use one of the GUI apps for uninstalling apps.
    – Gilby
    Apr 1, 2022 at 21:49

1 Answer 1

5

If you just want to remove the app files itself, you can type rm -Rdf followed by the file path.

If you want to also remove other files left by the app (like preferences and caches), you can use the script I include below.

#!/bin/sh

if [ -z "$1" ]; then
  printf "%s\n" "Usage: uninstall /path/to/app.app"
  exit 1
fi

IFS=$'\n'

red=$'\e[1;31m'
nc=$'\e[0m'

if [ ! -e "$1/Contents/Info.plist" ]; then
  printf "%s\n" "Cannot find app plist"
  exit 1
fi

bundle_identifier=$(/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" "$1/Contents/Info.plist" 2> /dev/null)

if [ "$bundle_identifier" = "" ]; then
  printf "%s\n" "Cannot find app bundle identifier"
  exit 1
fi

printf "%s\n" "Checking for running processes..."
sleep 1

app_name=$(basename $1 .app)

processes=($(pgrep -afil "$app_name" | grep -v "uninstall"))

if [ ${#processes[@]} -gt 0 ]; then
  printf "%s\n" "${processes[@]}"
  printf "${red}%s${nc}" "Kill running processes (y or n)? "
  read -r answer
  if [ "$answer" = "y" ]; then
    printf "%s\n" "Killing running processes..."
    sleep 1
    for process in "${processes[@]}"; do
      echo $process | awk '{print $1}' | xargs kill 2>&1 | grep -v "No such process"
    done
  fi
fi

home_dir=~

paths=()

paths+=($(find /private/var/db/receipts -iname "*$app_name*.bom" -maxdepth 1 -prune 2>&1 | grep -v "Permission denied"))
paths+=($(find /private/var/db/receipts -iname "*$bundle_identifier*.bom" -maxdepth 1 -prune 2>&1 | grep -v "Permission denied"))

if [ ${#paths[@]} -gt 0 ]; then
  printf "%s\n" "Saving bill of material logs to desktop..."
  sleep 1
  for path in "${paths[@]}"; do
    mkdir -p "$home_dir/Desktop/$app_name"
    lsbom -f -l -s -p f $path > "$home_dir/Desktop/$app_name/$(basename $path).log"
  done
fi

printf "%s\n" "Finding app data..."
sleep 1

locations=(
  "$home_dir/Library"
  "$home_dir/Library/Application Support"
  "$home_dir/Library/Application Support/CrashReporter"
  "$home_dir/Library/Containers"
  "$home_dir/Library/Caches"
  "$home_dir/Library/Group Containers"
  "$home_dir/Library/Internet Plug-Ins"
  "$home_dir/Library/LaunchAgents"
  "$home_dir/Library/Logs"
  "$home_dir/Library/Preferences"
  "$home_dir/Library/Saved Application State"
  "$home_dir/Library/WebKit"
  "/Library"
  "/Library/Application Support"
  "/Library/Application Support/CrashReporter"
  "/Library/Caches"
  "/Library/Extensions"
  "/Library/Internet Plug-Ins"
  "/Library/LaunchAgents"
  "/Library/LaunchDaemons"
  "/Library/Logs"
  "/Library/Preferences"
  "/private/var/db/receipts"
  "/usr/local/bin"
  "/usr/local/etc"
  "/usr/local/opt"
  "/usr/local/sbin"
  "/usr/local/share"
  "/usr/local/var"
  $(getconf DARWIN_USER_CACHE_DIR | sed "s/\/$//")
  $(getconf DARWIN_USER_TEMP_DIR | sed "s/\/$//")
)

paths=($1)

for location in "${locations[@]}"; do
  paths+=($(find "$location" -iname "*$app_name*" -maxdepth 1 -prune 2>&1 | grep -v "No such file or directory" | grep -v "Operation not permitted" | grep -v "Permission denied"))
done

for location in "${locations[@]}"; do
  paths+=($(find "$location" -iname "*$bundle_identifier*" -maxdepth 1 -prune 2>&1 | grep -v "No such file or directory" | grep -v "Operation not permitted" | grep -v "Permission denied"))
done

paths=($(printf "%s\n" "${paths[@]}" | sort -u));

printf "%s\n" "${paths[@]}"

  printf "%s\n" "Moving app data to trash..."
  sleep 1
  posixFiles=$(printf ", POSIX file \"%s\"" "${paths[@]}" | awk '{print substr($0,3)}')
  osascript -e "tell application \"Finder\" to delete { $posixFiles }" > /dev/null
  printf "%s\n" "Done"

I suggest keeping this script somewhere in your $PATH, so you can run it from any location.

I made a shortcut which allows you to launch this script without having to use the command line. It asks you to select the app and the interaction is just as easy as it is with tools like AppCleaner mentioned in a comment.

https://www.icloud.com/shortcuts/a4b8397f95e74a49b4e80b72be50b273

You can also launch this scripts using other graphical automation tools, like Automator, Keyboard Maestro, Alfred or BetterTouchTool.

2
  • 2
    That looks comprehensive [if a little above my pay grade]. Personally, I find AppCleaner (Freeware) much simpler ;)
    – Tetsujin
    Apr 1, 2022 at 16:58
  • 1
    If you are one macOS Monterey, you can try the shortcut I added at the end. It's just as easy.
    – anon
    Apr 1, 2022 at 17:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .