From 1b4603358438568bc03a6426853f5b20ff2b54e9 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Thu, 6 Aug 2026 22:31:50 -0400 Subject: [PATCH] grep -c prints zero and exits one, so every echo-0 fallback produced a two-line count --- Arrs_Stack/lidarr_cleanup.sh | 2 +- Arrs_Stack/playback_aware_lidarr_discovery.sh | 4 ++-- Arrs_Stack/radarr_cleanup.sh | 2 +- Arrs_Stack/sonarr_cleanup.sh | 2 +- Docker_Essentials/downloaders_reset.sh | 14 +++++++------- Monitors/system_tuning_monitor.sh | 2 +- .../unraid/Watchdogs/System/webgui_watchdog.sh | 2 +- Tools/docker_prune_images.sh | 6 +++--- Tools/emby_to_lidarr_sync.sh | 2 +- Tools/watchdog_skip_list_manager.sh | 2 +- Watchdogs/stability_watchdog.sh | 16 +++++++++++++--- 11 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Arrs_Stack/lidarr_cleanup.sh b/Arrs_Stack/lidarr_cleanup.sh index c981371..5d43a32 100755 --- a/Arrs_Stack/lidarr_cleanup.sh +++ b/Arrs_Stack/lidarr_cleanup.sh @@ -327,7 +327,7 @@ ARTIST_RESPONSE=$(arr_get_tracked_data "lidarr" "$LIDARR_URL" "$LIDARR_API_KEY" } ARTIST_IDS=$(echo "$ARTIST_RESPONSE" | jq -r '.[].id' 2>/dev/null) -ARTIST_COUNT=$(echo "$ARTIST_IDS" | grep -c "[0-9]" 2>/dev/null || echo 0) +ARTIST_COUNT=$(echo "$ARTIST_IDS" | grep -c "[0-9]" 2>/dev/null || true) # Safety Layer 4 — artist count > 0 if [[ "$ARTIST_COUNT" -eq 0 ]]; then diff --git a/Arrs_Stack/playback_aware_lidarr_discovery.sh b/Arrs_Stack/playback_aware_lidarr_discovery.sh index c2e6ce8..025f9fc 100755 --- a/Arrs_Stack/playback_aware_lidarr_discovery.sh +++ b/Arrs_Stack/playback_aware_lidarr_discovery.sh @@ -541,7 +541,7 @@ echo "━━━ $ICON_SYNC Existing Libraries ━━━" # fetch when it's stale, and waits out an active rescan before either. LIDARR_ARTISTS_JSON=$(arr_get_tracked_data "lidarr" "$LIDARR_URL" "$LIDARR_API_KEY" "v1") || { error "Could not fetch Lidarr artists"; exit 1; } LIDARR_NAMES=$(echo "$LIDARR_ARTISTS_JSON" | jq -r '.[].artistName' 2>/dev/null) -LIDARR_COUNT=$(echo "$LIDARR_NAMES" | grep -c . 2>/dev/null || echo 0) +LIDARR_COUNT=$(echo "$LIDARR_NAMES" | grep -c . 2>/dev/null || true) log "$LIDARR_COUNT artists in Lidarr" EMBY_LIBRARY_JSON=$(emby_api "Items?IncludeItemTypes=MusicAlbum&Recursive=true&Fields=AlbumArtists&Limit=10000") || { @@ -549,7 +549,7 @@ EMBY_LIBRARY_JSON=$(emby_api "Items?IncludeItemTypes=MusicAlbum&Recursive=true&F EMBY_ARTIST_NAMES="" } EMBY_ARTIST_NAMES=$(echo "$EMBY_LIBRARY_JSON" | jq -r '.Items[] | .AlbumArtists[]?.Name' 2>/dev/null) -EMBY_ARTIST_COUNT=$(echo "$EMBY_ARTIST_NAMES" | grep -c . 2>/dev/null || echo 0) +EMBY_ARTIST_COUNT=$(echo "$EMBY_ARTIST_NAMES" | grep -c . 2>/dev/null || true) log "$EMBY_ARTIST_COUNT album artists in Emby library" # MusicBrainz's canonical name for some artists (e.g. "blink‐182") uses a Unicode diff --git a/Arrs_Stack/radarr_cleanup.sh b/Arrs_Stack/radarr_cleanup.sh index 3af4e8a..e8c8494 100755 --- a/Arrs_Stack/radarr_cleanup.sh +++ b/Arrs_Stack/radarr_cleanup.sh @@ -314,7 +314,7 @@ MOVIES_RESPONSE=$(arr_get_tracked_data "radarr" "$RADARR_URL" "$RADARR_API_KEY" } MOVIE_IDS=$(echo "$MOVIES_RESPONSE" | jq -r '.[].id' 2>/dev/null) -MOVIE_COUNT=$(echo "$MOVIE_IDS" | grep -c "." 2>/dev/null || echo 0) +MOVIE_COUNT=$(echo "$MOVIE_IDS" | grep -c "." 2>/dev/null || true) # Safety Layer 4 — movie count > 0 if [[ "$MOVIE_COUNT" -eq 0 ]]; then diff --git a/Arrs_Stack/sonarr_cleanup.sh b/Arrs_Stack/sonarr_cleanup.sh index 7a919d2..1569d88 100755 --- a/Arrs_Stack/sonarr_cleanup.sh +++ b/Arrs_Stack/sonarr_cleanup.sh @@ -308,7 +308,7 @@ SERIES_RESPONSE=$(arr_get_tracked_data "sonarr" "$SONARR_URL" "$SONARR_API_KEY" } SERIES_IDS=$(echo "$SERIES_RESPONSE" | jq -r '.[].id' 2>/dev/null) -SERIES_COUNT=$(echo "$SERIES_IDS" | grep -c "." 2>/dev/null || echo 0) +SERIES_COUNT=$(echo "$SERIES_IDS" | grep -c "." 2>/dev/null || true) # Safety Layer 4 — series count > 0 if [[ "$SERIES_COUNT" -eq 0 ]]; then diff --git a/Docker_Essentials/downloaders_reset.sh b/Docker_Essentials/downloaders_reset.sh index 40324fa..c92321d 100755 --- a/Docker_Essentials/downloaders_reset.sh +++ b/Docker_Essentials/downloaders_reset.sh @@ -283,7 +283,7 @@ if [[ -n "$SLSKD_URL" ]] && [[ -n "$SLSKD_API_KEY" ]] && [[ "$SLSKD_CONNECTED" = IDS=$(echo "$SEARCHES" | tr '{' '\n' | \ grep '"isComplete":true' | grep '"searchText":' | \ grep -o '"id":"[^"]*"' | sed 's/"id":"//;s/"//') - COUNT=$(echo "$IDS" | grep -c . 2>/dev/null || echo 0) + COUNT=$(echo "$IDS" | grep -c . 2>/dev/null || true) COUNT="${COUNT//[^0-9]/}"; COUNT="${COUNT:-0}" if [[ "$COUNT" -eq 0 ]]; then @@ -339,7 +339,7 @@ if [[ -n "$SLSKD_URL" ]] && [[ -n "$SLSKD_API_KEY" ]] && [[ "$SLSKD_CONNECTED" = if [[ -z "$USERNAMES" ]]; then success "No transfer records found ✅" else - USER_COUNT=$(echo "$USERNAMES" | grep -c . 2>/dev/null || echo 0) + USER_COUNT=$(echo "$USERNAMES" | grep -c . 2>/dev/null || true) log "Found $USER_COUNT user(s) with transfer records" SUCCESS=0; SKIPPED=0; FAIL=0 while IFS= read -r USER; do @@ -416,7 +416,7 @@ if [[ -n "$SLSKD_FAILED_IMPORTS_DIR" ]]; then else OLD_IMPORTS=$(find "$SLSKD_FAILED_IMPORTS_DIR" \ -mindepth 1 -maxdepth 1 -mtime +"${DOWNLOADER_RETENTION_DAYS}") - IMPORT_COUNT=$(echo "$OLD_IMPORTS" | grep -c . 2>/dev/null || echo 0) + IMPORT_COUNT=$(echo "$OLD_IMPORTS" | grep -c . 2>/dev/null || true) IMPORT_COUNT="${IMPORT_COUNT//[^0-9]/}"; IMPORT_COUNT="${IMPORT_COUNT:-0}" if [[ "$IMPORT_COUNT" -eq 0 ]]; then @@ -459,7 +459,7 @@ if [[ -n "$SABNZBD_URL" ]] && [[ -n "$SABNZBD_API_KEY" ]]; then if [[ -z "$COMPLETED_IDS" ]]; then success "No completed history found ✅" else - HIST_TOTAL=$(echo "$COMPLETED_IDS" | grep -c . 2>/dev/null || echo 0) + HIST_TOTAL=$(echo "$COMPLETED_IDS" | grep -c . 2>/dev/null || true) log "Found $HIST_TOTAL completed history entries" DELETED=0; SKIPPED=0 while IFS= read -r NZO_ID; do @@ -507,7 +507,7 @@ if [[ -n "$SABNZBD_URL" ]] && [[ -n "$SABNZBD_API_KEY" ]]; then if [[ -z "$FAILED_IDS" ]]; then success "No failed history found ✅" else - FAILED_TOTAL=$(echo "$FAILED_IDS" | grep -c . 2>/dev/null || echo 0) + FAILED_TOTAL=$(echo "$FAILED_IDS" | grep -c . 2>/dev/null || true) log "Found $FAILED_TOTAL failed history entries" DELETED=0; SKIPPED=0 while IFS= read -r NZO_ID; do @@ -557,7 +557,7 @@ if [[ -n "$SABNZBD_URL" ]] && [[ -n "$SABNZBD_API_KEY" ]]; then if [[ -z "$STALLED_IDS" ]]; then success "No stalled queue items found ✅" else - QUEUE_TOTAL=$(echo "$STALLED_IDS" | grep -c . 2>/dev/null || echo 0) + QUEUE_TOTAL=$(echo "$STALLED_IDS" | grep -c . 2>/dev/null || true) log "Found $QUEUE_TOTAL queue item(s) — checking status" DELETED=0; SKIPPED=0 while IFS= read -r NZO_ID; do @@ -618,7 +618,7 @@ if [[ -n "$QBIT_URL" ]] && [[ -n "$QBIT_USERNAME" ]]; then -H "Cookie: $QBIT_COOKIE" 2>/dev/null) NOW=$(date +%s) - TORRENT_TOTAL=$(echo "$TORRENTS" | tr '}' '\n' | grep -c '"hash"' 2>/dev/null || echo 0) + TORRENT_TOTAL=$(echo "$TORRENTS" | tr '}' '\n' | grep -c '"hash"' 2>/dev/null || true) log "Found $TORRENT_TOTAL torrent(s) — applying age/ratio filter" DELETED=0; SKIPPED=0 diff --git a/Monitors/system_tuning_monitor.sh b/Monitors/system_tuning_monitor.sh index f80ec9a..6068bac 100755 --- a/Monitors/system_tuning_monitor.sh +++ b/Monitors/system_tuning_monitor.sh @@ -209,7 +209,7 @@ fi # ============================================================================================== PHPFPM_MAX="${PHP_MAX_CHILDREN:-250}" -PHPFPM_ACTIVE=$(ps aux 2>/dev/null | grep -c "php-fpm: pool" || echo 0) +PHPFPM_ACTIVE=$(ps aux 2>/dev/null | grep -c "php-fpm: pool" || true) PHPFPM_ACTIVE="${PHPFPM_ACTIVE//[^0-9]/}" PHPFPM_ACTIVE="${PHPFPM_ACTIVE:-0}" diff --git a/Plugin/unraid/Watchdogs/System/webgui_watchdog.sh b/Plugin/unraid/Watchdogs/System/webgui_watchdog.sh index 74a2e34..27995ab 100755 --- a/Plugin/unraid/Watchdogs/System/webgui_watchdog.sh +++ b/Plugin/unraid/Watchdogs/System/webgui_watchdog.sh @@ -186,7 +186,7 @@ log "WebGUI check — $WEBGUI_URL" # ── Healthy — completely silent ─────────────────────────────────────────────────────────────── if check_webgui; then - _nginx_count=$(pgrep -cx nginx 2>/dev/null || echo 0) + _nginx_count=$(pgrep -cx nginx 2>/dev/null || true) _fpm_count=$(pgrep -fc "php-fpm" 2>/dev/null || echo 0) log "$ICON_WEBGUI WebGUI responding ✅ — nginx workers:${_nginx_count} php-fpm workers:${_fpm_count}" echo "WebGUI responding — healthy ✅" diff --git a/Tools/docker_prune_images.sh b/Tools/docker_prune_images.sh index 03b67a3..3bf20f3 100755 --- a/Tools/docker_prune_images.sh +++ b/Tools/docker_prune_images.sh @@ -173,7 +173,7 @@ TOTAL_RECLAIMED=0 # ── Step 1 (--all only): remove stopped containers ──────────────────────────── if [[ "$ALL_MODE" == true ]]; then STOPPED_IDS=$(docker ps -a --filter "status=exited" --filter "status=created" -q 2>/dev/null) - STOPPED_COUNT=$(echo "$STOPPED_IDS" | grep -c . || echo 0) + STOPPED_COUNT=$(echo "$STOPPED_IDS" | grep -c . || true) if [[ "$STOPPED_COUNT" -eq 0 ]]; then echo "No stopped containers" @@ -198,11 +198,11 @@ if [[ "$ALL_MODE" == true ]]; then # Images not used by any running container RUNNING_IMAGES=$(docker ps --format "{{.Image}}" 2>/dev/null) UNUSED_COUNT=$(docker images --format "{{.Repository}}:{{.Tag}}" 2>/dev/null \ - | grep -vxF "$RUNNING_IMAGES" | grep -c . || echo 0) + | grep -vxF "$RUNNING_IMAGES" | grep -c . || true) TARGET_LABEL="$UNUSED_COUNT unused image(s)" else DANGLING_IDS=$(docker images -f "dangling=true" -q 2>/dev/null) - UNUSED_COUNT=$(echo "$DANGLING_IDS" | grep -c . || echo 0) + UNUSED_COUNT=$(echo "$DANGLING_IDS" | grep -c . || true) TARGET_LABEL="$UNUSED_COUNT dangling image(s)" fi diff --git a/Tools/emby_to_lidarr_sync.sh b/Tools/emby_to_lidarr_sync.sh index fc13fb9..9546640 100755 --- a/Tools/emby_to_lidarr_sync.sh +++ b/Tools/emby_to_lidarr_sync.sh @@ -212,7 +212,7 @@ echo "━━━ $ICON_SYNC Lidarr Library ━━━" # fetch when it's stale, and waits out an active rescan before either. LIDARR_ARTISTS_JSON=$(arr_get_tracked_data "lidarr" "$LIDARR_URL" "$LIDARR_API_KEY" "v1") || { error "Could not fetch Lidarr artists"; exit 1; } LIDARR_NAMES=$(echo "$LIDARR_ARTISTS_JSON" | jq -r '.[].artistName' 2>/dev/null) -LIDARR_COUNT=$(echo "$LIDARR_NAMES" | grep -c . 2>/dev/null || echo 0) +LIDARR_COUNT=$(echo "$LIDARR_NAMES" | grep -c . 2>/dev/null || true) log "$LIDARR_COUNT artists already in Lidarr" _in_lidarr() { diff --git a/Tools/watchdog_skip_list_manager.sh b/Tools/watchdog_skip_list_manager.sh index 0b6c63d..2cb2d10 100755 --- a/Tools/watchdog_skip_list_manager.sh +++ b/Tools/watchdog_skip_list_manager.sh @@ -172,7 +172,7 @@ touch "$DOCKER_WATCHDOG_FAILED_FILE" "$WATCHDOG_CONTAINER_RESTART_LOG" 2>/dev/nu echo "" echo "━━━ $ICON_WATCHDOG Skip List Status — $MY_ID ━━━" -SKIP_COUNT=$(grep -c "." "$DOCKER_WATCHDOG_FAILED_FILE" 2>/dev/null || echo 0) +SKIP_COUNT=$(grep -c "." "$DOCKER_WATCHDOG_FAILED_FILE" 2>/dev/null || true) SKIP_COUNT="${SKIP_COUNT//[^0-9]/}"; SKIP_COUNT="${SKIP_COUNT:-0}" RESTART_COUNT=$(wc -l < "$WATCHDOG_CONTAINER_RESTART_LOG" 2>/dev/null || echo 0) RESTART_COUNT="${RESTART_COUNT//[^0-9]/}"; RESTART_COUNT="${RESTART_COUNT:-0}" diff --git a/Watchdogs/stability_watchdog.sh b/Watchdogs/stability_watchdog.sh index de924ad..321e162 100755 --- a/Watchdogs/stability_watchdog.sh +++ b/Watchdogs/stability_watchdog.sh @@ -320,9 +320,19 @@ purge_old_reboots() { mv "${SYS_WATCHDOG_REBOOT_LOG}.tmp" "$SYS_WATCHDOG_REBOOT_LOG" } +# Always emits exactly one number, because the caller compares it against the reboot limit and a +# malformed value there decides whether a looping server reboots again or shuts down. +# +# Two failure paths have to collapse to 0, and the old one-liner got both wrong. An EMPTY log — +# the normal state — made grep -c print 0 and exit 1, so "|| echo 0" fired as well and the +# function returned two lines. A MISSING log makes grep print nothing at all, so "|| true" alone +# would return the empty string. Either way the caller's [[ -ge ]] dies with a syntax error. count_recent_reboots() { purge_old_reboots - grep -c "." "$SYS_WATCHDOG_REBOOT_LOG" 2>/dev/null || echo 0 + local n + n=$(grep -c "." "$SYS_WATCHDOG_REBOOT_LOG" 2>/dev/null || true) + n="${n//[^0-9]/}" + echo "${n:-0}" } log_reboot() { @@ -584,7 +594,7 @@ echo "━━━ $ICON_REBOOT Stability Watchdog — $(date '+%Y-%m-%d %H:%M:%S') # ── Kernel oops/BUG — kernel running with corrupted state ──────────────────────────────── if [[ "$SYS_WATCHDOG_CHECK_KERNEL_OOPS" == true ]]; then PREV_OOPS=$(get_state_val "kernel_oops_count") - CURRENT_OOPS=$(dmesg 2>/dev/null | grep -cE "BUG:|kernel BUG|Oops:" || echo 0) + CURRENT_OOPS=$(dmesg 2>/dev/null | grep -cE "BUG:|kernel BUG|Oops:" || true) CURRENT_OOPS="${CURRENT_OOPS//[^0-9]/}"; CURRENT_OOPS="${CURRENT_OOPS:-0}" set_state_val "kernel_oops_count" "$CURRENT_OOPS" @@ -756,7 +766,7 @@ echo "━━━ $ICON_REBOOT Stability Watchdog — $(date '+%Y-%m-%d %H:%M:%S') # ── Zombie processes ───────────────────────────────────────────────────────────────────── if [[ "$SYS_WATCHDOG_CHECK_ZOMBIES" == true ]]; then - ZOMBIE_COUNT=$(ps aux 2>/dev/null | awk '{print $8}' | grep -c "^Z$" || echo 0) + ZOMBIE_COUNT=$(ps aux 2>/dev/null | awk '{print $8}' | grep -c "^Z$" || true) ZOMBIE_COUNT="${ZOMBIE_COUNT//[^0-9]/}"; ZOMBIE_COUNT="${ZOMBIE_COUNT:-0}" TRIGGERED=false [[ "$ZOMBIE_COUNT" -ge "$SYS_WATCHDOG_ZOMBIE_LIMIT" ]] && TRIGGERED=true