API エンドポイントをエクスポートする VPN フックが変えるのは、それが起動するプロセスの環境であり、トンネルが上がったときすでに開いていたターミナルの環境ではありません。この一つの違いが、「ツールが今も公開エンドポイントを呼んでいる」という報告のほとんどを説明します。設定を置ける現実的な場所は二つあり、選択は誰がそれを使うか、どれくらい頻繁に変わるかで決まります。別の起動スクリプトを足す前に、両者を比べてください。

設定を置ける二つの場所

一つ目の選択肢はコマンド自体への前置きで、その値はその一回の呼び出しにだけ存在し、呼び出しとともに消えます。二つ目は接続フックの内部でのエクスポートで、その時点以降にフックが起動するすべてのプロセスに届きます。両者は構文ではなく到達範囲と寿命が違い、その違いがほとんどの失敗を決めます。

PropertyPrefix on the commandExport from the hook
Who receives itThat invocation onlyChildren the hook starts
LifetimeUntil the process exitsUntil the hook's own session ends
LeakageScoped to one commandApplies to later commands in that session
Repeat costEvery invocationOnce per connection
Works for an open editorNo, unless the editor is started with itNo

表はフックを安く見せる一方で、タスクと何の関係もないコマンドにもプライベートなエンドポイントを選んでしまうため、本当の請求を隠しています。各行は好みではなく制約として読んでください。エンドポイントがタスクごとに変わるなら、キー一打の手間はかかっても前置きのほうが精度で勝ります。

フックがすでに開いているシェルに届かない理由

環境変数は、プロセスのイメージが作られるときにそのプロセスへ渡されます。接続より前に起動したシェルは受け取った複製を保持し、フックの中で実行されたエクスポートはマシン上のすべてのプロセスへの同報ではありません。継承するのはフック自身の子だけです。シェル自身の子は、起動した瞬間にシェルが持っているものを引き継ぐので、同じコマンドがあるターミナルでは動き、別のターミナルでは失敗します。

同じことはグラフィカルエディタにも当てはまります。その拡張機能ホスト、統合ターミナル、バックグラウンドの言語サーバーは起動時に分岐し、それぞれ複製を持っています。フォルダを開き直してもそれらの子が必ず再起動するわけではないので、追加した設定はやはり届きません。

最も安い検証は、動いているシェルではなく失敗する場所から変数を表示することです。失敗するプロセスがトンネルより前に起動していたなら、エクスポートには最初から機会がありませんでした。

コマンドごとの形を書き出す

前置きにすれば、使うコマンドの中に選択が見えたままになり、タスクごとにエンドポイントが変わるときに役立ちます:

env INTERNAL_API='https://internal-api.example.net:8443' my-work-tool

このコマンドは例示で、my-work-tool はプレースホルダー、INTERNAL_API は VPN の標準ではないため、実際に実行するプログラムの文書化された設定と、自分の承認済みホストに置き換えてください。同じ行にトークンやパスワードを置くとシェルの履歴に残るため、置かないでください。

複数のコマンドが一つのタスクに属するなら、短くレビュー済みのラッパースクリプトが変数を設定してからそれらを起動します。こうすれば定義は一つに保たれ、値がターミナルの今後のすべてのコマンドにグローバルになることもありません。

再読み込みするか、再起動するか、そのままにするか

すでに動いているツールなら、あれば自身の再読み込みやワークスペースプロファイルを優先してください。なければ作業を保存し、設定を読むコンポーネント(多くの場合エディタのウィンドウではなく言語サーバー)を再起動します。ウィンドウを再起動して子プロセスも付いてきたと決めつけるのが、再読み込みが効かないように見える理由です。

切断は別の判断です。一時停止、終了、再接続はアプリケーションの側の話で、エンドポイントの変数がそれを制御するわけではありません。変数はアドレスを選ぶ設定として扱い、その後にどの通信を使ってよいかの規則とはせず、二つの関心事は切り離したままにしておきましょう。

関連記事