Skip to content

Lint Bash nounset empty array expansions #57

Description

@zeke-ricon

Problem

Bash 3.2 on macOS treats empty arrays under set -u as unbound when expanded as "${array[@]}".

This bit KnickKnackLabs/winnie#36 on hosted macOS CI. iso:get had:

set -euo pipefail
arch_args=()
[[ -n "$ARCH_FLAG" ]] && arch_args=(--arch "$ARCH_FLAG")

mise -C "$TASK_ROOT" run -q "catalog:$DISTRO" -- --json "${arch_args[@]}"

When ARCH_FLAG was empty, hosted macOS failed with:

.mise/tasks/iso/get: line 37: arch_args[@]: unbound variable

Linux/modern Bash and local runs did not catch it. The fix was the Bash-3-safe expansion:

mise -C "$TASK_ROOT" run -q "catalog:$DISTRO" -- --json ${arch_args[@]+"${arch_args[@]}"}

Desired lint

Add a lint rule that flags "${name[@]}" array expansions in Bash files that enable nounset (set -u, set -eu, set -euo pipefail, etc.) unless the expansion already uses the safe alternate-value form.

Flag:

cmd "${args[@]}"
for item in "${items[@]}"; do
  ...
done

Suggest:

cmd ${args[@]+"${args[@]}"}
for item in ${items[@]+"${items[@]}"}; do
  ...
done

Scope notes

  • This is the array sibling of Lint Bash nounset empty-argv forwarding #48 ($@ forwarding under nounset).
  • Focus on shell files with nounset enabled to avoid noisy findings in relaxed scripts.
  • ShellCheck did not catch the Winnie case.

Provenance

Found while adding Fedora support + template-shaped CI to KnickKnackLabs/winnie#36. Hosted macOS failed after Ubuntu and local validation passed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions