Fish Shell環境でのDockerコマンド実行エラーを修正

basecamp/kamal

KamalのDockerコマンド生成において、フィルタ名をシングルクォートで囲むことでFish Shell環境での実行エラーを解消しました。これにより、Bash以外のシェルを使用する環境でも正常に動作するようになります。

背景

Fish Shell環境で kamal details コマンドを実行すると、以下のエラーが発生していました:

fish: Expected a variable name after this $.
docker ps --filter name=^kamal-proxy$

この問題は #1691 で報告されており、Fish Shellが $ 記号を変数展開の開始として解釈することに起因します。Kamalが生成するDockerコマンドの --filter name=^kamal-proxy$ という指定において、末尾の $ が正規表現の行末記号ではなく変数として認識されていました。

BashやZshではクォートなしでも問題なく動作しますが、Fish Shellの変数展開ルールはより厳格であり、この違いが互換性問題を引き起こしていました。

技術的な変更

lib/kamal/commands/base.rblib/kamal/commands/proxy.rb において、--filter オプションの値をシングルクォートで囲む変更が加えられました。

変更前:

def container_id_for(container_name:, only_running: false)
  docker :container, :ls, *("--all" unless only_running), "--filter", "name=^#{container_name}$", "--quiet"
end

変更後:

def container_id_for(container_name:, only_running: false)
  docker :container, :ls, *("--all" unless only_running), "--filter", "'name=^#{container_name}$'", "--quiet"
end

同様の修正が lib/kamal/commands/proxy.rbinfo メソッドにも適用されています:

def info
  docker :ps, "--filter", "'name=^#{container_name}$'"
end

生成されるコマンドは docker container ls --all --filter 'name=^app-web-latest$' --quiet のようになり、シングルクォートによって正規表現全体が1つの文字列として扱われます。

テストファイル群(test/cli/app_test.rbtest/cli/main_test.rbtest/cli/proxy_test.rbtest/commands/app_test.rbtest/commands/proxy_test.rb)でも、期待されるコマンド文字列がクォート付きに更新されています。

設計判断

シングルクォートによるエスケープ という最小限の変更が採用されました。

Dockerコマンド自体は引用符なしの形式とクォート付きの形式の両方を受け入れるため、この変更はBashやZshなどの既存環境との互換性を維持しながら、Fish Shell環境での動作を保証します。ダブルクォートではなくシングルクォートが選ばれているのは、変数展開を完全に防ぐためです。

フィルタ値全体をクォートで囲むことで、シェルの種類に依存しない一貫した動作を実現しています。この判断は、Kamalがサポートする環境の多様性を考慮した堅実な選択といえます。

まとめ

本PRは、Dockerコマンドのフィルタ名をシングルクォートで囲むことで、Fish Shell環境での実行エラーを解消しました。最小限のコード変更で複数のシェル環境での互換性を確保し、Kamalの環境依存性を低減させています。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→各セクション(各論)→まとめ(結論)の3部構成が明確に適用されています。背景、技術的変更、設計判断といった必須・任意要素がすべて含まれており、理想的な構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```ruby:path/to/file.rb)およびGitHubのIssue/PRへのリンク記法([#123](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

Kamal、Docker、各種シェルの挙動に関する知識を前提としており、専門知識を持つエンジニアという対象読者に適合した内容です。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落はトピックセンテンスで始まり、1段落1トピックの原則が守られています。段落の長さも適切で、非常に高い可読性を確保しています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されているコード変更(`lib/kamal/commands/base.rb`, `lib/kamal/commands/proxy.rb`)は、提供されたDiff情報と完全に一致しています。テストファイルへの言及も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「変数展開」「正規表現」「シングルクォート」など、使用されている技術用語は文脈に適しており、正確です。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

Fish Shellにおける`$`の解釈や、シングルクォートによる変数展開の防止といった技術的な説明は正確かつ論理的です。

事実の突合 ⚠ WARNING

PR情報による主張の裏付け(ハルシネーション検出)

「BashやZshではクォートなしでも問題なく動作しますが」という記述はPR情報に明記されていません。技術的に自明な内容で文脈を補完するものですが、厳密にはPR外の情報に基づいています。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#1732)およびIssue番号(#1691)は正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルはPRの主題「Dockerコマンドのフィルタ名をクォートする」という変更の背景(Fish Shellでのエラー修正)を的確に表現しており、PR内容と完全に一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事には、バージョンのサポート状況やリリース日程といった、PR情報に基づかない外部知識は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「発生していました」といった過去形の表現が使われており、既存の問題を修正したPRの内容と時間表現が一致しています。