Created
August 20, 2026 15:33
-
-
Save tohuw/d979ff3ece31b346a1930217486e82ec to your computer and use it in GitHub Desktop.
macOS Spotlight and Launch Services fixer
This file contains hidden or 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
| #!/usr/bin/env bash | |
| set -u | |
| readonly SCRIPT_NAME="spotlight-fixer" | |
| readonly LSREGISTER="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister" | |
| usage() { | |
| cat <<'EOF' | |
| Usage: | |
| spotlight-fixer Rebuild the application registration database | |
| spotlight-fixer --doctor Check Spotlight and application-search health | |
| spotlight-fixer --rebuild-index Re-register apps and erase/rebuild the Spotlight index | |
| spotlight-fixer --help Show this help | |
| The full Spotlight rebuild is intentionally opt-in because it can take time and | |
| temporarily increase CPU and disk usage. | |
| EOF | |
| } | |
| pass() { printf 'PASS: %s\n' "$1"; } | |
| warn() { printf 'WARN: %s\n' "$1"; } | |
| fail() { printf 'FAIL: %s\n' "$1"; } | |
| doctor() { | |
| local status app_count launch_services | |
| printf '%s\n' "Spotlight doctor" | |
| printf '%s\n' "===============" | |
| if [[ "$(uname -s)" != "Darwin" ]]; then | |
| fail "This script requires macOS." | |
| return 1 | |
| fi | |
| if [[ -x "$LSREGISTER" ]]; then | |
| pass "Launch Services utility is available." | |
| else | |
| fail "Launch Services utility not found at $LSREGISTER" | |
| fi | |
| status="$(mdutil -s / 2>&1 || true)" | |
| if grep -q 'Indexing enabled' <<<"$status"; then | |
| pass "Spotlight indexing is enabled for /." | |
| else | |
| fail "Spotlight indexing is not reported as enabled for /." | |
| printf '%s\n' "$status" | |
| fi | |
| app_count="$(mdfind -onlyin /Applications 'kMDItemContentType == "com.apple.application-bundle"' 2>/dev/null | sed '/^$/d' | wc -l | tr -d ' ')" | |
| if [[ "$app_count" =~ ^[0-9]+$ ]] && (( app_count > 0 )); then | |
| pass "Spotlight can see $app_count application bundle(s) in /Applications." | |
| else | |
| fail "Spotlight returned no application bundles from /Applications." | |
| fi | |
| launch_services="$("$LSREGISTER" -dump 2>/dev/null | grep -c '^path:.*\.app' || true)" | |
| if [[ "$launch_services" =~ ^[0-9]+$ ]] && (( launch_services > 0 )); then | |
| pass "Launch Services contains $launch_services application registration(s)." | |
| else | |
| warn "Could not count Launch Services application registrations." | |
| fi | |
| if defaults read com.apple.Spotlight DisabledUTTypes 2>/dev/null | grep -q 'com.apple.application-bundle'; then | |
| fail "Application bundles appear in Spotlight's disabled type list." | |
| else | |
| pass "Application bundles are not listed as a disabled Spotlight type." | |
| fi | |
| warn "macOS does not expose the Spotlight Privacy UI as a reliable command-line setting." | |
| warn "The indexing and /Applications query above are the practical privacy-exclusion checks." | |
| printf '%s\n' "Check System Settings > Siri & Spotlight > Search Results: Applications enabled." | |
| printf '%s\n' "Check System Settings > Siri & Spotlight > Spotlight Privacy: no /Applications exclusion." | |
| } | |
| fix_launch_services() { | |
| if [[ ! -x "$LSREGISTER" ]]; then | |
| printf 'ERROR: Launch Services utility not found: %s\n' "$LSREGISTER" >&2 | |
| return 1 | |
| fi | |
| printf '%s\n' "Re-registering applications with Launch Services..." | |
| "$LSREGISTER" -kill -r -domain local -domain system -domain user | |
| killall Dock 2>/dev/null || true | |
| killall Finder 2>/dev/null || true | |
| printf '%s\n' "Application registration rebuilt." | |
| } | |
| rebuild_index() { | |
| printf '%s\n' "Erasing and rebuilding the Spotlight index for /..." | |
| sudo mdutil -E / | |
| printf '%s\n' "Spotlight rebuild requested. Indexing will continue in the background." | |
| } | |
| doctor_requested=0 | |
| rebuild_requested=0 | |
| for arg in "$@"; do | |
| case "$arg" in | |
| --doctor) doctor_requested=1 ;; | |
| --rebuild-index) rebuild_requested=1 ;; | |
| --help|-h) usage; exit 0 ;; | |
| *) printf 'ERROR: unknown option: %s\n\n' "$arg" >&2; usage >&2; exit 2 ;; | |
| esac | |
| done | |
| if (( doctor_requested )); then | |
| doctor | |
| exit $? | |
| fi | |
| fix_launch_services | |
| if (( rebuild_requested )); then | |
| rebuild_index | |
| fi | |
| # End of script | |
| # |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment