web-dev-qa-db-ja.com

Linuxでatime、mtime、ctimeではなく、どのファイルコンテンツが変更されたかを確認するにはどうすればよいですか?

Linuxで変更または追加されたファイルコンテンツを確認する方法はありますか?私はatime、ctime、mtimeを知っています。スクリプト「myscript.sh」を作成し、誰かがそのコンテンツを変更したとします。コードを数行追加するか、削除しました。ファイルの作成以降に変更されたコンテンツを知りたいですか?

何かご意見は?

1
Bustam

@SahibPrimeの回答に対するコメントに基づいて、 etckeeper を使用する必要があります。

ホームページから:

etckeeperは、/etcgitMercurialBazaar、またはdarcsリポジトリに保存するためのツールのコレクションです。 。これにより、gitを使用して、/ etcに加えられた変更を確認または元に戻すことができます。または、バックアップやチェリーピッキングの構成変更のためにリポジトリを別の場所にプッシュすることもできます。

aptなどのパッケージマネージャーにフックして、パッケージのアップグレード中に/etcに加えられた変更を自動的にコミットします。 gitが通常サポートしていないファイルのメタデータを追跡しますが、/ etc/shadowのアクセス許可など、/ etcにとって重要です。

これは非常にモジュール化されて構成可能ですが、バージョン管理の基本を理解していれば簡単に使用できます。

SahibPrimeが言及しなかったことの1つは、git diffを使用して、現在および/または以前にコミットされたバージョン間で行われた変更と、それらの変更がいつ行われたかを表示できることです。また、リビジョン管理されたファイルの以前のバージョンに簡単に戻すこともできます。

少なくともDebianでは、cronから毎日実行されるため、変更をコミットすることを覚えておく必要はありません。ほぼ確実に、他のディストリビューションでもcronから実行されます。

それをインストールし、必要になるまで完全に忘れてください。メンテナンスは不要です。

git(または他の同様のソフトウェア)を使用して、/ usr/localの変更を追跡することもできます。私はRCSを/ etcや/ usr/local/{s、} bin /や〜/ binなどのディレクトリで何年も使用していました。後で私はsvnに切り替えました。 etckeepergitの方が優れています。


tldr:gitmeoutofhere

2012年にetckeeperに切り替えたに違いありません。それ以降、すべての変更(少なくとも毎日、およびすべてのaptインストールまたはアップグレードの前後)の改訂履歴があります。

# git log | tail -5 
commit 7e3bb0eade7ae9e211bb684be2e3c7d4a3128c24
Author: ...my.email.address.deleted...
Date:   Wed Feb 29 12:53:30 2012 +1100

    Initial commit

# git log | grep '^commit' | wc -l
1378

私はそれを見たり、考えたり、そこにあることを覚えたりする必要はほとんどありませんが、必要なときは非常に貴重です。私は自分がするかもしれない愚かなことを元に戻すことができ、設定ファイルの既知の動作している良いバージョンを即座に取り戻すことができます。

設定ファイルのすべての改訂履歴でできることのいくつかを次に示します。

特定のファイルのコミットのリストを見ることができます:

# git log Apache2/Apache2.conf | sed -ne 's/commit //p'  | head
2d0fabf90f2bc639d30bca925147fafd3fbd5e50
8022c7ca6dbe1661064604a646c52ca0d1f1b3ac
0620c88b8d1fd625f74f42059a4e8f056846df16
8c2fcfef72eca034b251654be44a268e92e39416
02329cf86655a2bb2c09c793b1d195a4de579cf1
5e449105f0ab75f9e903d8c75af5c8db6543c281
d8339212967af2c664b0c1776e9352f6c0e12ff8
7e3bb0eade7ae9e211bb684be2e3c7d4a3128c24

これらのコミットのいずれかがいつ発生したかを確認できます。

# git log 8022c7ca6dbe1661064604a646c52ca0d1f1b3ac | head -5
commit 8022c7ca6dbe1661064604a646c52ca0d1f1b3ac
Author: ...
Date:   Tue Aug 20 12:26:53 2013 +1000

    committing changes in /etc after apt run

そして私はdiffを見ることができます:

# git diff 8022c7ca6dbe1661064604a646c52ca0d1f1b3ac Apache2/Apache2.conf
diff --git a/Apache2/Apache2.conf b/Apache2/Apache2.conf
index baf6d8a..617152c 100644
--- a/Apache2/Apache2.conf
+++ b/Apache2/Apache2.conf
@@ -71,7 +71,7 @@
 #
 # The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
 #
-Mutex file:${Apache_LOCK_DIR} default
+#Mutex file:${Apache_LOCK_DIR} default

 #
 # PidFile: The file in which the server should record its process

そして、私は何でもおよび/またはすべてを以前のバージョンに戻すことができます。最も便利なのは、個々のファイルを元に戻すことです。

# git checkout 8022c7ca6dbe1661064604a646c52ca0d1f1b3ac Apache2/Apache2.conf
# git diff 8022c7ca6dbe1661064604a646c52ca0d1f1b3ac Apache2/Apache2.conf
#

前回のコミット以降に変更されたファイルのリストを確認できます。

# git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   Apache2/Apache2.conf

no changes added to commit (use "git add" and/or "git commit -a")

必要に応じて、(git addgit commitを使用して)もう一度コミットするか、考えを変えて最新のコミットを取り戻すことができます。

# git checkout 2d0fabf90f2bc639d30bca925147fafd3fbd5e50 Apache2/Apache2.conf
# git help status
# 
0
cas

gitを介してVCSの方法でこれを行うことができます。
まず、gitをインストールします(プリインストールされている必要があります。そうでない場合は、パッケージマネージャーにインストールされている必要があります)
Debianシステムの場合:Sudo apt-get install git
次に、ファイルを保存するディレクトリを作成します(mkdir myDir
ディレクトリに移動し、git initを実行します。 (これにより、ローカルのGitリポジトリが作成されます)。
ファイルをディレクトリに追加してから、git add -f *を実行します。
これで、git commit -m "file before editing"を実行して、ファイルをそのまま保存できます。
git statusを実行して、ファイルが編集されているかどうかを確認できます。次のように表示されます。

modified: myFile.txt

最後にgit commitを実行したときにファイルをロールバックする場合は、git reset --hard HEAD^を実行できます。これにより、ローカルリポジトリは最後のコミットに戻るように強制されます。

次のように、git commitを使用してファイルへの新しい変更を保存できます。

git commit -m "added 4 lines"

コミット(およびそのメッセージ)のリストを表示したい場合は、git logを実行できます。


VCSはこのために設計されたので、私はそれを答えに使用しました。

3
InitializeSahib

通常、Unixに組み込まれている機能はありません(つまり、Unixの最も一般的なファイルシステムに組み込まれています OpenVMS上にあります )ので、以前のバージョンのファイルを取得することは期待できません。

最も簡単な解決策は、「監視」したいファイルの個人用コピーを保持し、これらとシステムにインストールされているコピーに対して定期的にdiffを実行することです。

次のステップは、ファイルをある種のリビジョン管理システムに保持することです。 Unixでこれらの中で最も簡単に利用できるのは、通常 [〜#〜] rcs [〜#〜] です。これは非常に基本的ですが、缶に書かれていることを実行します。

Git はより洗練されていますが、これが1つまたは少数のファイルに関係する場合は面倒すぎる可能性があります(RCSは個々のファイルを処理し、一緒に属する多くのファイルの「リポジトリ」の概念はありません)。

1
Kusalananda

「diff」で十分ではないでしょうか。 diff oldfile newfile> changesはすべての違いを適切な行番号でファイル名の変更に入れます。

アラン

0
apolinsky

最後の手段メソッド、リビジョン管理を使用しなかった場合。警告:前提条件を確認してください。状況によっては機能しない場合があります。私はこれを2回しか行っていません。

前提条件:

  • ファイルは、ファイルを置き換えるエディターによって変更されました:unlink、create;または作成、リンク解除、移動。 (オリジナルを変更することによってではありません)
  • 元のファイルは、システム上の少なくとも1つのプロセスによってまだ開かれています。
  • あなたは賢く、忍耐強く、そして時間があります。
  • あなたは幸運です(「私がより幸運を得るほど練習すればするほど」を覚えておいてください)。

方法:

  1. 元のファイルがまだ開いているプロセスを見つけます。 (ヒント:lsof
  2. このプロセスのPIDを特定します。
  3. /proc/«pid»/fdに移動します。
  4. 探しているファイルのファイル記述子(番号:0はstdin、1 stdout、2 stderr、その他のファイルの場合はその他の番号)を特定します。
  5. ファイルを/proc/«pid»/fd/«file-descriptor»から永続ストレージ領域(ハードディスク)にコピーします。

警告:これは魔法です(これを思い出させてくれた@wildcardに感謝します)。

0
ctrl-alt-delor

侵入検知システム(IDS)を探している可能性があります。一部のIDSは、システム上のすべてのファイルを定期的に検査し、予期しない変更を警告します。古典的な例はtripwireですが、過去8時間、 tripwire.org で403を取得しています。

このようなシステムは通常、ファイルのチェックサムを記憶しているだけなので、何が変更されたかを知るには、バックアップと比較する必要があります。

0
Law29