日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.2-RELEASE-K, 8.0-RELEASE-K は、プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.2-RELEASE-K, 8.0-RELEASE-K は、全翻訳済み)
6.4-STABLE-K, 7.2-STABLE-K, 8.0-STABLE-K は現在、 作成中で日々更新されています。 最新の snapshots を元に作成しています。
PATCH(1) PATCH(1)
名称
patch - diff ファイルをオリジナルのファイルに適用する
書式
patch [options] [origfile [patchfile]] [+ [options] [origfile]]...
ですが、たいていは以下のようにします。
patch <patchfile
解説
patch は、 diff プログラムによって生成された 4 つの形式の差分情報を含む
パッチファイルを受け付け、オリジナルファイルにその差分を当てて、パッ チ
済みのバージョンを生成します。
デフォルト動作では、オリジナルは ".orig" の拡張子 (長いファイル名を扱え
ないシステムでは "~") を付けてバックアップとして残した上で、オリジナ ル
ファ イルはパッチ済みのバージョンに置き換えられます。オリジナルをバック
アップする拡張子はオプション -b (--suffix), -B (--prefix) あるい は -V
(--version-control) によって、あるいは環境変数 SIMPLE_BACKUP_SUFFIX に
よっても変更できます。環境変数による指定はオプション指定によって上書 き
されます。
バックアップファイルが既に存在していた場合、 patch は新しいバックアップ
ファイル名として、ファイル名本体の中で最初に出てくる英小文字の部分を 大
文 字に替えたものを使います。英小文字の部分がなかった場合は、ファイル名
の最初の 1 文字削除したものとし、既存のバックアップファイル名と合致しな
くなるまでこれを繰り返します。
ファイルの出力先は -o (--output) で指定することができますが、もしそこに
既に同じファイル名のファイルが存在していたら、まずバックアップが作ら れ
ます。
patchfile が指定されない場合やハイフンである場合、パッチは標準入力から
読み込まれます。 -i 引数が指定された場合、標準入力の代りに、これに続 く
ファイル名が使用されます。 -i ディレクティブは 1 度のみ使用可能です。
patch が最初に行う作業は、差分情報がどんな形式か判別することです。これ
は、オプション -c (--context), -e (--ed), -n (--normal), -u (--unified)
に よっ て 形式を指定することもできます。 context diff (old-style, new
style, unified) および normal diff は patch 自身によりパッチが当てら れ
ます。 ed diff だった場合は、パイプを通して単にパッチファイルをエディタ
ed に入力するだけです。
patch は、差分情報の前に含まれるゴミをスキップし、差分を適用し、そし て
後 に含まれるゴミをスキップしようとします。ですから差分情報が入った記事
やメッセージなどをそのまま patch に与えても、うまく動作するはずです。差
分 全体が一定量だけインデントされていても、そのことを考慮のうえ処理され
ます。
context diff の場合、そして normal diff の場合もいくらかあてはまりま す
が、 patch はパッチに書かれた行番号が正しくない場合にそれを検知し、各
hunk (パッチの各々の単位)を適用する正しい場所を見つけようと試みます。ま
ず hunk に書かれた行番号に対し、前回 hunk を適用した際に用いたオフセッ
トを加算あるいは減算します。それが正しい場所でなければ、 patch は一定の
行 数だけその前後を走査し、hunk のコンテキスト(context)にマッチする行を
探します。一番最初は、 patch はコンテキスト中の全ての行が一致する場所を
探 します。一致する場所が見つからない場合、パッチが context diff 形式で
あり、しかも最大曖昧度(maximum fuzz factor)が 1 以上に設定され て い れ
ば、 コンテキストの最初と最後の行を無視して再度走査を行います。それでも
見つからない場合、最大曖昧度が 2 以上なら、コンテキストの最初と最後の 2
行 を 無 視 して再度走査します。 (デフォルトの最大曖昧度は 2 です) もし
patch がパッチを当てる場所を見つけられなかった場合、その部分の差分情 報
を リジェクトファイルに出力します。リジェクトファイルは、通常、出力ファ
イルに ".rej" の拡張子 (長いファイル名を扱えないシステムでは "#") を 付
けたものになります。 (注意: 入力パッチが context diff であっても normal
diff であっても、リジェクト部分は context diff 形式で出力されます。入力
が normal diff の場合、コンテキストの多くは単なる null になります。) こ
のリジェクトファイルに出力される時の差分情報に付けられている行番号 は、
元 の パッ チファイルにあるものと違ったものになっている可能性もあります
が、元のものよりは場所的により近い位置になっていると思われる行番号に な
ります。
パッチの各 hunk が処理される毎に、そのパッチ処理が成功した(succeeded)の
か失敗した(failed)のかの別と、 patch が推定したパッチ適用行位置(新し い
ファ イルにおける行番号) が報告されます。この位置が差分中に示された行番
号と異なる場合、そのズレ(オフセット)も報告されます。 hunk のひとつだ け
が 大きなオフセットで適用された場合、それは誤った位置に適用されたことを
意味する「かも」しれません。またパッチ適用に際して曖昧度(fuzz factor)が
用 いられた場合もその旨報告されます。この場合は少し疑ってみるべきでしょ
う。
もし、オリジナルファイルがコマンドラインで指定されなかった場合、 patch
は、 エディットすべきファイル名を、差分情報の前に付加されているゴミの中
から見つけようとします。 context diff のヘッダの場合、 ファ イ ル 名 は
"***" もしくは "---" で始まる行から探し、既存ファイルに一致する最も短い
名前が用いられます。 context diffには上のような行が含まれますが、 も し
ヘッダに "Index:" いう行があったら patch はここから得たファイル名を使う
ことを試みます。 context diff ヘッダは Index 行に優先して用いられます。
も しファイル名を見つけることができなかった場合、パッチすべきファイル名
を入力するよう求めます。
もしオリジナルファイルが見つからないかリードオンリーであるけ れ ど も、
SCCS か RCS ファイルが存在する場合、 patch はそのファイルのゲットもしく
はチェックアウトを試みます。
加えて、もし差分の前のゴミの中に "Prereq: " という行が含まれていれ ば、
patch はその行に必要条件 (通常はバージョン番号) が書いてあるものとみな
して最初の word を取りだし、オリジナルファイルの中に同じ word がある か
どうかを調べます。もしその word が発見できなければ、 patch は処理を実行
してよいか、確認を求めるようになります。
結局のところ、ニュースリーダを使っているときに、パッチを含んだ記事に 対
して
| patch -d /usr/src/local/blurfl
のように指示してやれば、blurfl ディレクトリにあるファイルに記事から直接
パッチをあてることができる、ということです。
パッチファイルに、1 つ以上のパッチが含まれていた場合、 patch は、各々が
別 々のパッチファイルであるものと思って処理を実行します。この場合、パッ
チを当てるべきオリジナルファイルは、今まで説明したように、各々の差分 情
報 の中から抽出でき、また、各差分記述の前にあるゴミの部分を調べることで
ファイル名やリビジョンレベル等の重要事項が得られる、と仮定していま す。
この他に、'+' で繋げてファイル名を並べることで、 2 番目以降のファイル名
を指定することもできます (ただし、この場合でも、パッチ当てた後の新し い
ファイル名を指定することはできません)。
patch には次のようなオプションがあります:
-b suff, --suffix=suff
".orig" や "~" の代わりに suff がバックアップファイルの拡張子とし
て解釈されるようにします。
-B pref, --prefix=pref
pref が、バックアップファイル名の前に付けるプレフィックスとして 解
釈されるようにします。この指定を行うと -b の指定は無視されます。
-c, --context
パッチファイルを context diff 形式として解釈します。
-C, --check
どういう処理が行われるか確認します。しかし実行はしません。
-d dir, --directory=dir
dir をディレクトリとみなし、処理の前にそのディレクトリに移動しま
す。
-D sym, --ifdef=sym
"#ifdef...#endif" 構造を用いて差分を示します。差分情報を切り替える
シンボルとして sym が用いられます。
-e, --ed
パッチファイルを ed スクリプト形式として解釈します。
-E, --remove-empty-files
パッチ適用後、空のファイルは削除するようにします。
-f, --force
ユー ザは処理内容を正確に把握しているものとみなし、 patch は何も尋
ねず、次のように仮定して処理を進めます。すなわち、パッチすべきオリ
ジ ナ ル ファ イル見つけることができなかった場合はスキップします。
``Prereq:'' のバージョンが正しくなくても、パッチを実行します。パッ
チ済みと思われても、リバースパッチではないと仮定します。なお、この
オプションは、 patch が表示するメッセージを抑制しません。メッ セー
ジを止めるには -s を使います。
-t, --batch
-f と同様ですが、次のように仮定します。パッチすべきオリジナルファ
イルを見つけることができなかった場合はスキップします( -f と同じ)。
``Prereq:'' のバージョンが正しくない場合は、スキップします。パッチ
済みと思われる場合は、リバースパッチと仮定します。
-F number, --fuzz=number
最大曖昧度を設定します。このオプションは context diff 形式にのみ適
用され、 hunk の適用位置を探す際に最大 number 行だけ無視します。こ
の値を大きくするとパッチが間違ってあたる可能性も増えることに注意し
て下さい。デフォルト値は 2 であり、 context の行数(通常は 3)より大
きい値にはしません。
-i patchfile
標準入力の代りに patchfile を適用するよう、 patch に指示します。
-I, --index-first
patch に、``Index:'' 行を context diff のヘッダより優先して扱わ せ
ま す。 PATCH_INDEX_FIRST 環境変数を設定すれば同じ効果が得られま
す。
-l, --ignore-whitespace
パターンマッチの条件を緩くし、タブおよび空白に関する違いは無視しま
す。パターン中の連続する任意個の空白は、入力ファイル中の連続する任
意個の空白にマッチします。しかし普通の文字は正確に合致しなければな
り ません。 context の各行に対して入力ファイル中にマッチする行がな
ければなりません。
-n, --normal
パッチファイルを normal diff 形式として解釈します。
-N, --forward
リバースパッチ、もしくはすでにパッチ済みであると思われるパッチをス
キップします。 -R も参照して下さい。
-o file, --output=file
file を出力ファイル名と解釈します。
-p[number], --strip[=number]
パ ス名の除去カウント(strip count)を設定します。パッチ作成者と異な
るディレクトリにファイルを置いている場合、パッチファイル中のパス名
をどのように解釈するか、を指示します。除去カウントは、パス名の先頭
から何個のスラッシュを除去するか、を指定するものです(その間にあ る
ディ レクトリ名も取り除かれます)。例えば、パッチファイル中のファイ
ル名が
/u/howard/src/blurfl/blurfl.c
であった場合、 -p あるいは -p0 オプションを指定すると、パス名は 全
く修正されません。 -p1 を指定すると、最初のスラッシュがない
u/howard/src/blurfl/blurfl.c
となり、 -p4 を指定すると
blurfl/blurfl.c
、そして -p を全く指定しないと "blurfl.c" となります。ただし、その
前のパス(u/howard/src/blurfl)が相対パスとして存在する場合は別 で、
そ の 場合、パス名全体は無修正のままです。最後に、こうして得られた
ファイルを、カレントディレクトリあるいは -d オプションで指定 し た
ディレクトリ内で探します。
-r file, --reject-file=file
file をリジェクトファイル名として解釈します。
-R, --reverse
こ のパッチが新旧 2 つのファイルを入れ換えて作成したものであること
を patch に知らせます。 (ええ、たまにはそういうことも起きると 思っ
ています。人間ってそういうものです。) patch は各 hunk を適用する前
に新旧を入れ換えます。リジェクトファイルは入れ換え後の形式で出力さ
れます。 -R オプションは ed スクリプト形式の差分には使えません。逆
操作の手順をつくり出すには情報が不足しているからです。
もしパッチ中の最初の hunk が失敗すれば、 patch はそれを リ バー ス
パッ チ にしてうまく適用できるかどうか試します。もしうまくいけば、
-R オプションをセットしてパッチを当てますか、と尋ねられます。そ う
しないと答えれば、パッチは通常通り適用されていきます。 (注: パッチ
が normal diff 形式で、しかも最初のコマンドが追加 (つまり本来は 削
除) であると、この方法ではリバースパッチを検出できません。空のコン
テキストはどこにでもマッチするので、追加操作は常に成功してしまうか
らです。幸い、発見的には、パッチは行を削除するよりも追加あるいは修
正するものがほとんどであるため、 normal diff 形式のリバースパッ チ
は削除から始まって失敗におわることがほとんどです。)
-s, --silent, --quiet
エラーの場合以外、静かに処理を行います。
-S, --skip
パッチファイル中のこのパッチを無視し、次のパッチから処理を続けるよ
うに指示します。例えば
patch -S + -S + <patchfile
と指定すると、3 つのパッチのうち、1 番目と 2 番目のパッチを無視 し
ます。
-u, --unified
パッチファイルを unified diff 形式 (unidiff) として解釈します。
-v, --version
patch コマンドのリビジョンヘッダとパッチレベルを表示します。
-V method, --version-control=method
バックアップファイル名の作成方法として method を用います。作成され
るバックアップのタイプは環境変数 VERSION_CONTROL でも指定できま す
が、 こ のオプションはそれに優先します。 -B はこのオプションに優先
し、バックアップファイルを作る際に常にプレフィックスが用いられるよ
う にします。環境変数 VERSION_CONTROL および -V オプションの引数の
指定は、GNU Emacs の `version-control' 変数と同様です。より分か り
や すい同義語も認識されます。有効な値は以下の通り(一意に短縮するの
も可):
`t' または `numbered'
常に数字を付けたバックアップファイルを作ります。
`nil' または `existing'
すでに数字付きバックアップファイルが存在する場合は、数字 付
き バックアップを行い、それ以外の場合は、単純なバックアップ
を行います。これがデフォルトです。
`never' または `simple'
常に単純なバックアップを行います。
-x number, --debug=number
内部のデバッグフラグに値を設定します。 patch コマンドにパッチを あ
てる人だけに関係するものです。
作者
Larry Wall <lwall@netlabs.com>
および多くの貢献者の方々。
環境変数
TMPDIR テンポラリファイルを置くディレクトリ。デフォルトでは /tmp
SIMPLE_BACKUP_SUFFIX
バックアップファイルに付ける拡張子を指定します。デフォルトでは、
".orig" もしくは "~"。
VERSION_CONTROL
数字付きバックアップファイルが作成される際に選択します。
関連ファイル
$TMPDIR/patch*
関連項目
diff(1)
パッチ作成者への注意
パッチを作って送付しようとする際に留意すべき点がいくつかあります。第 1
に、patchlevel.h というファイルを管理することで皆は大変幸せになれます。
作成したパッチファイルの最初の差分はこの patchlevel.h にパッチをあ て、
パッチレベルをインクリメントします。パッチの中に Prereq: 行を入れておけ
ば、順番通りにパッチを適用しない限り警告が出ます。第 2 に、context diff
ヘッ ダ か Index: 行で正しくファイル名を指定していることを確認して下さ
い。サブディレクトリにあるファイルにパッチをあてようとする場合は、必 要
に応じて -p オプションを指定するよう、ユーザに伝えて下さい。第 3 に、空
のファイルと新規ファイルを比較する差分を送付することで、新しいファイ ル
を 生成することができます。これは、ターゲットディレクトリにその新ファイ
ルがまだ存在しない場合にのみ有効です。第 4 に、リバースパッチを送付しな
い ように気を付けて下さい。そのパッチは適用済なのかと皆が混乱します。第
5 に、例えば 582 個の差分をたったひとつのファイルに突っ込んでハイサヨナ
ラ とすることもできることはできますが、何か発狂しそうになったときに備え
て、関係あるパッチをいくつかの独立したファイルにまとめあげるほうがお そ
らく賢明でしょう。
診断
ここに列挙しきれないほどたくさんありますが、一般に patch がパッチファイ
ルを解釈できないことを示しています。
メッセージ "Hmm..." は、パッチファイル中に処理できないテキストが存在 し
ていること、そして patch はそのテキスト中にパッチがあるかどうか、もし存
在すればどういう形式のパッチであるかを推測しようとしていることを示し て
います。
ひ と つ でもリジェクトファイルが作成されれば、 patch は 0 でない終了ス
テータスで終了します。いくつものパッチを繰り返し適用する場合は、この 終
了 ステータスをチェックし、パッチが部分的にしか適用されていないファイル
に対してさらなるパッチをあてないようにすべきです。
警告
patch は ed スクリプト形式では行番号のズレを示せませ ん。 ま た normal
diff 形 式 で も、 行 番 号の誤りを指摘できるのは "change" コマンドや
"delete" コマンドが現れる場合だけです。 context diff 形式で曖昧度 3 を
指 定した場合も同様の問題があります。適切な対話インタフェースが追加され
るまでは、こういう場合は context diff を見比べて修正が意味的に正しい か
ど うか確認すべきでしょう。もちろん、エラーなくコンパイルできれば、パッ
チはうまく適用されたという小さなサインにはなりますが、必ずしもいつも そ
うだというわけではありません。
たとえ多くの類推を行わなくてはならない場合でも、 patch は通常、正しい結
果を生成します。しかし、結果が正しいと保証できるのは、パッチを作成し た
の と 正 確に同じバージョンのファイルに対してパッチを適用した場合だけで
す。
バグ
多めの deviant オフセットと入れ換えコードにより、部分的なマッチングに関
して更に賢くできますが、そのためにはパスを追加する必要がありそうです。
コー ド が複製されている場合(例えば #ifdef OLDCODE ... #else ... #endif
によって)、 patch は両者にパッチをあてることができません。そしてそこ で
パッ チコマンドがうまくいった場合、そのパッチはおそらく誤って適用されて
おり、おまけに「成功しました」と報告してきます。
既に適用済のパッチをあてると、 patch はそれをリバースパッチと考え、適用
し たパッチを外すかどうか尋ねてきます。これも特徴の一つと解釈可能でしょ
う。
LOCAL PATCH(1)