Skip to content

Lint Bash nounset empty-argv forwarding #48

Description

@c0da-ricon

Problem

Bash task wrappers that run under set -u can fail on macOS system Bash 3.2 when they forward an empty argv with "${@}" / "$@".

This bit KnickKnackLabs/monkeys#37: a wrapper task delegated to another mise task with:

set -euo pipefail
mise run -q hear:qwen "${@}"

When invoked with no args on macOS hosted CI, the wrapper failed before delegation:

.mise/tasks/hear/_default: line 15: @: unbound variable

Linux/Bash 5 and my local default Homebrew Bash did not reproduce it; macOS /bin/bash 3.2 did.

Desired lint

Add a lint rule that flags direct empty-argv forwarding in Bash files that enable nounset (set -u, set -eu, set -euo pipefail, etc.).

Flag shapes like:

some_command "$@"
some_command "${@}"
exec other "$@"
mise run child "${@}"

when the file has nounset enabled.

Suggest the Bash-3-safe form:

some_command ${@+"$@"}
exec other ${@+"$@"}
mise run child ${@+"$@"}

Scope notes

  • This is especially relevant for .mise/tasks/* wrapper tasks that delegate to another task/command.
  • The lint should avoid false positives in files without nounset, and should probably focus on command arguments rather than every mention of $@.
  • A rule name could be bash-empty-argv-forwarding or similar.
  • It may belong near existing shell/task convention lints rather than replacing ShellCheck; ShellCheck did not catch this in monkeys#37.

Repro

On macOS:

/bin/bash -u -c 'set --; exec printf "%s\n" "$@"'
# /bin/bash: @: unbound variable

/bin/bash -u -c 'set --; exec printf "%s\n" ${@+"$@"}'
# succeeds with no args

Provenance

Found while porting monkeys to KKL template conventions and adding hosted macOS/Linux CI in KnickKnackLabs/monkeys#37.

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