Bash tool: shell-quote mangles { }, heredoc markers, and $ in piped commands
Related: #4711 (fixed 2>&1 mangling in v1.0.74). These are further edge cases in the same shell-quote reconstruction path.
Bug Description
The Bash tool's shell-quote library doesn't understand several shell constructs. When pipes are present, token reconstruction mangles them. Three related symptoms:
1. Brace groups { } quoted as literals
# Works — no pipe
{ echo inside braces; }
# Output: inside braces
# Fails — with pipe
true | true; { echo inside braces; }
# set -x trace shows: '{' echo inside braces
# Error: /bin/bash: line 1: {: command not found
2. Heredoc markers containing hyphens are split
# Fails — hyphens in heredoc marker
bash <<'MY-MARKER'
echo hi | cat
MY-MARKER
# Error: syntax error near unexpected token `<'
# Reconstructed as: bash < < MY-MARKER echo hi ...
Markers using only [A-Za-z0-9_] survive reconstruction by accident — shell-quote treats them as simple word tokens.
3. $ expansion broken in pipes (likely related to #29298)
# Works
echo "PID=$$"
# Output: PID=12345
# Fails
true | true; echo "PID=$$"
# Output: PID=
Root Cause
All three stem from shell-quote not recognizing these as shell syntax during tokenization. When the command contains a pipe, shell-quote parses and reconstructs the token stream, and the reconstruction:
- Quotes
{and}as literal strings - Splits
<<'MARKER'into separate<<tokens when the marker contains non-word characters - Escapes or drops
$in variable references
Workaround
Wrap commands in a heredoc so shell-quote only sees bash and a simple redirect. The heredoc marker must use only [A-Za-z0-9_] characters:
bash <<'BASH_SAFE'
true | true; { echo inside braces; }
BASH_SAFE
This can be automated via a PreToolUse hook (we have one at ~/.claude/hooks/bash-preamble.py).
Environment
- Claude Code: 2.1.72
- Platform: linux
- Shell: bash
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗