PATHにチルダを書いてはいけない

Don't Put Tilde In Your Path

PATHにチルダを書いてはいけない

シェルの設定ファイルでPATHに「~/.local/bin」と書くと、チルダは展開されず、カレントディレクトリ配下の「./~/.local/bin」がPATHに追加される。nonoツールの警告をきっかけにこの落とし穴を解説し、$HOMEを使う修正法と確認コマンドを紹介する。

Bashは、変数代入において、『:』または最初の『=』の直後にあるクォートされていないチルダプレフィックスをチェックし、これらの場合にチルダ展開を行います。
  1. SoftTalker

    スクリプトではチルダは絶対に使わない。対話的にコマンドを打つときの便利機能としてだけ使う。

    それ以外は$HOMEを使う。これにも落とし穴はあるが、他の環境変数と同じ話だ。

  2. amarshall

    それか、単に…チルダをクォートしなければいいだけでは。みんなBashで「文字列」を反射的にクォートしてしまうけど、(ほぼ)すべては文字列で、ほとんどの文字列はクォートされないし、クォートするのはむしろ変だということに気づいていない(例えば`"ls" "-a" "foo"`なんて誰もやらない)。

  3. thefilmore

    単にこうすればいいだけだ:

    PATH=~/.local/bin:$PATH

    PATHはすでにexportされている。代入にクォートも不要だ。

  4. FeepingCreature

    ~/.local/binのPATHが機能していないことに気づくべきだったんじゃないか?

  5. alexpotato

    チルダの話というより、大企業でbashに起こりうる狂気について:

    以前の仕事で、自分のbashrcのどの部分が特定の環境変数を設定しているのか突き止めようとしていた。ユーザープロファイルにインストールされた何らかのデフォルトか、/etc/<何か>から継承しているのだろうと想定していた。

    すぐに、自分のbashrcが他のファイルをインポートしていることに気づいた。これもまた、インポートは1階層深いだけだろうという想定だった。

    ところが、「ur-bashrc」から始まって、さらに何層ものインポートが積み重なり、ようやくユーザーレベルのプロファイルにたどり着くまで、10層以上のインポートがあったのだ。

    あまりに入り組んでいて気が狂いそうになったが、このStack Exchangeの投稿を見つけて救われた:https://unix.stackexchange.com/questions/813/how-to-determin...

    bashのインポートで「トレース」を有効にして、環境変数がどこで設定されているかを絞り込めるようにするものだ。

  6. dspillett

    「自分の環境ではいつも動くようだけど」と言おうとしたら、「…実はBashとZshで動く、なぜなら…」という記述を見てしまった。

    移植性を意識するときには使わないよう気をつけるべき、また別のBash固有の機能だ。

    多くのシステムでは/bin/shはbash(やzsh)ではないので、Bash固有の機能に頼りたい(あるいはそれらを探すのが面倒な)なら、明確にシバンに「#!/bin/bash」を使うべきだ。例えばDebianやその類似ディストロでは通常dashだ。

  7. the__alchemist

    Linuxディストロが、スクリプト言語から切り離された「ターミナル」や「CLI」プログラムなどを同梱してくれたらいいのにと思う。特定のシェルに縛られない普遍的なPath環境変数を持たせてほしい。cdコマンドを実行したり、python/git/cargo/任意のアプリケーションを起動したり、優れたブックマーク+オートコンプリートシステムを持たせたりできるように。スクリプト言語とCLIアプリケーションの混同が、こうした複雑さや微妙な問題の根源のように感じる。

    シェルスクリプトを使うなら(そしてBashなどをPythonより好むなら)、Bash/Fish/Zshなどを引き続き使えばいい。GUIを持たないアプリケーションを起動したり、ディレクトリを移動したり、ファイルシステム操作を行ったりするためにCLIを使うなら、素のターミナルを使えばいい。

  8. ligarota

    ホームへのシンボリックリンクである~というファイルを作ればいいだけだよ :)

    大天才の時間だ

この日のほかの記事

2026-10-11