Shell snapshot enables set -o monitor and set -o onecmd in every Bash tool shell (grep "on" matches option names)

Status Open
Reported on v2.1.283
Maintainer reply None cached
Activity 0 comments · opened Sep 26, 2026

Summary

The shell snapshot captures shell options with:

set -o | grep "on" | awk '{print "set -o " $1}' | head -n 1000 >> "$SNAPSHOT_FILE"

grep "on" is meant to keep options whose state is on, but it matches the substring anywhere in the line. Two option names contain "on": monitor and onecmd. Both are written to the snapshot as set -o monitor and set -o onecmd even when they are off, so every Bash tool shell runs with job control and onecmd enabled.

This appears to be the root cause of #47689 and #19057 (see also #17534 and #16231), which report set -o onecmd in snapshots on shells where it is off.

Reproduction

In a clean bash:

$ env -i bash --norc --noprofile -c 'set -o | grep -E "^(monitor|onecmd)\s"'
monitor         off
onecmd          off

$ env -i bash --norc --noprofile -c 'set -o | grep "on" | awk "{print \"set -o \" \$1}"'
set -o braceexpand
set -o hashall
set -o interactive-comments
set -o monitor
set -o onecmd

In Claude Code, ~/.claude/shell-snapshots/snapshot-bash-*.sh contains set -o monitor and set -o onecmd, and echo $- in a Bash tool call prints hmtBc (m is monitor, t is onecmd).

Effects

  • monitor in a non-interactive shell puts each background job in its own process group, and bash prints job-status lines such as [1]+ Done sleep 0.1 into tool output.
  • onecmd: the linked issues report Bash tool calls returning no output.

Suggested fix

Match the state column instead of the substring:

set -o | awk '$2 == "on" {print "set -o " $1}' | head -n 1000 >> "$SNAPSHOT_FILE"

With this change, the clean-shell output above contains only braceexpand, hashall, and interactive-comments.

Environment

  • Claude Code 2.1.283

View original on GitHub ↗