4

更新:私は非常に愚かだったことがわかりました。アクセス時間を確認する必要があるのに、変更時間を確認していました。再現性がなかった理由は、テストファイルがで作成されたためですdd if=/dev/urandom of="$target" bs='1K' count=1 || exit 1。ほとんどの場合、新しいファイルの変更時間(の終わりdd)がアクセス時間(の開始時間)と異なるには速すぎましたdd。注意すべきもう一つのこと。

あるファイルのアクセス時間をプラス2年を別のファイルに適用するスクリプトに取り組んでいます。これは、、stat -c %xおよびdate --rfc-3339=nsを使用しtouch -a --date="$result"ます。stat両方ともdate、ナノ秒の日付文字列を出力します。

2012-11-17 10:22:15.390351800+01:00

、そしてinfo coreutils 'touch invocation'それはナノ秒をサポートすると言います。ただし、タッチを適用すると、適用されたタイムスタンプと後でstatによって返されるタイムスタンプにわずかな違いがある場合があります。実際の実行からのデータは次のとおりです。

$ for i in {1..100}; do ./t_timecopy.sh 2>/dev/null| grep ASSERT; done
ASSERT:Expecting same access time expected:<2012-11-17 10:58:40.719320935+01:00> but was:<2012-11-17 10:58:40.723322203+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:00:04.342346275+01:00> but was:<2012-11-17 11:00:04.346358718+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:00:39.343348183+01:00> but was:<2012-11-17 11:00:39.347351686+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:01:08.655348312+01:00> but was:<2012-11-17 11:01:08.659347625+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:01:37.930346876+01:00> but was:<2012-11-17 11:01:37.934347311+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:02:16.939319832+01:00> but was:<2012-11-17 11:02:16.943323061+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:02:46.456443149+01:00> but was:<2012-11-17 11:02:46.458379114+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:03:15.487339595+01:00> but was:<2012-11-17 11:03:15.491341426+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:04:04.646335863+01:00> but was:<2012-11-17 11:04:04.650346634+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:04:14.410326608+01:00> but was:<2012-11-17 11:04:14.414331233+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:04:24.159367348+01:00> but was:<2012-11-17 11:04:24.163352418+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:04:33.931387953+01:00> but was:<2012-11-17 11:04:33.935350115+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:05:03.394361030+01:00> but was:<2012-11-17 11:05:03.398320957+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:05:42.054317430+01:00> but was:<2012-11-17 11:05:42.059106497+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:06:40.346320820+01:00> but was:<2012-11-17 11:06:40.350346956+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:08:17.194346778+01:00> but was:<2012-11-17 11:08:17.198338832+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:08:27.102347603+01:00> but was:<2012-11-17 11:08:27.106320380+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:09:16.247322948+01:00> but was:<2012-11-17 11:09:16.251347966+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:09:55.191325266+01:00> but was:<2012-11-17 11:09:55.195320672+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:12:09.915318301+01:00> but was:<2012-11-17 11:12:09.919334099+01:00>
ASSERT:Expecting same access time expected:<2012-11-17 11:12:28.906346914+01:00> but was:<2012-11-17 11:12:28.910348186+01:00>

したがって、100回のテストのうち21回が失敗し、平均は3.938ミリ秒、中央値は4.001ミリ秒でした。これを引き起こす可能性のあるアイデアはありますか?

$ uname -a
Linux user 2.6.32-22-generic #33-Ubuntu SMP Wed Apr 28 13:27:30 UTC 2010 i686 GNU/Linux
4

2 に答える 2

0

私はこの一連の(確かに迅速で汚い)onelinerを使用して、私のシステムで問題をテストしました-Mandriva Linux 2010.1(x86-64):

seq 1 1000 | while read f; do sleep 0.01; touch test-$f-0; done

seq 1 1000 | while read f; do touch -a -d "$(stat -c %x test-$f-0 | sed 's|^2010|2012|')" test-$f-1; done

seq 1 1000 | while read f; do A="$(stat -c %x test-$f-0)"; B="$(stat -c %x test-$f-1)"; if [[ ! "${A#2010}" = "${B#2012}" ]]; then echo test-$f; fi; done

私はあなたの問題を一度も再現することができませんでした。touchには-dパラメータで期待されるタイムスタンプが与えられていないようですが、それ以外の方法で計算されたものがあります。

もちろん、問題はシステム固有である可能性があります。その場合、システムに関する詳細情報が必要になります(CPU、OS 32または64ビット、kernel / glibc / coreutilsバージョンなど)。

アップデート:

32ビットバージョンのstatとtouchでも同じことを試しました。問題は発生しませんでした。カーネルはまだ64ビットのものでした。

UPDATE2:

私はまた、このワンライナーのセットを試しました。

$ seq 1 1000 | while read f; do sleep 0.01; touch test-$f-0; done
$ seq 1 1000 | while read f; do sleep 0.01; touch test-$f-1; done
$ seq 1 1000 | while read f; do sleep 0.01; cat test-$f-0; done
$ seq 1 1000 | while read f; do touch -a -d "$(stat -c %x test-$f-0 | sed 's|^2010|2012|')" test-$f-1; done
$ seq 1 1000 | while read f; do A="$(stat -c %x test-$f-0)"; B="$(stat -c %x test-$f-1)"; if [[ ! "${A#2010}" = "${B#2012}" ]]; then echo test-$f; fi; done

ここでも問題は検出されませんでした。relatimeとstrictatimeの両方のマウントオプションでこれを試しました。

UPDATE3:

Mandrivai686ラップトップで上記のテストを実行する必要があります。そこにもナノ秒の精度で問題はないようです。また、別の32ビットシステムで、ナノ秒の精度がサポートされていない場合(たとえば、ext3)、統計出力のナノ秒フィールドがゼロになることを確認しました。

于 2010-11-17T13:17:01.577 に答える
0

Windows764ビットのタッチは同様の問題を引き起こします。これは私のエクスプロイトコードです:

touch a && touch b && ls --full-time a b
touch -r a b && ls --full-time a b

そして出力:

-rw-rw-rw-  1 Jarek 0 0 2012-05-09 12:05:27.851839700 +0200 a
-rw-rw-rw-  1 Jarek 0 0 2012-05-09 12:05:27.874841000 +0200 b

-rw-rw-rw-  1 Jarek 0 0 2012-05-09 12:05:27.851839700 +0200 a
-rw-rw-rw-  1 Jarek 0 0 2012-05-09 12:05:27.851839000 +0200 b

lsそしてtouchgnuwin32から来ます。最初の2つの出力行には、20ミリ秒のタイムスタンプの違いがあります。良い。しかし、2回目の実行では、それらは等しくなければなりません(bからスタンプを取得しましたa)。運がない。0.7usの違いがあります:)。

svn status違いを理解しているので、それをだますのは難しいtouchです。

于 2012-05-09T10:18:55.680 に答える