Preflight Checklist
What's Wrong?
Piped bash commands prompt for permission even when ALL individual components are already allowed in settings.json.
I have many bash commands allowed in my global settings.json:
"Bash(ls:*)",
"Bash(awk:*)",
"Bash(wc:*)",
"Bash(echo:*)"
Each command works fine individually:
ls /some/path - works without prompting
awk --version - works without prompting
But piped commands prompt for permission even when ALL components are allowed:
ls /some/path | awk '{print $1}' - prompts for permission
echo "test" | wc -l - prompts for permission
This is because the permission system uses prefix matching on the entire command string. Bash(awk:*) only matches commands that START with awk, not commands where awk appears after a pipe.
What Should Happen?
If I run cmd1 | cmd2 | cmd3 and each of cmd1, cmd2, cmd3 individually matches an allowed pattern, the full piped command should be allowed without prompting. Same for &&, ||, and ;.
Steps to Reproduce
- Add bash command permissions to global or local settings.json:
{
"permissions": {
"allow": [
"Bash(ls:*)",
"Bash(awk:*)",
"Bash(wc:*)",
"Bash(echo:*)"
]
}
}
- Ask Claude Code to run a simple allowed command like
ls /tmp - it runs without prompting
- Ask Claude Code to run a piped command like
ls /tmp | wc -l - it prompts for permission despite both ls and wc being individually allowed
Claude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
No response
Claude Code Version
2.0.61 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
I created a PreToolUse hook for a workaround, you can run npx claude-code-plus to get this behavior installed on your machine: claude-code-plus.
Preflight Checklist
What's Wrong?
Piped bash commands prompt for permission even when ALL individual components are already allowed in settings.json.
I have many bash commands allowed in my global settings.json:
Each command works fine individually:
ls /some/path- works without promptingawk --version- works without promptingBut piped commands prompt for permission even when ALL components are allowed:
ls /some/path | awk '{print $1}'- prompts for permissionecho "test" | wc -l- prompts for permissionThis is because the permission system uses prefix matching on the entire command string.
Bash(awk:*)only matches commands that START withawk, not commands whereawkappears after a pipe.What Should Happen?
If I run
cmd1 | cmd2 | cmd3and each ofcmd1,cmd2,cmd3individually matches an allowed pattern, the full piped command should be allowed without prompting. Same for&&,||, and;.Steps to Reproduce
{ "permissions": { "allow": [ "Bash(ls:*)", "Bash(awk:*)", "Bash(wc:*)", "Bash(echo:*)" ] } }ls /tmp- it runs without promptingls /tmp | wc -l- it prompts for permission despite bothlsandwcbeing individually allowedClaude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
No response
Claude Code Version
2.0.61 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
I created a PreToolUse hook for a workaround, you can run
npx claude-code-plusto get this behavior installed on your machine: claude-code-plus.