Bash tool ignores login shell from /etc/passwd, auto-detects zsh from .zshrc
Bug Description
The Bash tool overrides the SHELL environment variable and uses zsh instead of the user's actual login shell (fish), apparently because it finds a .zshrc file.
Environment
- OS: WSL2 (Ubuntu) on Windows
- Login shell (from
/etc/passwd):/usr/bin/fish - Claude Code version: latest CLI
Steps to Reproduce
- Set login shell to fish:
chsh -s /usr/bin/fish - Have a
.zshrcfile present (e.g. from previously using zsh) - Launch Claude Code from fish
- Use the Bash tool to run any command
Expected Behavior
The Bash tool should respect the login shell from /etc/passwd (/usr/bin/fish) or at minimum the SHELL environment variable inherited from the parent process.
The parent Claude process correctly has SHELL=/usr/bin/fish (confirmed via /proc/$PPID/environ), but the spawned shell process has SHELL=/usr/bin/zsh.
Actual Behavior
The Bash tool sets SHELL=/usr/bin/zsh and launches zsh, which sources .zshrc and loads oh-my-zsh with all its plugins. This causes:
- Unexpected aliases (e.g. tmux plugin alias overrides
tmuxcommand) - Slower shell startup due to oh-my-zsh initialization
- Side effects from zsh plugins (e.g.
ZSH_TMUX_AUTOSTART=truetrying to create tmux sessions)
Evidence
# Parent process (claude) has correct SHELL:
cat /proc/$PPID/environ | tr '\0' '\n' | grep SHELL
# Output: SHELL=/usr/bin/fish
# But Bash tool runs zsh:
echo "$0 / $SHELL"
# Output: /usr/bin/zsh / /usr/bin/zsh
# Login shell is fish:
getent passwd $USER | cut -d: -f7
# Output: /usr/bin/fish
Suggested Fix
Shell detection priority should be:
SHELLenvironment variable inherited from parent process- Login shell from
/etc/passwd(getent passwd $USER) - Fall back to bash
The presence of .zshrc or .bashrc files should NOT override the user's configured shell.
Workaround
Renamed .zshrc so Claude Code doesn't detect zsh.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗