パイプラインの一部としてパッチを適用するにはどうすればよいですか?つまり、標準入力をパッチする方法は何ですか?

パイプラインの一部としてパッチを適用するにはどうすればよいですか?つまり、標準入力をパッチする方法は何ですか?

mypatch.diffstdinに均一なdiffを適用し、結果をstdoutとして出力したいと思います。

これまで私は次のことを試しました。

patch -i mypatch.diff -o - -u originalfile

正常に適用しmypatch.diff、結果を標準出力として印刷します。ただし、標準入力を介さずに元のファイルを提供する必要がありますoriginalfile

次のようにしようとすると:

patch -i mypatch.diff -o - -u -

これによりパッチが拒否されます。

patching file -
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file -.rej

答え1

POSIXシェルの解決策は次のとおりです。

#!/bin/sh
patchstdin() (
    set -o errexit
    tmpdir="$(mktemp -d)"
    trap 'rm -rf -- "$tmpdir"' EXIT
    trap 'exit 1' HUP INT TERM
    cat >"$tmpdir/original"
    patch "$@" -o "$tmpdir/patched" "$tmpdir/original"
    cat "$tmpdir/patched"
)

yourcommandパッチが必要な出力を生成し、パッチされたanothercommand出力を受け取ると想定すると、次のように呼び出すことができます。

yourcommand | patchstdin -i patch.diff | anothercommand

POSIXの一部ではありませんmktemp。バラよりPOSIXにmktempコマンドがないのはなぜですか?より多くの情報とシェルスクリプトで一時ファイルを作成するには?POSIXシェル用のソリューションです。

答え2

GNUにはこのオプションがないようですpatch。 stdin forまたはstdout for(forは廃棄拒否として解釈されます)を-意味しますが、パッチするファイルは現在ディレクトリから呼び出されたファイルとして解釈されます。-i-o-r--

また、パッチするファイル名に応じてpatch関連ファイルまたはサフィックスを生成する必要があります。.orig.rej

シンボリックリンクパッチを受け入れないようなのでpatch、Linuxでは/dev/stdinまたは/proc/self/fd/0の使用は機能しません。

使用している場合は、一時ファイルを使用するプロセス代替フォームをzsh使用できます。=(...)

patch -i mypatch.diff -r - -o - =(cat)

GNU 2.6以降が必要です(-o -参照:-r -patch犯罪そして犯罪)。

関連情報