PKG_ADD(1)

名称
pkg_add - ソフトウェア配布 package をインストールするプログラム

書式
pkg_add [-vInfrRMS] [-t template] [-p prefix] pkg-name [pkg-name ...]

解説
pkg_add コマンドは、 pkg_create(1) コマンドにより作成された package (訳注: FreeBSD の package system におけるパッケージを指す場合にこう表記します) を展開するのに用いられます。

警告
pkg_add コマンドは package ファイルに含まれるスクリプトやプログラムを 実行することがあるので、あなたのシステムは、危険な配布ファイルを 作る極悪人からの “トロイの木馬” や他の巧妙な攻撃などを受ける 可能性があります。

package ファイルを提供する人物の能力と身元を確認するとよいでしょう。 より進んだ安全のためには、package を展開するのに -M フラグを用い、その内容と、スクリプトがシステムに害をおよぼさないかを 確認します。 +INSTALL, +POST-INSTALL, +DEINSTALL, +REQUIRE, +POST-INSTALL, +REQUIRE, +MTREE_DIRS の各ファイルには 特に注意を払い、+CONTENTS ファイルの @cwd, @mode (setuid をチェック), @dirrm, @exec, @unexec ディレクティブを調べてください。 package ファイルを調べるのには pkg_info(1) コマンドも使えます。

オプション
以下のコマンドラインオプションが提供されています:

pkg-name [pkg-name ...]
    指定された package がインストールされます。 - という名前が指定されると、 pkg_add は stdin から読み込みます。 package がカレントディレクトリに見つからないと、 pkg_add は PKG_PATH で指定された各ディレクトリを探します。

-v  饒舌な出力に切り替えます。

-I  package にインストール用スクリプト (pre-install または post-install) が存在しても、それを実行しません。

-n  実際にはインストールを行わず、インストールした場合に実行されるであろう ステップを表示します。

-R  package のインストール結果を記録しません。 このオプションは、後でアンインストールすることを不可能にするため、 自分が何をしているかを理解している人のみ使ってください。

-r  リモートフェッチ機能を使用します。 適切なオブジェクト形式とリリースを決定してから、 package を取得してインストールします。

-f  あらかじめ必要な package がインストールされていなかったり、 requirements スクリプトが失敗した場合にも強制的にインストールします。 これは pkg_add が見つからない必要な package を探して自動的にインストールすることを 止めるわけではなく、見つからない場合でも中断しないようにします。

-p prefix
    package からファイルを展開するディレクトリの前に prefix を付けます。 package がデフォルトディレクトリを保持している場合には、 このオプションで変更できます。 pkg_add はディレクトリ設定が相対的に行われているか、絶対的に行われているか を知る術がないので、最初の @cwd ディレクティブのみが変更されることに注意してください。 複数回のディレクトリ変更が行われることはまれですが、 実際にあった場合、すべてのディレクトリ変更を制御したくなる でしょう。この場合、 MASTER モード、 SLAVE モードの使用を検討してみてください (オプション -M と -S を参照)。

-t template
    “作業領域” を作成する際に、 mktemp(3) への入力として template を用います。 これはデフォルトでは /var/tmp/instmp.XXXXXX という文字列ですが、 /var/tmp ディレクトリの容量が制限されているような状況では 変更する必要があるかもしれません。 mktemp(3) が一意の ID を用いるために必要な `X' の文字をいくつか残しておく ことを忘れないでください。

    作業領域 template を package ファイルがインストールされるディレクトリと同じディスク パーティションに設定することによって、パフォーマンスを高めることが 可能です (大抵は /usr )。

-M  MASTER モードで実行します。これは pkg_add のとても特殊な実行モードであり、 SLAVE モードと共に実行しなければなりません。 このモードで実行されると、 pkg_add は一時的な作業領域 ( -t オプションを参照) へ package を展開する以上のことはせず、 現在の作業領域ディレクトリ名を頭に付加した packing list を標準出力に 出力します(標準出力は sed(1) のようなプログラムにフィルタされているかもしれません)。 SLAVE モードと共に用いると、中身を処理する前に package 構造に 大きな変更を加えることが可能になります。

-S  SLAVE モードで実行します。これは pkg_add のとても特殊な実行モードであり、 MASTER モードと共に実行しなければなりません。 このモードで実行されると、 pkg_add は package の内容がすでに作業領域に展開され、その場所が 標準入力から文字列として入力されることを想定します。 完全な packing list も stdin から読み込まれ、その後中身が 通常どおり処理されます。

一つ以上の pkg-name 引数を指定することが可能で、それらは package を含むファイル名 (通常 拡張子 “.tgz” で終わります) か、ftp サイトにあるファイルを 示す URL のどちらかになります。 したがって、anonymous ftp から直接ファイルを展開することが 可能です (例えば pkg_add ftp://ftp.FreeBSD.org/pub/FreeBSD/packages/shells/bash-1.14.4.tgz) 。 注意: もし上記のような転送で用いる ftp で passive mode を利用したいなら、環境変数 FTP_PASSIVE_MODE に何らかの値を設定する必要があります。 そうでなければ、より一般的な ACTIVE モードが利用されます。 もしうまく動作していることがわかっているサイトから package を 得ようとして pkg_add が常に失敗する場合、あなたが passive mode の ftp を使う必要のあるファイアウォールの中にいるのが原因である場合が あります。

技術詳細
pkg_add はきわめて単純です。各 package の "packing list" を 特別な作業ディレクトリに展開し、 中身を解析し、内容を完全に展開するために 以下の手順を実行します:

1.  package がすでにインストールされている、と記録されているかどうかを チェックします。もしそうならインストールを中断します。

2.  @pkgdep ディレクティブ ( pkg_create(1) を参照) による package のすべての依存関係をチェックし、各々が存在するかどうかを 確認します。もし存在しなければ、足りない package を見つけて自動的に インストールしようとします。もし見つからなければ、 インストールを中断します。

3.  package がどのようにシステムに追加されるかを制御する @option ディレクティブを検索します。このマニュアルページを書いている時点では、 実装されているオプションは @option extract-in-place のみであり、これは /tmp 内の作業領域を経由しないで、 package を最終的なディレクトリに直接展開するようにします。

4.  @option extract-in-place が指定されていれば、package は最終的な場所に直接展開され、 そうでなければ作業領域内に展開されます。

5.  package が require ファイル ( pkg_create(1) を参照) を含んでいる場合、そのファイルを以下の引数を付けて実行します:
    pkg-name INSTALL

    ここで pkg-name は問題としている package の名前であり、 INSTALL キーワードはインストールの requirements チェックであることを 示しています (これは複数の機能を提供するひとつのスクリプトを 用いようとする場合に有用です)。

6.  package に pre-install スクリプトが存在する場合、以下の引数を付けて実行されます:
    script pkg-name PRE-INSTALL

    ここで pkg-name は対象の package 名であり、 PRE-INSTALL はこれがインストール前のフェーズであることを示すキーワードです。

    注: ( -i および -I のフラグを pkg_create(1) に使用することにより) package 作成時に pre-install と post-install のスクリプトが別々に与えられる場合には、 PRE-INSTALL キーワードは登場しません。

7.  @option extract-in-place が指定されていない場合、packing list ( +CONTENTS ファイル) が作業領域から最終的な場所に ファイルを移動 (必要ならコピー) するために参照されます。

8.  package が mtreefile ファイル ( pkg_create(1) を参照) を含む場合、mtree が以下の引数を付けて実行されます:
    mtree -u -f mtreefile -d -e -p prefix

    ここで prefix は -p フラグが指定されていればその prefix、 -p フラグが指定されていない場合にはこの package の最初の @cwd ディレクティブのディレクトリ名が prefix になります。

9.  package に post-install スクリプトが含まれる場合、
    script pkg-name POST-INSTALL

    として実行されます。 ここで pkg-name は対象の package 名であり、 POST-INSTALL はこれがインストール後のフェーズであることを示すキーワードです。

    注: ( -i および -I のフラグを pkg_create(1) に使用することにより) package 作成時に pre-install と post-install のスクリプトが別々に与えられる場合には、 POST-INSTALL キーワードは登場しません。

    POST-INSTALL および PRE-INSTALL のキーワードを渡す背景には、 “インストールの前とインストール後の両方” の手続きをこなす一つの install スクリプトを用いることを可能にすることがあります。 しかしながら、メンテナンスの観点からは、機能を分離する方が有利かつ容易です。

10. インストールが終了すると、後で pkg_delete(1) で使うために packing list、 deinstall スクリプト、 description、 display の各ファイルが /var/db/pkg/<pkg-name> にコピーされます。 package の依存関係は、他の package の /var/db/pkg/<other-pkg>/+REQUIRED_BY ファイル (PKG_DBDIR 環境変数が設定してある場合、上記の /var/db/pkg/ が置き換えられます) に記録されます。

11. 最後に、作業領域が削除されプログラムは終了します。

すべてのスクリプトは環境変数 PKG_PREFIX にインストール時の prefix ( 前述の -p オプションを参照) が設定された状態で実行されます。 このことにより、package の作者は pkg_add の -p フラグにより package がインストールされるディレクトリが 変更されても、きちんとふるまうスクリプトを書くことが可能になります。

環境変数
PKG_PATH の値は、指定された package が見つからない時に用いられます。 環境変数はコロンで区切られた一連のエントリです。 各エントリはディレクトリ名からなります。 カレントディレクトリは空欄のディレクトリ名で暗黙のうちに指定されるか、 一つのピリオドで明示的に指定します。

環境変数 PKG_DBDIR は、インストールされた package についてのデータベースの位置を指定します。

pkg_add が作業領域の生成を試みる作業用ディレクトリの名前は、環境変数 PKG_TMPDIR と TMPDIR とから (この順で) 取られます。 これらの変数が存在しないか、指定されたディレクトリに十分な空き容量が ない場合、 pkg_add は、 /var/tmp, /tmp, /usr/tmp のうちで、十分な空き容量を持つ最初のディレクトリを使います。

環境変数 PACKAGEROOT は、 pkg_add が取得を行う代替位置を指定します。 取得に使用する URL は、本環境変数と、 -r オプション使用時に pkg_add が自動的にディレクトリを決定する論理とで、構築されます。 設定例は "ftp://ftp3.FreeBSD.org" です。

環境変数 PACKAGESITE は、 pkg_add が取得を行う代替位置を指定します。 この変数を使用すると、 -r オプション使用時に pkg_add が自動的にディレクトリを決定する論理が破壊されます。 よって、これはリモートパッケージファイルへの完全な URL であることが必要です。

関連ファイル
/var/tmp
    環境変数 PKG_TMPDIR と TMPDIR のどちらも適切なディレクトリを指定しない場合に、作業領域を作成するため に用いる作業用ディレクトリ。
/tmp
    /var/tmp が存在しないか、十分な空き容量を持たない場合、その次に選ばれる ディレクトリ。
/usr/tmp
    /var/tmp と /tmp のどちらも作業領域を作成するには適切でない場合、最後に選ばれる ディレクトリ。
/var/db/pkg
    インストールされた package についてのデータベースのデフォルトの位置。

関連項目
pkg_create(1), pkg_delete(1), pkg_info(1), pkg_update(1), pkg_version(1), mktemp(3), sysconf(3), mtree(8)

作者
Jordan Hubbard

協力者
John Kohl <jtk@rational.com>

バグ
配布物のファイル間のハードリンクは、 (1) 作業領域が、ファイルへのすべてのリンクの最終的な ディレクトリと同じファイルシステムの場合もしくは、 (2) ファイルへのすべてのリンクが contents ファイル内で @cwd ディレクティブで括られている場合にのみ保存されます。 さらに その上、リンク名は単一の tar コマンド ( sysconf(_SC_ARG_MAX) により返される値に依存する実行時の引数の長さの制限により、複数の 実行には分割できません) で展開されなければなりません。

バグは他にもあるはずです。