-
Notifications
You must be signed in to change notification settings - Fork 1
/
app-cleaner.sh
149 lines (127 loc) · 4.58 KB
/
app-cleaner.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/zsh
# Written by: VerityJ
# Published on: https://gist.github.com/verityj
#
# Usage: ./app-cleaner.sh /Applications/<app-name>.app
#
# Modified from:
# https://github.com/sunknudsen/privacy-guides/tree/d6b7f836a0595efaf9716703b597138ce34e3b28/how-to-clean-uninstall-macos-apps-using-appcleaner-open-source-alternative
if [ -z "$1" ] || [ "$1" = "--help" ]; then
printf "%s\n" "Usage: app-cleaner.sh /path/to/app.app"
exit 0
fi
IFS=$'\n'
red=$(tput setaf 1)
normal=$(tput sgr0)
app_name=$(basename $1 .app)
if [ ! -e "$1/Contents/Info.plist" ]; then
printf "%s\n" "Cannot find "$1"/Contents/Info.plist"
if [ ! -e "$1/Wrapper/$app_name.app/Info.plist" ];
then
printf "%s\n" "Cannot find "$1"/Wrapper/"$app_name".app/Info.plist"
exit 1
else
printf "%s\n" "(Found "$1"/Wrapper/"$app_name".app/Info.plist)"
info_plist=$1/Wrapper/$app_name.app/Info.Plist
printf "%s\n" "(Assigned "$info_plist")"
printf "\n"
printf "%s\n" " ************* IMPORTANT *************"
printf "%s\n" " * This is an iOS app with Containers!"
printf " * Next, run \$ find-all.sh "$app_name
printf "%s\n" " (case-insensitive)"
printf "%s\n" " * find-all.sh available at https://verityj.github.io"
printf "%s\n" " * Remove all identified folders from ~/Library/Containers/<long-string>"
printf "\n"
fi
else
info_plist=$1/Contents/Info.Plist
printf "%s\n" "Assigned "$info_plist
fi
bundle_identifier=$(/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" "$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
processes=($(pgrep -afil "$app_name" | grep -v "app-cleaner.sh"))
if [ ${#processes[@]} -gt 0 ]; then
printf "%s\n" "${processes[@]}"
printf "$red%s$normal" "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 sudo kill 2>&1 | grep -v "No such process"
done
fi
fi
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/Desktop/$app_name"
lsbom -f -l -s -p f $path > "$HOME/Desktop/$app_name/$(basename $path).log"
done
fi
printf "%s\n" "Finding app data…"
sleep 1
locations=(
"$HOME/Library"
"$HOME/Library/Application Scripts"
"$HOME/Library/Application Support"
"$HOME/Library/Application Support/CrashReporter"
"$HOME/Library/Containers"
"$HOME/Library/Caches"
"$HOME/Library/HTTPStorages"
"$HOME/Library/Group Containers"
"$HOME/Library/Internet Plug-Ins"
"$HOME/Library/LaunchAgents"
"$HOME/Library/Logs"
"$HOME/Library/Preferences"
"$HOME/Library/Preferences/ByHost"
"$HOME/Library/Saved Application State"
"$HOME/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"
"/Library/PrivilegedHelperTools"
"/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 "$red%s$normal" "Move app data to trash (y or n)? "
read -r answer
if [ "$answer" = "y" ]; then
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"
fi