Created
February 10, 2026 12:09
-
-
Save weslien/70af6c7b5e8a595b8b35af11fbef1702 to your computer and use it in GitHub Desktop.
Keep 2 different claude code accounts using aliases and symlinks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # multi-claude-setup.sh | |
| # | |
| # Helper script to run multiple Claude Code accounts (e.g. work + personal) | |
| # on macOS with zsh, using: | |
| # - one config directory per account | |
| # - a shared ~/.claude for non-secret data | |
| # - per-account .claude.json (tokens/session) kept separate | |
| # | |
| # Usage: | |
| # chmod +x multi-claude-setup.sh | |
| # ./multi-claude-setup.sh | |
| # | |
| # After running: | |
| # - `claude-w` will start Claude Code with your "work" account | |
| # - `claude-p` will start Claude Code with your "personal" account | |
| # | |
| # Then: | |
| # 1) Run `claude-w` once, log in with work credentials in the browser. | |
| # 2) Run `claude-p` once, log in with personal credentials. | |
| # | |
| # Inspired by community patterns for multi-account config dirs. [web:4][web:6][web:11] | |
| set -euo pipefail | |
| # ---- CONFIG ---- | |
| BASE="${HOME}/.claude" # canonical/shared directory | |
| WORK="${HOME}/.claude-work" # work account config dir | |
| PERSONAL="${HOME}/.claude-personal" # personal account config dir | |
| ZSHRC="${HOME}/.zshrc" | |
| # Files/dirs we will NOT symlink (account-specific) | |
| # .claude.json is where Claude stores per-account session / MCP state.[web:12][web:40] | |
| EXCLUDE_REGEX='^\.?\.$|^\.claude\.json' | |
| # ---- FUNCTIONS ---- | |
| make_dir_if_missing() { | |
| local dir="$1" | |
| if [ ! -d "$dir" ]; then | |
| echo "Creating directory: $dir" | |
| mkdir -p "$dir" | |
| fi | |
| } | |
| link_shared_items() { | |
| local target_dir="$1" | |
| echo | |
| echo "Linking shared items into: $target_dir" | |
| cd "$target_dir" | |
| # Iterate all items in BASE (including dotfiles) except . and .. and .claude.json* [web:46][web:47] | |
| # We use 'ls -A' to include dotfiles but skip . and ... | |
| for item in $(ls -A "${BASE}"); do | |
| if echo "$item" | grep -Eq "$EXCLUDE_REGEX"; then | |
| # Skip files we know should remain per-account | |
| continue | |
| fi | |
| # If something already exists, leave it alone | |
| if [ -e "$item" ] || [ -L "$item" ]; then | |
| continue | |
| fi | |
| echo " ln -s ${BASE}/${item} -> ${target_dir}/${item}" | |
| ln -s "${BASE}/${item}" "${item}" | |
| done | |
| } | |
| ensure_alias() { | |
| local alias_name="$1" | |
| local alias_value="$2" | |
| if grep -Fq "$alias_name" "$ZSHRC"; then | |
| echo "Alias '$alias_name' already present in ${ZSHRC}, skipping." | |
| else | |
| echo "Adding alias '$alias_name' to ${ZSHRC}" | |
| { | |
| echo "" | |
| echo "# Claude Code multi-account alias: ${alias_name}" | |
| echo "alias ${alias_name}='CLAUDE_CONFIG_DIR=\"${alias_value}\" claude'" | |
| } >> "$ZSHRC" | |
| fi | |
| } | |
| # ---- MAIN ---- | |
| echo "=== Claude Code multi-account setup (work + personal) ===" | |
| # Ensure base shared dir exists | |
| make_dir_if_missing "$BASE" | |
| # Ensure work/personal dirs exist | |
| make_dir_if_missing "$WORK" | |
| make_dir_if_missing "$PERSONAL" | |
| # Link shared content into work + personal | |
| link_shared_items "$WORK" | |
| link_shared_items "$PERSONAL" | |
| # Add convenient aliases to .zshrc [web:4][web:41] | |
| ensure_alias "claude-w" "$WORK" | |
| ensure_alias "claude-p" "$PERSONAL" | |
| echo | |
| echo "Done." | |
| echo | |
| echo "Next steps:" | |
| echo " 1) Restart your terminal or run: source \"$ZSHRC\"" | |
| echo " 2) Run 'claude-w' and log in with your WORK account." | |
| echo " 3) Run 'claude-p' and log in with your PERSONAL account." | |
| echo | |
| echo "Notes:" | |
| echo " - ${BASE} holds your shared settings, history, projects, etc." | |
| echo " - ${WORK} and ${PERSONAL} keep their own .claude.json (tokens / sessions)." | |
| echo " - If new credential files appear under ${BASE} in future releases," | |
| echo " move them into WORK/PERSONAL and keep them out of the shared dir.[web:22][web:29]" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment