3

私は Linux で簡単なことだと思うことをやろうとしています。さまざまなテスト プログラムを実行する bash スクリプトがあり、現在のディレクトリ内のどのファイルがテスト プログラムによって作成されたかを確認したいと考えています。だから私はこのようなことをしています:

touch タイムスタンプ ファイル
テストを実行する
find -newer timestamp-file -type f > list-of-files
rm -f タイムスタンプファイル

find -newer の粒度が悪いことが判明したため、通常、テスト プログラムによって生成された一部のファイルがタイムスタンプ ファイルよりも古いものとして表示されます。それで、私はこれを試しました:

ls -tr1 | sed '1,/timestamp-file/d'

同じリストを生成します。これは通常は機能しますが、常に機能するとは限りません。テストによって生成されたファイルがタイムスタンプ ファイルよりも古いものとして表示されるという状況に陥ります。

ありがとう!

PS 別の方法として、ディレクトリの 2 つのスナップショット (テスト プログラムの実行前と実行後) を取得し、それらを比較することで、これを実現できます。最初のリストにない 2 番目のリストのファイルはすべて、テスト プログラムによって作成されたものでなければなりません (バックグラウンド ジョブや、他のユーザーがディレクトリに書き込むことには関心がありません)。しかし、このメソッドは私が望むものではありません。テストを実行する前に出力ファイルが削除されなかった場合 (削除されるはずですが、削除されない場合もあります)、このメソッドは、テストプログラムが実行される前にディレクトリにあったため、テストプログラム。

4

4 に答える 4

3

実際に touch を使用して、ディレクトリ内の現在のすべてのファイルのタイムスタンプを、次のように過去に強制することができます。

touch -t 200801010000.00 *

テストを実行する前にこれを行うと、" " がテストを取得するのに十分な時間差があるはずfind -newerです。粒度が 2 分の場合、現在のすべてのファイルを 10 分前に、タイムスタンプ ファイルを 5 分前に設定してから、テストを実行できます。

したがって、スクリプトは次のようになります。

touch -t (current time - 10 minutes) *
touch -t (current time -  5 minutes) timestamp-file
run the test
find -newer timestamp-file -type f > list-of-files
rm -f timestamp-file

date -tPerl が適切にインストールされていると仮定すると、次のようにして " "の正しい形式で 5 分前 (または 10 分間に -600 を使用) を取得できます。

use Date::Manip;
print UnixDate(DateCalc(ParseDateString("now"),"-300"),"%Y%m%d%H%M.%S") . "\n";

何らかの理由でタイムスタンプの変更が許可されていない場合は、次を使用します。

sleep 300
touch timestamp-file
sleep 300
run the test
find -newer timestamp-file -type f > list-of-files
rm -f timestamp-file

これは同じ効果がありますが、コーヒーを飲むのに10分かかります(または、コーヒーを飲まない場合は選択した毒)。

于 2009-01-02T23:35:16.763 に答える
2

がどのようfind(1)に実装されているかを考えると、これが期待どおりに機能しない場合がある理由が明確になります。ヒントは次のとおりです。

  $ touch timestamp ; touch newer ; find . -newer timestamp 
  $ rm timestamp newer
  $ touch timestamp ; sleep 1 ; touch newer ; find . -newer timestamp
  .
  ./newer
  $

find(1)システムコール を使用して、ファイル mtime/ctime/atime 値を取得しますstat(2)struct statfrom <sys/stat.h>(Linux)の要素は次のとおりです。

  time_t    st_atime;   /* time of last access */
  time_t    st_mtime;   /* time of last modification */
  time_t    st_ctime;   /* time of last status change */

Linux (および一般的なユニックス)time_tでは、「1970 年の開始からの秒数」を表す整数です。したがって、理解できる最も細かい粒度-newerはわずか 1 秒です。

于 2009-01-03T10:18:01.893 に答える
1

実行前にすべてのファイルのファイル名を取得しますが、タイムスタンプを含めます。

find -printf '%p %T@\n' | sort > file1

その検索オプションを利用できない場合は、そのジョブにも stat を使用できます。

find -print0 | xargs -0 stat -c "%n %Y" | sort > file1

そして、 への実行の後file2。次に使用します

comm -1 -3 file1 file2

に固有の行が表示されますfile2。間違いがなければ、これは新しいファイルである必要があります。それらが以前に存在していた場合、変更時間は変更されています。これは、%T@thingy によって処理されます (1970 年からの秒数を出力します)。

[js@HOST2 cpp]$ find -printf '%p %T@\n' | 並べ替え > ファイル 1
[js@HOST2 cpp]$ echo foo>bar
[js@HOST2 cpp]$ echo foo>baz
[js@HOST2 cpp]$ find -printf '%p %T@\n' | 並べ替え > file2
[js@HOST2 cpp]$ comm -1 -3 file1 file2
. 1230947309.0000000000
./bar 1230947308.0000000000
./baz 1230947309.0000000000
./file2 1230947315.0000000000
[js@HOST2 cpp]$ find -printf '%p %T@\n' | 並べ替え > ファイル 1
[js@HOST2 cpp]$ echo lol>bar
[js@HOST2 cpp]$ find -printf '%p %T@\n' | 並べ替え > file2
[js@HOST2 cpp]$ comm -1 -3 file1 file2
./bar 1230947359.0000000000
./file2 1230947362.0000000000
[js@HOST2 cpp]$`
于 2009-01-03T01:32:18.290 に答える
0

テストを実行するための一時ディレクトリを作成しないのはなぜですか? ディレクトリにタイムスタンプベースの名前を使用して、いつどの結果が発生したかを追跡し、終了したらディレクトリ全体を単純に削除します。

于 2009-01-02T23:47:37.753 に答える