Claude Media
Claude CodeでNushellは使えるか — Bashツールのシェルとpathの通し方

Claude CodeでNushellは使えるか — Bashツールのシェルとpathの通し方

NushellをログインシェルにしてもClaude CodeのBashツールはbashかzshで動きます。Nushell側のPATHの通し方と、bash構文が出力される問題への現実的な対処をまとめます。

Nushellをログインシェルにしていても、Claude Codeは使えます。ただしBashツールが動くのはNushellではなく、bashかzshです。Nushellを直接指定する設定は今のところありません。実際に困るのは、次の2点に絞られます。

  • claudeがcommand not foundになる(Nushell側のPATH)
  • Claudeが出力するコマンドがbash構文で、Nushellの目には読みにくい

前者は数行の設定で直り、後者は運用で緩和するしかありません。

Bashツールはログインシェルに関係なくbashかzshで動く

Claude Codeのシステム要件が挙げる対応シェルは、Bash・Zsh・PowerShell・CMDの4つです。Nushellは入っていません。

Bashツールが使うシェルの決まり方は、環境変数CLAUDE_CODE_SHELLの説明にまとまっています。

判定

Bashツールのシェルが決まる順序

  1. 1

    CLAUDE_CODE_SHELLを見る

    動作するbashかzshのパスが入っていれば、そのシェルを使います。未設定や、fish・Nushellなどのパスなら次へ進みます。

  2. 2

    $SHELLを見る

    $SHELLがbashかzshならそれを使います。Nushellを指しているときは次へ進みます。

  3. 3

    PATHと標準の場所から探す

    最初に見つかった動作するzsh、なければbashが選ばれます。

記述は「fishのような他のシェルはサポートされない」で、Nushellも同じ扱いです。$SHELLが/usr/bin/nuを指していても、そのまま無視されます。zshかbashが入っている環境なら、特に設定しなくてもBashツールは動きます。

CLAUDE_CODE_SHELLで固定する場合は、settings.jsonのenvに書けます。

{
  "env": {
    "CLAUDE_CODE_SHELL": "/opt/homebrew/bin/bash"
  }
}

パスは環境変数の説明にある例と同じHomebrewのbashです。nuのパスを書いても、上の順序どおり自動検出に回るだけです。

v2.1.289のclaude --helpを見ても、シェルを選ぶオプションは出ません。BashやPowerShellの名前が出てくるのは、--allowedToolsなどツール名を指定する説明の中だけです。シェルの指定は、環境変数と設定ファイルで行います。

defaultShellにもNushellは指定できない

設定の名前から、defaultShellにNushellを書けそうに見えます。しかし値は"bash"か"powershell"の2択です。しかもこの設定が切り替えるのは、入力欄で!を付けて打つ対話コマンド(shell mode)だけです。値の意味と各環境での既定はdefaultShellでshell modeの既定シェルを変更するにまとめています。

もう1つ紛らわしいのがPowerShellツールです。第二のシェル言語を扱う仕組みとして存在しますが、対象はPowerShellだけです。CLAUDE_CODE_USE_POWERSHELL_TOOLを有効にしても、Nushellが使えるようにはなりません。

Nushell側でPATHを通す

claudeがcommand not foundになる原因は、たいていインストーラーが使う~/.local/binがNushellのPATHに入っていないことです。トラブルシューティングのページは、fishやNushellのユーザーには「シェル自身の設定構文で~/.local/binをPATHに追加し、ターミナルを再起動する」とだけ案内しています。Nushellでの書き方は、Nushell公式ドキュメントに載っています。

NushellはPATHを文字列ではなくリストとして扱います。起動時に継承した文字列を、自動でリストに変換するためです。そのため末尾への追加は次のように書けます。

$env.path ++= ["~/.local/bin"]

先頭に足して優先順位を上げたいときは、標準ライブラリのpath addが使えます。既定の動作は先頭への追加です。

use std/util "path add"
path add "~/.local/bin"
path add ($nu.home-dir | path join ".cargo" "bin")

config.nuはconfig nuコマンドで開けます。編集後は新しいNushellセッションを開くと反映されます。bash用のexport PATH="$HOME/.local/bin:$PATH"は、Nushellではそのまま通りません。

Nushellの環境変数の名前は大文字小文字を区別しません。Path、path、PATHはどれも同じ変数の別表記として扱われます。

env.nuとconfig.nuのどちらに書くか

かつては環境変数をenv.nuに書くのが定石でした。Nushellの現行ドキュメントでは、環境変数などの設定はconfig.nuか自動読み込みディレクトリに書く方式が推奨です。古い記事の手順をなぞってenv.nuに書いた設定が残っていても、動作はしますが、新規に書くならconfig.nuが無難です。

ログインシェルならlogin.nuも確認する

Nushellをログインシェルにしている場合は、login.nuの存在に注意が必要です。Nushellのドキュメントによると、ログインシェルとしての起動時にだけ実行したい設定はlogin.nuに書きます。POSIX向けの~/.profileはNushellでは処理できません。従来のログインシェルで.profileなどに書いていた環境変数が、Nushellではlogin.nuに移っていないと、PATHを含む値が引き継がれません。

継承されている環境変数を洗い出す1行も、Nushellのドキュメントにあります。従来のログインシェルの中でnuを起動して実行します。

$env | reject config | transpose key val | each {|r| echo $"$env.($r.key) = '($r.val)'" } | str join (char nl)

出力から必要なものだけをlogin.nuに写します。PS1のようにPOSIXのプロンプト用の値は不要です。

起動方法でconfig.nuが読まれるかが変わる

Nushellの起動方法ごとに、読み込まれる設定ファイルは違います。nu -c "ls"はenv.nuもconfig.nuもlogin.nuも読みません。nu -l -c "ls"(ログインシェル指定)なら3つとも読みます。外部プログラムがNushellをコマンド文字列付きで呼ぶ場合、config.nuに書いたPATHや設定が効いていないことがあるのはこのためです。

Claude Codeに渡るPATHはどこで決まるか

Bashツールのドキュメントには、環境の引き継ぎについて次の記述があります。

  • Bashツールは、セッション開始時に~/.zshrc、~/.bashrc、~/.profileのいずれかを読み込み、得られたエイリアス・関数・シェルオプションを以降のBashコマンドすべてに適用する
  • Bashコマンド間で環境変数を持ち越したいときは、CLAUDE_ENV_FILEにシェルスクリプトを指定するか、SessionStartフックで生成する

読み込まれるのはbash/zshの起動ファイルなので、Nushellのconfig.nuは対象外です。つまりconfig.nuに書いたPATHが、Bashツールの中でも使えるとは限りません。Nushellからclaudeを起動したなら、プロセスの環境変数として継承されたPATHが元になります。継承されなかった場合は、~/.zshrcや~/.bashrc側にPATH追加を書きます。

export PATH="$HOME/.local/bin:$PATH"

zsh・bashの起動ファイルがいつ読まれるかはClaude Codeのシェル起動設定で扱っています。fishで同じ問題が起きたときの解説はClaude CodeでfishシェルのPATHを通す設定と注意点です。OS・シェルを問わない一般的な確認手順はClaude Codeのcommand not foundをPATH設定で直すにあります。

切り分けの手順

Nushellのプロンプトで確認する順序は次のとおりです。

手順

Nushellのプロンプトでの切り分け

  1. 1

    Nushell側から見えるか

    which claudeでclaudeが見つかるか確認します。

  2. 2

    見つからないとき

    path addをconfig.nuに書き(ログインシェルならlogin.nuにも)、新しいセッションで再確認します。

  3. 3

    見つかるのにClaude内で見つからないとき

    Claudeにecho $PATHをBashツールで実行させ、~/.local/binが含まれるか見ます。

  4. 4

    含まれないとき

    ~/.zshrcまたは~/.bashrcにPATH追加を書きます。

Nushellのaliasや自作コマンドはBashツールの中では使えません。Claudeに実行させる処理は、bash/zshで動く形にしておきます。

ClaudeにNushell構文を書かせたいときの現実的な対処

もう1つの悩みは、Claudeが出力するコマンドがbash構文になることです。GitHubのissue #83537は、Nushellを既定シェルにできるようにする機能要望です。「Claudeが出力するbashコマンドが読みにくく、承認する自信を持てない」という動機が書かれています。このissueはopenで、ラベルはenhancementとarea:toolsです。

同じissueのコメントには、利用者が試した回避策の組み合わせが載っています。投稿者は手元のマシンすべてでNushellをログインシェルにし、CI用のヘルパーやデプロイ用のスクリプトもNushellで書いています。仕様ではなく利用者の報告です。

  1. グローバルのCLAUDE.mdに、ユーザーへ渡すコマンドはNushellで書く指示と、bash構文が紛れ込みやすい箇所のチェックリストを書く
  2. UserPromptSubmitフックで、毎ターン短いリマインダーを注入する
  3. 入力欄のコマンドは!nu -c '<command>'で実行する
  4. Nushellの書き方と落とし穴をまとめたSkillを用意する

コメントの投稿者は、この構成で「ユーザーに渡すコマンド」はおおむね守られると書いています。一方でツール本体は変えられないとも述べています。Bashツールはbash構文を前提にしているためです。

CLAUDE.mdの指示は、例えば次のような形にできます。あくまで例示で、効果の程度はプロジェクトごとに確認が必要です。

## シェルの扱い
- Claudeが自分のBashツールで実行するコマンドは、bash構文で書く
- ユーザーに手で実行してもらうコマンドは、Nushell構文で書く
  - 変数: `let x = 1`(`x=1`ではない)
  - 環境変数: `$env.FOO = "bar"`(`export FOO=bar`ではない)
  - コマンド置換: `(cmd)`(`$(cmd)`ではない)
  - 連結: `;`(`&&`ではない)

!nu -c '<command>'は、!コマンドの実行環境がbashである前提での回避策です。シングルクォートで囲むと、bashが中の文字列をそのままnuに渡します。ただし報告では、この方式だとNushellのaliasや自作コマンドは引き継がれません。nu -cは前述のとおりconfig.nuを読まないためです。nu -l -cにすればログインシェルとして設定を読みます。

Nushellをログインシェルにするか迷う場合

Claude Code中心の作業なら、ログインシェルはそのままNushellにして、Claudeが動く範囲(Bashツール)はbash/zshと割り切る運用が現実的です。Claudeに読ませるスクリプトやhooksのコマンドも、bashで書いておけば余計な変換が要りません。

逆にNushellの構文をClaudeが一貫して出力してくれることを期待すると、期待外れになります。issueの要望が通り、Bashツールの説明でシェルがNushellと明示されるようになるまでは、指示で補う形が続きます。

まとめ

NushellをログインシェルにしたままClaude Codeを使う場合、PATHはconfig.nuとlogin.nu、Claude内で必要なPATHは~/.zshrcか~/.bashrcと、書く場所が2系統に分かれます。bash構文の読みにくさはツール側の仕様です。人に渡すコマンドの構文はCLAUDE.mdで指定して緩和し、Claudeに読ませるスクリプトやhooksはbashで書いておけば変換の手間が要りません。

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