Skip to content

interp: $- is unset, so it is empty and errors under set -u #1398

Closed

Description

@blairham

$-, the POSIX special parameter holding the current option flags, is never set.

$ gosh -c 'echo "[$-]"'
[]
$ bash -c 'echo "[$-]"'
[hBc]

$ gosh -c 'set -e; echo "[$-]"'
[]
$ bash -c 'set -e; echo "[$-]"'
[ehBc]

Being empty rather than absent would already be a divergence, but it is genuinely unset, so set -u turns any reference into a fatal error:

$ gosh -c 'set -u; echo "[$-]"'
-: unbound variable
$ bash -c 'set -u; echo "[$-]"'
[uhBc]

That combination is the awkward one: set -euo pipefail followed by anything that consults $- aborts. The common idioms are interactivity checks in shell rc files and libraries that save and restore options:

case $- in *i*) ... ;; esac        # sees no flags at all
[[ $- == *e* ]] && restore_errexit=1

The interactivity check happens to reach the right answer today, since an empty $- contains no i either — but only by accident, and only while interp has no interactive mode.

$- should hold the single-letter names of the enabled options, which interp already tracks in posixOptsTable; note that pipefail has no letter there ( ), so it is -o-only in bash too and should be left out.

Reproduced on master at d6550df against bash 5.3.15 on darwin/arm64, found while measuring set for #1392.

Activity

  1. added a commit that references this issue on Aug 22, 2026
    6622086
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions