Lesson 2: Wildcard * in the Wrong Case Arm¶
File affected: scripts/actions/workspace-actions.sh
Severity: High — all named actions silently fall back to the menu, nothing executes
What Happened¶
The main dispatch used this pattern:
MODE="${1:-list}"
shift
case "$MODE" in
list|ls|help|--help|-h|*) # <-- the |* here is the bug
show_fuzzel_menu
;;
*)
execute_action "$1" # <-- dead code, never reached
;;
esac
The |* appended to the first arm means "or anything else". Bash evaluates case
arms in order and stops at the first match. Because * matches everything, the
second *) arm is permanently unreachable — every possible value of $MODE hits
the menu instead of executing the intended action.
A secondary bug is also present: after shift, the code tries to read "$1" again,
but shift already advanced $1 to what was formerly $2 (or empty).
The Fix¶
MODE="${1:-list}"
shift
case "$MODE" in
list|ls|help|--help|-h)
show_fuzzel_menu
;;
*)
execute_action "$MODE" # use $MODE, not $1 (which was shifted)
;;
esac
Key changes:
1. Remove |* from the first arm so named values fall through.
2. Pass $MODE (captured before the shift) instead of $1 (which has moved).
The General Rule¶
Never place
|*in the middle of acasearm list.*is a catch-all and must always be the last arm, alone, with no other patterns.
# BAD
case "$x" in
foo|bar|*) echo "foo/bar/anything" ;; # * eats everything
baz) echo "never reached" ;;
esac
# GOOD
case "$x" in
foo|bar) echo "foo or bar" ;;
baz) echo "baz" ;;
*) echo "fallback" ;;
esac