代码之家  ›  专栏  ›  技术社区  ›  l0b0

在ext4上触摸时间戳精度

  •  4
  • l0b0  · 技术社区  · 14 年前

    更新 原来我很笨。我在检查修改时间,当时我应该检查访问时间。不可复制的原因是测试文件是用 dd if=/dev/urandom of="$target" bs='1K' count=1 || exit 1 对于修改时间来说,大部分时间都太快了(结束于 dd )与访问时间不同的新文件的 DD )还有一件事要注意。

    我正在编写一个脚本,将一个文件的访问时间加上两年时间应用于另一个文件。这种用途 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' 说它支持纳秒。但有时应用touch时,应用的时间戳和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.938ms,中位数4.001 ms。有什么可能导致这种情况吗?

    $ uname -a
    Linux user 2.6.32-22-generic #33-Ubuntu SMP Wed Apr 28 13:27:30 UTC 2010 i686 GNU/Linux
    
    2 回复  |  直到 12 年前
        1
  •  0
  •   thkala jaxb    14 年前

    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
    

    $ 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
    

        2
  •  0
  •   Jarekczek    12 年前

    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 touch b a

    svn status