Skip to content

Instantly share code, notes, and snippets.

@johnlindquist
Last active January 23, 2026 05:26
Show Gist options
  • Select an option

  • Save johnlindquist/a22d4171e56107b55d60db4a0e929fb3 to your computer and use it in GitHub Desktop.

Select an option

Save johnlindquist/a22d4171e56107b55d60db4a0e929fb3 to your computer and use it in GitHub Desktop.
Loading ZSH Functions into Claude Code

Loading ZSH Functions into Claude Code

Make your shell functions and aliases available to Claude Code's Bash tool.

Setup

1. Create the Shell Init Script

Create ~/.claude/shell-init.sh:

#!/bin/bash
# Claude Code shell initialization
# Sources zsh configuration to make functions/aliases available

# Respect ZDOTDIR if set, otherwise fall back to ~/.config/zsh or ~
ZDOTDIR="${ZDOTDIR:-${HOME}/.config/zsh}"

# Source zsh config (suppress errors for bash-incompatible syntax)
if [ -f "$ZDOTDIR/.zshrc" ]; then
  source "$ZDOTDIR/.zshrc" 2>/dev/null || true
elif [ -f "$HOME/.zshrc" ]; then
  source "$HOME/.zshrc" 2>/dev/null || true
fi

Make it executable:

chmod +x ~/.claude/shell-init.sh

2. Export the Environment Variable

Add to your ~/.zshrc (or ~/.config/zsh/conf.d/*.zsh if using modular config):

export CLAUDE_ENV_FILE="$HOME/.claude/shell-init.sh"

3. Restart Your Shell

source ~/.zshrc
# or just open a new terminal

How It Works

  1. When Claude Code starts, it reads CLAUDE_ENV_FILE from the environment
  2. Before running any Bash command, Claude sources this script
  3. Your functions, aliases, and environment variables become available
  4. Claude can now use your custom shell functions in its Bash tool

Example Functions

Once set up, Claude can use functions like:

# Your function in .zshrc
dopus() { claude --model opus --dangerously-skip-permissions "$@"; }

# Claude can now run:
# dopus "Fix the bug in main.ts"

Example: Modular ZSH Config

If you use a modular zsh config structure:

~/.config/zsh/
├── .zshrc              # Main entry point
├── conf.d/
│   ├── 10-path.zsh     # PATH configuration
│   ├── 20-aliases.zsh  # General aliases
│   ├── 30-functions.zsh # Shell functions
│   └── 40-ai.zsh       # AI tool configs (CLAUDE_ENV_FILE lives here)

In ~/.config/zsh/conf.d/40-ai.zsh:

# Claude Code configuration
export CLAUDE_ENV_FILE="$HOME/.claude/shell-init.sh"

# Convenience aliases
alias c='claude'
alias dopus='claude --model opus --dangerously-skip-permissions'

Tips

  • Use 2>/dev/null || true when sourcing to suppress bash-incompatible zsh syntax errors
  • Keep frequently-used AI helper functions in a separate file (e.g., ~/.config/zsh/conf.d/40-ai.zsh)
  • Test your init script manually: bash ~/.claude/shell-init.sh && type your_function
  • Functions defined with zsh-specific syntax won't work (Claude uses bash)

Verify It's Working

Check if Claude sees your environment:

# In Claude's Bash tool, this should show your init file
echo $CLAUDE_ENV_FILE

Or ask Claude to run one of your functions directly.

Troubleshooting

Functions Not Available

  1. Check the env var is set: echo $CLAUDE_ENV_FILE
  2. Test the script manually: bash ~/.claude/shell-init.sh
  3. Verify function is bash-compatible (not zsh-only syntax)

Syntax Errors

If you see errors when Claude runs commands, your .zshrc likely has zsh-specific syntax. The 2>/dev/null || true suppresses most of these, but you may need to wrap incompatible sections:

# In your .zshrc
if [[ -n "$ZSH_VERSION" ]]; then
  # zsh-only stuff here
fi

Related: Disabling Hooks

If you need to run Claude without hooks (e.g., for testing), see the Hidden Flags gist for workarounds using --setting-sources "" and --settings '{"hooks": {}}'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment