Linuxでのファイル差分の確認方法の実務上の結論は「review可能なtext差分はdiff -u、byte単位の一致はcmp、離れたcopyの照合はSHA-256を使い分けます。差分確認とpatch適用を同じ段階にしません。」です。比較前に「同一」をtext意味、byte列、metadataのどれで定義するか決めます。diffやcmpのstatus 1は差ありであり、read failureを示す2以上と同じ再試行queueへ入れません。
diffの終了statusを三段階で読む
textの内容差はdiff -u、byte単位で同一かだけを見るならcmp、directory treeの比較はdiff -rが入口です。ただしowner、mode、ACL、xattr、timestampなどmetadataは通常の内容diffだけでは完全に比較できません。改行、encoding、生成順、localeによる差もあり、何を同一とするかを先に定義しないと、差を隠すoptionが誤判定につながります。
diff -uは前後context付きでreviewしやすく、–labelで一時pathを意味ある名前へ置換できます。-wや-Bは空白や空行を無視しますが、source codeや設定では意味のある変更も消し得ます。cmp –silentはbyte同一性のstatus判定向けです。directory比較では除外pattern、symbolic link、別filesystem、special fileの扱いを明記します。
text差・byte差・metadata差の合格基準を定める
- textかbinaryかを確認する
- 意味差とbyte差のどちらを判定するか決める
- 改行、encoding、localeの扱いを固定する
- 比較中にfileが変化しないsnapshotを用意する
比較中に片方が更新されるなら結果を採用しません。両側のsizeとhashを前後で記録し、CRLF、encoding、生成順を正規化する必要がある場合は、比較optionではなく承認済み前処理として仕様化します。
diff・cmp・SHA-256を目的別に走らせる
unified diffを表示
diff -u -- ./before.conf ./after.conf
終了code 0は同一、1は差あり、2はtroubleとして分けます。
同一かを静かに判定
cmp -s -- ./before.bin ./after.bin
rc=$?
case "$rc" in
0) printf '%s\n' 'identical' ;;
1) printf '%s\n' 'different' ;;
*) printf 'cmp_error=%s\n' "$rc" >&2; exit "$rc" ;;
esac
cmpの0は同一、1はbyte差、2以上はreadやoption等のerrorとして分岐し、error statusを保持します。
最初のbyte差を表示
cmp -- ./before.bin ./after.bin
binaryの差位置を確認し、内容全体はterminalへ出しません。
SHA-256を比較
sha256sum -- ./before.bin ./after.bin
同じdigest algorithm、同じbyte列であることを確認します。
空白差を調査用に表示
diff -u --ignore-trailing-space -- ./before.txt ./after.txt
無視optionは調査補助であり、正式なbyte同一判定には使いません。
内容差・metadata差・構造差を分ける
diffはline-orientedなtext差分、cmpはbyte比較です。diffの終了code 1は通常の差ありでerrorではありません。whitespace無視やcase無視は差を隠すため、正式判定とreview補助を分けます。hash一致は強いbyte同一性確認ですが、信頼できるmanifestや署名の代わりではありません。
GNU diffは差なしで0、差ありで1、read errorやoption errorなど問題発生で2以上を返します。差ありの1をcommand失敗として再試行しても内容は一致しません。逆にpipelineや表示toolで最終statusが0になり、diffのerrorが隠れることがあります。stdoutの差分、stderr、終了statusを別々に保存し、空出力でもstatusを確認します。
binary判定、encoding不一致、CRLF/LF、権限不足、途中更新、broken linkを区別します。大きな生成物をtext diffするとmemoryやI/O負荷が増え、比較中にsourceが更新されると一貫しない結果になります。『Binary files differ』だけでは差の位置や安全性は分からず、hash、size、format固有validatorへ切り替えます。
差あり1と読取error2以上を混同しない
- diff終了code 1を実行errorとする
- 空白無視結果を完全同一と呼ぶ
- binaryをtext diffで大量表示する
- 変更中file同士を一回だけ比較する
- digestのalgorithmやmanifest sourceを確認しない
diff/cmpの0は同一、1は差あり、2以上はoptionやread等の問題として記録します。1を再実行して一致を待たず、2以上ならstderrと権限を直して同じsnapshotを再試験します。
snapshot同士を比較しpatch適用を切り離す
比較中は原本を編集せず、必要ならread-only snapshotを使います。diff出力にsecretが含まれるため共有先を制限します。patchを適用する場合は別承認、backup、dry-run相当、rollback、post-apply hashを設けます。
差分表示は読み取りでも、そこからpatch、rsync、上書きへ直結させると影響が変わります。秘密情報を含む設定diffをticketや公開logへ貼らず、masking後も意味が残る最小範囲だけ共有します。merge前はbackupまたはversion管理commitを確保し、差分が空になったことだけでserviceの正常性を判断しません。
再現可能な差分検証
同一、1行差、末尾newline差、CRLF/LF、encoding差、binary差、read errorをsample化します。diff/cmp/hashの結果と終了codeを期待表へ記録し、原本hashが不変か確認します。
同一file、一文字変更、空白だけ、改行だけ、binary一byte変更、read不可、処理中更新をfixtureにします。diff -u、cmp、必要なmetadata取得のstdout・stderr・statusを期待表へ照合し、差あり1とerrorを別の合格条件にします。patch適用を伴う検証はcloneまたはcopyで行い、原本へ自動反映しません。
CIで0・1・2以上を用途別にmappingする
CIでは終了status 0を一致、1を期待された差、2以上をtool errorとして明示し、用途に応じて1をpassかfailへmappingします。生成順が不定ならsourceを正規化する専用処理を定義し、diff側で広く無視しません。比較前後のhashとsizeを採取し、sourceが変化したrunを無効として再取得します。
差の種類からsemantic comparatorを選ぶ
code reviewや設定比較にはunified diff、完全なbyte一致にはhashまたはcmp、directory同期の設計にはmetadataとlinkも扱えるtoolを選びます。JSONやXMLなど順序や空白の意味が構造依存ならparse後のsemantic comparisonを使います。差を見つける目的と、どちらを正本にする判断を分離して記録します。
diffの終了値は、0が差分なし、1が差分あり、2以上が読取りやoptionなどのerrorです。差分ありを実行失敗へまとめず、CIでは期待する状態に応じて1を判定へ組み込みます。binary判定や文字code、改行codeの違いで表示が変わるため、fileとlocaleを記録し、比較対象のhashとsizeも併せて残すと再検証できます。
合格は同一・一byte差・read不可fixtureでcmpの0・1・2以上を保ったままCI判定へ写せることです。比較前後のhashが変わったrunは破棄し、snapshotを作り直します。

コメント