curl|sh、irm|iex、npx、GitHub直接取得——CLIツールのインストール方法をすべて比較する
1. はじめに
CLIツールをインストールするとき、公式サイトには複数のコマンドが並んでいることが多いです。「`curl -fsSL https://example.com/install.sh | sh`」という行の下に、Windows向けの「`irm https://example.com/install.ps1 | iex`」が並び、さらに「`npx create-something`」や、GitHubのREADMEに書かれた「`git clone`」の手順が追加されている——という光景は珍しくありません。
これらは見た目こそ似ていますが、内部の処理、検証の有無、オフライン対応のしやすさ、OSごとの前提はまったく異なります。インストール方法を選ぶ基準を持っておくと、業務でツールを導入する際の判断や、セキュリティレビューでの説明がしやすくなります。
curl|sh、irm|iex、npx、GitHubからの直接取得、そしてOS標準のパッケージマネージャーという主要な方法を取り上げ、それぞれの処理の仕組み、オンライン/オフラインでの違い、Windows・Linux・macOSでの扱いの差を順に見ていきます。
2. なぜインストール方法は一つに統一されないのか
2-1. OSごとに前提となるシェルが違う
LinuxとmacOSはPOSIX系のシェル(bash・zshなど)を共有しているため、curl|shの形式は両方で同じように動きます。一方Windowsには長らくcmd.exeしかなく、curlコマンド自体も標準搭載されていませんでした(Windows 10の1803以降にcurl.exeが同梱されるようになった経緯があります)。PowerShellが標準シェルとして定着したことで、irm|iexという同型のパターンがWindows側にも採用されるようになりました。OSの数だけシェルの文化があり、それぞれの事情に合わせる形でインストールパターンが分岐してきました。
2-2. 言語・エコシステムごとに配布の作法が異なる
npm、pip、cargo、goなど言語ごとのパッケージマネージャーは、それぞれ独自の配布ルールを持っています。npmはレジストリ中心、Goはモジュールプロキシとチェックサムデータベース中心、Rustのcargoはcrates.ioを既定としつつ`--git`オプションでの直接取得を許しています。さらにGitHub自体がバイナリ配布の場(Releases機能)として使われることも増えており、特定の言語エコシステムに乗らない単体バイナリ(Goやrustで書かれたCLIツールなど)は、curl|shやReleasesページからの直接取得に頼りがちになります。
OSの違いと言語エコシステムの違いという2つの軸が組み合わさることで、同じツールでも複数のインストール手順が並立する状況が生まれています。
3. スクリプト直接実行型——curl|sh と irm|iex の仕組み
3-1. curl | sh が行っていること
curl|sh形式のインストーラーは、実行環境のOSとCPUアーキテクチャを判定し、対応するバイナリのURLを選び、ダウンロードして展開し、PATH上の実行可能な場所に配置する、という一連の処理をシェルスクリプト1本にまとめたものです。Rustのインストーラーrustupの公式コマンドは次のように、プロトコルとTLSバージョンを固定するオプションを付けています。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh通信路の安全性を最低限確保しようとする工夫ですが、スクリプトの内容そのものに対する署名やチェックサムの検証はこの一行には含まれていません。
3-2. Windows の irm | iex は何が違うのか
PowerShellの`irm`(Invoke-RestMethod)はcurlに相当するダウンロード機能、`iex`(Invoke-Expression)は取得した文字列をコードとして実行する機能を持ちます。
irm https://example.com/installer.ps1 | iexこの一行は構造的にcurl|shと同一であり、Windows環境でのスクリプト直接実行型インストールの標準的な書き方になっています。winget自体のブートストラップやScoopのインストール手順でも、このパターンが採用されています。
3-3. 共通するリスクと向き合い方
curl|shとirm|iexには共通する弱点があります。通信が途中で切れた場合にスクリプトが半分だけ実行されてしまう可能性、配布元のサーバーが侵害された場合に任意のコードがユーザー権限で実行されてしまうサプライチェーン上のリスク、そしてチェックサムや署名による検証が標準では行われない点です。サーバー側でcurlのアクセスを検出し、ブラウザでアクセスした場合とは異なる内容を返す、という理論上の手法も指摘されています。実際の被害報告は限定的ですが、起きてからでは取り返しがつかない種類のリスクでもあり、「何が実行されるか分からないまま実行する」という構造そのものが、レビューを難しくしています。
緩和策としては、スクリプトを一度ファイルに保存して内容を確認したうえで実行する方法があります。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > install.sh
cat install.sh
sh install.shCI/CDパイプラインのように再現性が重要な場面では、信頼できるバージョンのスクリプトを自分たちのリポジトリに固定して使う方法も有効です。

4. パッケージ実行型——npx はなぜ「インストール」ではないのか
4-1. npx の実行順序
npxはnpm 5.2.0以降に同梱されているコマンドです。`npx <パッケージ名>`を実行すると、まずローカルのnode_modulesにパッケージがあるかを確認します。見つからない場合はnpmレジストリから一時的にダウンロードし、実行可能ファイルをPATHに通して実行します。実行のたびにバージョンを固定したい場合は`npx package@1.2.3`のようにバージョンを明示できます。グローバルな永続インストールとしては残らないため、ツールを試しに使うだけの場面に向いています。

4-2. curl|sh との本質的な違い
curl|shは任意のシェルスクリプトを取得してそのまま実行する方式であるのに対し、npxはnpmレジストリに公開されたパッケージを取得して実行する方式です。レジストリを経由する分、パッケージ名・バージョン・配布元の履歴がnpmの管理下に残り、事後的な追跡が可能になる点が異なります。ただし、npmレジストリへの公開自体に高度な審査が必須というわけではないため、悪意あるパッケージが公開されるリスクは別の問題として残ります。
5. GitHubから直接取得する方法
5-1. git clone してビルドする
ソースコードをそのままcloneしてビルドする方法は、レジストリによる審査や配布の手間を経ないぶん最新のコードに触れられます。その一方で、ビルド環境の準備や依存関係の解決を利用者側で行う必要があります。OSSへのコントリビューションやプレリリース版の検証目的で使われることが多い方法です。
5-2. Releasesバイナリを手動で取得する
GitHubのReleases機能を使い、ビルド済みのバイナリを配布するプロジェクトも多くあります。利用者はブラウザやcurlでファイルを直接ダウンロードし、実行権限を付けて使います。手順は手作業になりますが、ダウンロードしたファイルをそのまま社内ミラーや別環境にコピーできるため、オフライン環境への配布という点では扱いやすい方法です。最新版の確認やアップデートを自動化したい場合は、GitHub Releasesを監視して自動取得する専用ツールを併用する例もあります。
5-3. 言語別の直接インストール
Go、Rust、Pythonなど言語ごとのパッケージマネージャーにも、レジストリを経由せずGitHubから直接取得する手段が用意されています。
`go install github.com/owner/repo@version`——Goのモジュールプロキシ経由で取得され、GOSUMDB(既定では`sum.golang.org`)によるチェックサム検証が標準で働きます。記録されているハッシュと一致しない場合はインストールが中断されるため、curl|shには存在しない検証の仕組みが言語のツールチェーンに組み込まれている点が特徴です。
`cargo install --git https://github.com/owner/repo`——crates.ioを経由せず直接ビルドします。Cargo.lockによって依存関係のバージョンは固定できますが、crates.io掲載パッケージのような中央側のキュレーションは経ません。
`pip install git+https://github.com/owner/repo`——PyPIを経由せずGitリポジトリから直接インストールします。未リリースの最新コードを試す場合に使われます。
いずれも、配布元のレジストリ審査を迂回するぶん、開発中のコードへ早くアクセスできる手段だと整理できます。
6. パッケージマネージャーという選択肢——OS別の違い
6-1. Linux:apt / dnf / pacman
Linuxディストリビューションには標準のパッケージマネージャーが組み込まれています。Debian系のapt、Fedora系のdnf、Arch系のpacmanなどが代表的で、パッケージは署名付きリポジトリで管理され、依存関係の解決やアップデートもシステムが一括して担います。ディストリビューションの審査を経るため安定性が高い一方、最新バージョンの反映には時間差が生じやすい傾向があります。
6-2. macOS:Homebrew
macOSにはApple公式の一次パッケージマネージャーは用意されておらず、Homebrewがコミュニティ標準として広く使われています。`brew install`で多くのCLIツールやライブラリを導入でき、フォーミュラ(パッケージ定義)はGitHub上で公開・レビューされる仕組みになっています。
6-3. Windows:winget / Scoop / Chocolatey
Windowsには複数の選択肢が並立しています。wingetはMicrosoft公式で、Windows 10(1809以降)・Windows 11に標準搭載されており、Microsoft Storeのアプリにもアクセスできます。Scoopはユーザー権限の範囲にインストールするポータブル指向で、システム全体への変更を避けたい場合に向いています。Chocolateyは2011年から続く老舗で、対応パッケージ数の多さと管理ツールの成熟度に強みがあります。Windowsが長らく統一的なパッケージマネージャーを持たなかった背景には、MSIインストーラーとアプリストアモデルが主流だった歴史があり、その間隙を埋める形で複数のツールが育ってきました。

7. オンライン前提の落とし穴とオフライン対応
7-1. すべての方法がオンラインを前提にしているわけではない
curl|sh、irm|iex、npxはいずれも実行のたびにインターネット接続を必要とします。スクリプトやパッケージを事前にダウンロードしておかない限り、オフライン環境やエアギャップされたネットワークでは動作しません。GitHub Releasesのバイナリ手動取得は、いったんファイルを取得してしまえば、その後はネットワークなしで何度でも配布できる点で扱いやすい方法です。
7-2. オフライン・エアギャップ環境での備え方
npmはインターネットに接続できる環境で依存関係をtar.gz化してエクスポートし、オフライン側にコピーする方法や、Verdaccioのようなプライベートレジストリをローカルに立てる方法が使われます。pipは`.whl`ファイルを直接配布するか、`pip install --no-index -f /path/to/wheels`のようにローカルディレクトリから依存関係を解決できます。cargoには依存クレートをまとめてローカルに保存する`cargo vendor`というコマンドがあり、オフラインビルドに対応しています。
共通する考え方は、オンライン側で取得したアーティファクトをオフライン側に転送し、ローカルのキャッシュやミラー経由でインストールする、という二段構成です。業務でエアギャップ環境を運用している場合、ツール選定の段階で「オフラインでの再現性」を基準に加えておくと、後からの構成変更を避けられます。
8. どの方法を選ぶか——判断基準と実践への橋渡し
8-1. 5つの判断軸
ここまで見てきた方法を選ぶ際は、次の5つの軸で整理すると判断しやすくなります。
検証可能性——チェックサムや署名による改ざん検知ができるか
権限——システム全体に影響するか、ユーザー権限の範囲に収まるか
再現性——同じバージョンを後から再現できるか(ロックファイルの有無)
オフライン対応——インターネット接続なしで再実行できるか
更新の容易さ——アップデートの確認・適用が自動化されているか

8-2. 実際の選び方
個人の検証用途で素早く試したいだけなら、公式が提供するcurl|shやirm|iexでも実用上は問題にならない場面が多くあります。結局のところ、どこまで検証可能性を重視するかは用途次第です。CI/CDパイプラインや本番環境の構成管理に組み込む場合は、検証可能性と再現性を優先し、パッケージマネージャーや言語標準のインストール手段(go installのチェックサム検証など)、あるいは自前のリポジトリに固定したスクリプトを使う方が安全な選択になります。オフライン環境が前提にある場合は、早い段階でGitHub Releasesのバイナリ配布やプライベートレジストリの構成を検討しておくと、後工程での手戻りを減らせます。
9. おわりに
CLIツールのインストール方法は、一見すると似たようなコマンドに見えますが、内部の処理、検証の仕組み、オフラインでの扱いやすさはそれぞれ異なります。普段使っているコマンドが何を行っているかを把握しておくことは、ツール導入時の判断やセキュリティレビューの場面で役立つはずです。次にインストールコマンドをコピーする前に、その一行が何をしているのかを少し確認してみると、選択の基準が一つ増えるかもしれません。
参考資料:
