Instantly share code, notes, and snippets.
Last active
June 7, 2026 07:45
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save Vadorequest/57bea269db0f21975838f525c6056f2a to your computer and use it in GitHub Desktop.
Helps index/unindex SMB shares with premium support for ConnectMeNow 4
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 -euo pipefail | |
| # Default for ConnectMeNow. | |
| # Override with: | |
| # MOUNT_ROOT=/Volumes mount-smb-share.sh | |
| MOUNT_ROOT="${MOUNT_ROOT:-$HOME/MountPoints}" | |
| # Command printed in list output. | |
| # Override with: | |
| # SMB_INDEX_CMD=msmb mount-smb-share.sh | |
| SMB_INDEX_CMD="${SMB_INDEX_CMD:-${0##*/}}" | |
| case "$MOUNT_ROOT" in | |
| "~"/*) MOUNT_ROOT="$HOME/${MOUNT_ROOT#"~/"}" ;; | |
| "~") MOUNT_ROOT="$HOME" ;; | |
| esac | |
| usage() { | |
| cat <<USAGE | |
| Usage: | |
| $SMB_INDEX_CMD | |
| $SMB_INDEX_CMD list | |
| $SMB_INDEX_CMD status <share-name-or-path> | |
| $SMB_INDEX_CMD on <share-name-or-path> | |
| $SMB_INDEX_CMD off <share-name-or-path> | |
| $SMB_INDEX_CMD reindex <share-name-or-path> | |
| $SMB_INDEX_CMD purge-index <share-name-or-path> | |
| Examples: | |
| $SMB_INDEX_CMD | |
| $SMB_INDEX_CMD status "Grand Cocon" | |
| $SMB_INDEX_CMD off "Grand Cocon" | |
| $SMB_INDEX_CMD on Photos | |
| $SMB_INDEX_CMD reindex Photos | |
| $SMB_INDEX_CMD purge-index "Grand Cocon" | |
| Default mount root: | |
| $MOUNT_ROOT | |
| Override mount root: | |
| MOUNT_ROOT=/Volumes $SMB_INDEX_CMD | |
| USAGE | |
| } | |
| shell_quote() { | |
| # Avoid printf %q: it can mangle decomposed Unicode on macOS. | |
| local s="$1" | |
| local part | |
| printf "'" | |
| while [[ "$s" == *"'"* ]]; do | |
| part="${s%%\'*}" | |
| printf "%s'\\''" "$part" | |
| s="${s#*\'}" | |
| done | |
| printf "%s'" "$s" | |
| } | |
| lower() { | |
| printf '%s' "$1" | /usr/bin/tr '[:upper:]' '[:lower:]' | |
| } | |
| all_smb_mounts() { | |
| /sbin/mount | /usr/bin/awk ' | |
| /\(smbfs,/ { | |
| line=$0 | |
| sub(/^.* on /, "", line) | |
| sub(/ \(smbfs.*$/, "", line) | |
| print line | |
| } | |
| ' | |
| } | |
| smb_mounts_under_root() { | |
| all_smb_mounts | while IFS= read -r mp; do | |
| case "$mp" in | |
| "$MOUNT_ROOT"/*) printf '%s\n' "$mp" ;; | |
| esac | |
| done | |
| } | |
| md_status_one_line() { | |
| local path="$1" | |
| local out | |
| if out=$(/usr/bin/mdutil -s "$path" 2>&1); then | |
| printf '%s\n' "$out" | /usr/bin/awk 'NF { last=$0 } END { sub(/^[ \t]+/, "", last); print last }' | |
| else | |
| printf '%s\n' "$out" | /usr/bin/awk 'NF { last=$0 } END { sub(/^[ \t]+/, "", last); print last }' | |
| fi | |
| } | |
| spotlight_status_with_icon() { | |
| local status="$1" | |
| case "$status" in | |
| *"Indexing enabled."*|*"Server Search enabled."*|*"Server search enabled."*) | |
| printf 'โ %s' "$status" | |
| ;; | |
| *"Indexing disabled."*) | |
| printf 'โ %s' "$status" | |
| ;; | |
| *) | |
| printf 'โ ๏ธ %s' "$status" | |
| ;; | |
| esac | |
| } | |
| list_shares() { | |
| local found=0 | |
| local mp name status status_display quoted_name | |
| printf 'SMB mounts under: %s\n\n' "$MOUNT_ROOT" | |
| while IFS= read -r mp; do | |
| found=1 | |
| name="${mp#$MOUNT_ROOT/}" | |
| status="$(md_status_one_line "$mp")" | |
| status_display="$(spotlight_status_with_icon "$status")" | |
| quoted_name="$(shell_quote "$name")" | |
| printf ' %s\n' "$name" | |
| printf ' Spotlight: %s\n' "$status_display" | |
| printf ' Path: %s\n' "$mp" | |
| printf ' Status: %s status %s\n' "$SMB_INDEX_CMD" "$quoted_name" | |
| printf ' Enable: %s on %s\n' "$SMB_INDEX_CMD" "$quoted_name" | |
| printf ' Disable: %s off %s\n' "$SMB_INDEX_CMD" "$quoted_name" | |
| printf ' Reindex: %s reindex %s\n' "$SMB_INDEX_CMD" "$quoted_name" | |
| printf ' Purge: %s purge-index %s\n\n' "$SMB_INDEX_CMD" "$quoted_name" | |
| done < <(smb_mounts_under_root) | |
| if [ "$found" -eq 0 ]; then | |
| printf 'No mounted SMB shares found under %s\n\n' "$MOUNT_ROOT" | |
| printf 'Currently mounted SMB paths:\n' | |
| all_smb_mounts | sed 's/^/ /' | |
| fi | |
| } | |
| resolve_share() { | |
| local query="$1" | |
| local query_norm query_lc | |
| local mp name mp_lc name_lc | |
| local matches=() | |
| query_norm="${query#/System/Volumes/Data}" | |
| query_lc="$(lower "$query_norm")" | |
| while IFS= read -r mp; do | |
| name="${mp#$MOUNT_ROOT/}" | |
| mp_lc="$(lower "$mp")" | |
| name_lc="$(lower "$name")" | |
| if [ "$mp" = "$query_norm" ] || \ | |
| [ "$name" = "$query_norm" ] || \ | |
| [[ "$mp_lc" == *"$query_lc"* ]] || \ | |
| [[ "$name_lc" == *"$query_lc"* ]]; then | |
| matches+=("$mp") | |
| fi | |
| done < <(smb_mounts_under_root) | |
| case "${#matches[@]}" in | |
| 0) | |
| printf 'No SMB share matched: %s\n\n' "$query" >&2 | |
| list_shares >&2 | |
| exit 2 | |
| ;; | |
| 1) | |
| printf '%s\n' "${matches[0]}" | |
| ;; | |
| *) | |
| printf 'Multiple SMB shares matched: %s\n\n' "$query" >&2 | |
| for mp in "${matches[@]}"; do | |
| printf ' %s\n' "$mp" >&2 | |
| done | |
| printf '\nUse a more specific name.\n' >&2 | |
| exit 2 | |
| ;; | |
| esac | |
| } | |
| require_share_arg() { | |
| if [ "$#" -eq 0 ]; then | |
| printf 'Missing share name/path.\n\n' >&2 | |
| usage >&2 | |
| exit 2 | |
| fi | |
| } | |
| status_share() { | |
| local path="$1" | |
| printf 'Path: %s\n\n' "$path" | |
| /usr/bin/mdutil -s "$path" | |
| } | |
| enable_indexing() { | |
| local path="$1" | |
| printf 'Enabling Spotlight indexing for:\n %s\n\n' "$path" | |
| sudo /usr/bin/mdutil -i on "$path" | |
| /usr/bin/mdutil -s "$path" | |
| } | |
| disable_indexing() { | |
| local path="$1" | |
| printf 'Disabling Spotlight indexing for:\n %s\n\n' "$path" | |
| sudo /usr/bin/mdutil -i off "$path" | |
| /usr/bin/mdutil -s "$path" | |
| } | |
| reindex_share() { | |
| local path="$1" | |
| printf 'Enabling and rebuilding Spotlight index for:\n %s\n\n' "$path" | |
| sudo /usr/bin/mdutil -i on "$path" | |
| sudo /usr/bin/mdutil -E "$path" | |
| /usr/bin/mdutil -s "$path" | |
| } | |
| purge_index() { | |
| local path="$1" | |
| local spotlight_dir="$path/.Spotlight-V100" | |
| local answer | |
| printf 'Disabling Spotlight indexing for:\n %s\n\n' "$path" | |
| sudo /usr/bin/mdutil -i off "$path" || true | |
| if ! sudo /bin/test -e "$spotlight_dir"; then | |
| printf 'No .Spotlight-V100 directory found at:\n %s\n\n' "$spotlight_dir" | |
| /usr/bin/mdutil -s "$path" || true | |
| return 0 | |
| fi | |
| printf '\nThis will delete the Spotlight index directory on the mounted share:\n' | |
| printf ' %s\n\n' "$spotlight_dir" | |
| printf 'Proceed? [y/N] ' | |
| read -r answer | |
| case "$answer" in | |
| y|Y|yes|YES) | |
| sudo /bin/rm -rf "$spotlight_dir" | |
| printf 'Deleted: %s\n\n' "$spotlight_dir" | |
| ;; | |
| *) | |
| printf 'Cancelled.\n\n' | |
| ;; | |
| esac | |
| /usr/bin/mdutil -s "$path" || true | |
| } | |
| main() { | |
| local action="${1:-list}" | |
| local path share_query | |
| case "$action" in | |
| list|ls) | |
| list_shares | |
| ;; | |
| status|st|check) | |
| shift | |
| require_share_arg "$@" | |
| share_query="$*" | |
| path="$(resolve_share "$share_query")" | |
| status_share "$path" | |
| ;; | |
| on|enable) | |
| shift | |
| require_share_arg "$@" | |
| share_query="$*" | |
| path="$(resolve_share "$share_query")" | |
| enable_indexing "$path" | |
| ;; | |
| off|disable) | |
| shift | |
| require_share_arg "$@" | |
| share_query="$*" | |
| path="$(resolve_share "$share_query")" | |
| disable_indexing "$path" | |
| ;; | |
| reindex|rebuild) | |
| shift | |
| require_share_arg "$@" | |
| share_query="$*" | |
| path="$(resolve_share "$share_query")" | |
| reindex_share "$path" | |
| ;; | |
| purge-index|purge|clean-index) | |
| shift | |
| require_share_arg "$@" | |
| share_query="$*" | |
| path="$(resolve_share "$share_query")" | |
| purge_index "$path" | |
| ;; | |
| -h|--help|help) | |
| usage | |
| ;; | |
| *) | |
| share_query="$*" | |
| path="$(resolve_share "$share_query")" | |
| status_share "$path" | |
| ;; | |
| esac | |
| } | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Awesome! Thank you for writing and sharing this as a helper script for ConnectMeNow ๐