Skip to content

Instantly share code, notes, and snippets.

@webframp
Created May 20, 2026 13:19
Show Gist options
  • Select an option

  • Save webframp/2dbe1a7af7b5eb63f29d3132dbf06837 to your computer and use it in GitHub Desktop.

Select an option

Save webframp/2dbe1a7af7b5eb63f29d3132dbf06837 to your computer and use it in GitHub Desktop.
claude hook to block piping to python3
#!/usr/bin/env python3
# Goes in .claude/hooks/no-python-pipes.py
"""Block pipes / inline execution into python in Claude Code Bash calls."""
import json
import re
import sys
data = json.load(sys.stdin)
if data.get("tool_name") != "Bash":
sys.exit(0)
command = data.get("tool_input", {}).get("command", "")
# (regex, human-readable label)
patterns = [
(r'\bpython3?\s+-c\b', 'python -c "..." inline string'),
(r'\|\s*python3?\b', 'pipe into python'),
(r'\bpython3?\s*<<-?\s*\w', 'heredoc into python'),
(r'\bpython3?\s+<\(', 'process substitution into python'),
(r'\bpython3?\s+<\s', 'file redirect into python'),
(r'\bpython3?\s+-\s*$', 'python reading from stdin (-)'),
]
for pattern, label in patterns:
if re.search(pattern, command):
print(
f"Blocked: {label} detected.\n"
f"Project rule: never pipe or inline-execute Python. "
f"Write a .py file, then run `python3 path/to/file.py`.",
file=sys.stderr,
)
sys.exit(2) # exit 2 = block + show stderr to Claude
sys.exit(0)
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 ~/.claude/hooks/no-python-pipes.py"
}
]
}
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment