Claude Media
defaultShellでshell modeの既定シェルを変更する

defaultShellでshell modeの既定シェルを変更する

settings.jsonのdefaultShellは!から始まる対話コマンドの既定シェルを切り替える設定です。PowerShellツールとの関係、hooks・Skillsの同名設定との違いをまとめます。

settings.jsondefaultShellは、入力欄で!から始めて実行する対話コマンドの既定シェルを切り替える設定です。値は"bash""powershell"のいずれかで、Windows環境でGit Bashが無い場合は自動的に"powershell"になります。この設定が効くのは!コマンドだけで、Claudeが呼び出すBashツール自体やhooks・Skillsのシェル選択は別の設定で決まります。WSL2とPowerShellが混在する環境では、この3つを混同すると意図しないシェルでコマンドが実行されます。名前だけ見ると「Claude Code全体の既定シェル」を決める設定に見えますが、実際に切り替わる範囲はかなり狭いことを最初に押さえておくと、設定ミスを避けやすくなります。

defaultShellは何を切り替える設定か

Claude Codeの入力欄で!を先頭に付けて実行するコマンドは「shell mode」と呼ばれ、Claudeの承認を経ずに直接シェルへ渡されます。

! npm test
! git status

defaultShellは、このshell modeで使うシェルを指定します。既定値は"bash"ですが、Git Bashが無いWindows環境ではPowerShellが自動的に既定シェルになります。

{
  "defaultShell": "powershell"
}

"powershell"を指定するには、あらかじめPowerShellツールが有効になっている必要があります。Windows(Git Bashなし)では自動で有効ですが、Windows(Git Bashあり)は段階的ロールアウト中、Linux・macOS・WSLではオプトインです。

PowerShellツールを有効にする

Linux・macOS・WSLでdefaultShell"powershell"にするには、先にPowerShellツール自体を有効化します。

{
  "env": {
    "CLAUDE_CODE_USE_POWERSHELL_TOOL": "1"
  },
  "defaultShell": "powershell"
}

この環境ではPowerShell 7以降(pwsh)がPATH上に必要です。有効化すると、ClaudeはPowerShellを主シェルとして扱うようになりますが、Git Bashが入っている環境ではBashツールもPOSIXスクリプト用に引き続き使えます。実行ポリシーは-ExecutionPolicy Bypass付きでプロセス単位に起動されるだけなので、グループポリシーのMachinePolicy/UserPolicyは上書きされません。マシンの実効ポリシーに従わせたい場合はCLAUDE_CODE_POWERSHELL_RESPECT_EXECUTION_POLICY=1を設定します。zsh・bashの起動ファイル読み込みとPowerShellプロファイルの扱いの違いはClaude Codeのシェル起動設定で詳しく扱っています。

Git BashとPowerShellをどう見つけているか

defaultShellの既定値がWindowsでGit Bashの有無によって変わるのは、Claude Codeが起動時にGit Bashを探しに行く手順を持っているためです。CLAUDE_CODE_GIT_BASH_PATHが未設定の場合、Claude Codeは次の順でbash.exeを探します。

  1. C:\Program Files\GitC:\Program Files (x86)\Gitの既定インストール先
  2. PATH上のgitから辿れるbin\bash.exe

2番目の探索では、Claude Codeを起動したフォルダ配下や、node_modules.venvenvのようなパスに置かれたgitは意図的にスキップされます。プロジェクトが配置した実行ファイルを誤って実行しないための挙動です。この位置にGitがある場合は、CLAUDE_CODE_GIT_BASH_PATHで明示的に指定します。

{
  "env": {
    "CLAUDE_CODE_GIT_BASH_PATH": "C:\\Program Files\\Git\\bin\\bash.exe"
  }
}

このパスはbash.exesh.exebashshという名前のファイルしか受け付けません。Git for Windowsのランチャーであるgit-bash.exeのような別名を指定すると、変数ごと無視されて自動検出にフォールバックします(--debugで警告が確認できます)。この探索の結果としてGit Bashが1つも見つからなければ、Claude CodeはBashツールを使わずPowerShellツールを既定で有効にします。defaultShellが自動で"powershell"になる、というさきほどの挙動はこの探索の帰結です。

defaultShellと混同しやすい2つの設定

シェル選択に関わる設定はdefaultShell以外に2つあり、それぞれ効く範囲が違います。

設定効く範囲PowerShellツールの有効化
defaultShell(settings.json)効く範囲!から始まる対話コマンド(shell mode)PowerShellツールの有効化必要
shell(個別のcommand hookフィールド)効く範囲そのhookの実行PowerShellツールの有効化不要(PowerShellを直接起動するためCLAUDE_CODE_USE_POWERSHELL_TOOLの値に関係なく動く)
shell: powershell(Skillのfrontmatter)効く範囲Skill内の!`command`ブロックPowerShellツールの有効化必要

defaultShell"powershell"に変更しても、hooksやSkillsで使うシェルは自動では切り替わりません。hookは個別のshellフィールドを持たせて明示的に指定する必要があり、こちらはPowerShellツールが無効でも動きます。このshellフィールドでは、Windowsではpwsh.exe(7以降)を自動検出し、無ければpowershell.exe(5.1)にフォールバックします。Claude Codeが自らhookを起動する仕組みだからです。逆にSkill内の!`command`構文はPowerShellツールの有効化が前提になる点でdefaultShellと条件が揃っています。PreToolUseフックで実行コマンドを検査している場合は、BashだけでなくBash|PowerShellにマッチさせないと、PowerShellツール経由のコマンドを取りこぼします。

{
  "type": "command",
  "shell": "powershell",
  "command": "& \"$env:CLAUDE_PROJECT_DIR\\.claude\\hooks\\check.ps1\""
}

このhookの例では、プロジェクトルートの参照に${CLAUDE_PROJECT_DIR}ではなく$env:CLAUDE_PROJECT_DIRを使っています。PowerShellのシェル形式コマンドでは、v2.1.198以降${CLAUDE_PROJECT_DIR}が自動的に${env:CLAUDE_PROJECT_DIR}形式へ書き換えられますが、この展開はダブルクォート文字列の中でしか効きません。シングルクォートで囲むとPowerShellは変数展開を一切行わないため、$CLAUDE_PROJECT_DIRという裸の書き方をすると未定義のローカル変数として$nullに解決され、スクリプトパスからプロジェクトルートの接頭辞が欠け落ちます。Claude Codeはこの形をリライトしないため、デバッグログに警告が残るだけで気づきにくい失敗になります。defaultShellをPowerShellにしている環境でhookを書くときは、この$env:形式の書き分けも合わせて意識しておくと安全です。

WSL2/PowerShell混在環境での設定パターン

WSL2からWindows側のPowerShellを併用する構成では、次の組み合わせが典型的です。

シーン推奨設定
WSL2内は主にbashで作業、!コマンドもbashのまま推奨設定defaultShellを設定しない(既定の"bash"のまま)
WSL2内でも!コマンドだけPowerShellへ通したい推奨設定CLAUDE_CODE_USE_POWERSHELL_TOOL=1 + defaultShell: "powershell"
WindowsネイティブでGit Bash未導入推奨設定何も設定しなくても自動でPowerShellが既定になる
hookだけPowerShellで実行し、!コマンドはbashのまま推奨設定defaultShellは変更せず、対象hookに"shell": "powershell"を個別指定

WSL2上でPowerShellツールを使う場合、pwshがPATHに無いと有効化に失敗します。WindowsのPowerShell実行ファイルとWSL側のPATHは別物なので、WSL側にpwsh(PowerShell 7)を別途インストールしておく必要があります。WSLディストリビューションのパッケージマネージャー経由でインストールするのが最も確実で、Windows側にだけPowerShellが入っている状態では、WSL内のClaude CodeからはPowerShellツールを有効化できません。

よくある質問

defaultShellを変更するとBashツールでの通常のコマンド実行も変わりますか

変わりません。defaultShellが効くのは入力欄で!から始める対話コマンド(shell mode)だけです。Claudeがツール呼び出しとして実行する通常のBashコマンドは、この設定の影響を受けません。

defaultShellを"powershell"にしたのに!コマンドがbashのまま実行されます

PowerShellツールが有効化されていない可能性があります。Windows(Git Bashあり)・Linux・macOS・WSLではCLAUDE_CODE_USE_POWERSHELL_TOOL=1を明示的に設定する必要があります。Windows(Git Bashなし)以外では自動で有効にはなりません。

hooksの実行シェルもdefaultShellで決まりますか

決まりません。hooksは個別のshellフィールドで指定します。このshellフィールドはPowerShellを直接起動するため、PowerShellツールが無効な環境でも動作します。

PowerShellツールにはどんな制約がありますか

プレビュー中の制約として、PowerShellプロファイル($PROFILE)を読み込まない点と、Windowsでのサンドボックス実行に対応していない点があります。プロファイル依存のエイリアスや関数は、Claude CodeのPowerShellコマンドからは参照できません。

Gitは入っているのにPowerShellツールが使われてしまいます

Claude Codeが既定のインストール先やPATH上のgitからbash.exeを見つけられていない可能性があります。プロジェクト直下やnode_modules.venv配下にあるgitは探索の対象から意図的に除外されるため、そうした場所にGitを置いている場合はCLAUDE_CODE_GIT_BASH_PATHbin\bash.exeのフルパスを明示します。指定したファイル名がbash.exesh.exebashshのいずれでもない場合も、変数ごと無視されて自動検出にフォールバックする点に注意してください。設定を変えたのに挙動が変わらないときは、まずこのファイル名条件から疑うと原因を絞りやすくなります。

まとめ

defaultShellは名前の印象より効く範囲が狭く、!から始まる対話コマンドの既定シェルを切り替える設定で、"bash""powershell"を指定します。"powershell"を使うにはPowerShellツールの有効化(CLAUDE_CODE_USE_POWERSHELL_TOOL)が前提で、Windows(Git Bashなし)以外では明示的な設定が必要です。hooksのshellフィールドやSkillのshell: powershellは別の設定で、defaultShellを変えても自動では揃いません。WSL2とPowerShellが混在する環境では、この3つの設定がどの範囲に効くかを分けて考えると設定ミスを避けられます。settings.jsonの全体像はClaude Code settings.json完全ガイド、環境変数の一覧はClaude Code環境変数リファレンス、Hooksの書き方はClaude Code Hooksの設定方法で確認できます。

この記事を共有:XはてブLinkedIn