※当サイトの記事には、広告・プロモーションが含まれます。

Linuxでファイルに追記が行われても更新日時(mtime)が変わらない場合がある罠

nazology.kusuguru.co.jp

米国のバージニア工科大学(Virginia Tech)での研究によると、ニュートンの第一法則が、誰も気づかないまま300年に渡り、誤訳されていたようです。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

ニュートンの第一法則は一般に「力が働いていない物体は直線移動するか静止したままである」と解釈されています。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

しかし研究者たちがラテン語の原典を調べたところ、どうやらニュートンは第一法則について「力が働いていない物体」に限らず「力が働いている物体」も含んで述べていたことが判明しました。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

もちろんこの発見により物理理論が書き換わるわけではありません。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

研究者たちは些細なニュアンスのミスが原因と述べています。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

ラテン語においてニュートンは「運動は外力によって強制される限りにおいてのみ変化する」と記していましたが、1729年にアンドリュー・モットが英語に翻訳する際に「限りにおいてのみ」“nisi quatenus(英語ではexcept insofar)”という部分を「でなければ」“unless”としてしまったのです。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

これにより原典のラテン語では「運動は外力によって強制される限りにおいてのみ(except insofar)変化する(つまり物体の変化には力が必要だ)」との力強い主張が、多くの人々の目にする英語版では「運動は外力によって強制されていなければ(unless)変化しない(つまり力が働かな物体には変化がない)」と控えめかつ、循環論法と誤解を誘発する表現になっていたのです。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

そして残念なことに、この間違いは修正されることなく拡散していきました。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

今後もニュートンの第一法則の解釈は間違ったまま、語り継がれるでしょう。

ニュートンの「第一法則」は300年以上も誤訳されていた! - ナゾロジー

⇧ いや、誤訳に気付いたなら、改訂履歴を残して訂正して欲しいんだが...

  1. ラテン語
  2. 英語
  3. それ以外

で、認識合わせするの辛い気がするんだが...

  1. ラテン語」版の原典に誤りが無い
  2. ラテン語」版の原典を元に「日本語」版は翻訳されている
  3. 「日本語」版で誤訳が無い

を満たしているのであれば、日本の学術研究においては影響を受けていないことになるような気がするのだが...

「日本語」版の翻訳の状況が全く分からないから、何とも言えないのだが...

2025年4月30日(水)追記:↓ ここから

何やら、

gigazine.net

約300年前に物理学者のアイザック・ニュートンが考案した「ニュートン法」は、現代でも物流や金融工学、コンピュータビジョン、純粋数学など多岐にわたる分野で重要な役割を果たしているアルゴリズムです。これまでさまざまな数学者がこのニュートン法の改良に苦心しており、近年の研究でついにアップデートされたと科学系ニュースサイトのQuanta Magazineが紹介しています。

物理学者ニュートンが300年前に考案して現代でも実用されるアルゴリズム「ニュートン法」がアップデートされる - GIGAZINE

ニュートン法は数学の世界の中だけではなく、私たちの日常生活を支える多くの技術や問題解決に深く関わっています。例えばGPSのナビゲーションでは、最短経路を見つける際、様々な道路の組み合わせの中から最も時間や距離が短くなるルートを計算する必要があります。この「最適化問題」の解決にニュートン法のような数値解析手法が使われています。

物理学者ニュートンが300年前に考案して現代でも実用されるアルゴリズム「ニュートン法」がアップデートされる - GIGAZINE

ニュートン法の最大の強みは、その「二次収束」と呼ばれる性質です。これは反復するたびに解の誤差が指数関数的に減少することを意味し、勾配降下法のようなアルゴリズムよりも少ない回数で解に到達できます。

物理学者ニュートンが300年前に考案して現代でも実用されるアルゴリズム「ニュートン法」がアップデートされる - GIGAZINE

しかし、ニュートン法には「すべての関数に対して効率的に機能するわけではない」という弱点があり、特に複雑な非凸関数において課題があります。そこで数学者たちは長年にわたり、効率性を維持しながらも適用範囲を広げる方法を研究してきました。

物理学者ニュートンが300年前に考案して現代でも実用されるアルゴリズム「ニュートン法」がアップデートされる - GIGAZINE

ニュートンの定義した法則が活用されているのなら、益々持って翻訳の統一した方が良い気はするんだが...

とりあえず、

計算機科学において、Garbage In, Garbage Outガービッジ・イン、ガービッジ・アウト/ガベージ・イン、ガベージ・アウト)、略してGIGOとは、欠陥のある、または無意味な(garbage)入力データは無意味な出力を生み出すという概念である。直訳は「ゴミ入力するとゴミが出力される」。すなわち、「『無意味なデータ』をコンピュータに入力すると『無意味な結果』が返される」という意味である。Rubbish in, rubbish out (RIRO)とも表現される

Garbage in, garbage out - Wikipedia

この原則は、すべての論理的議論に適用される。健全な議論もその前提に欠陥があれば、健全でない結論に至ることがある。

Garbage in, garbage out - Wikipedia

⇧ 不正確な情報を元にすることは、正確ではない回答になり得るリスクが大きいはずですしな...

何と言うか、「伝言ゲーム」が意図せず情報が「捏造」されてしまうように、

バタフライ効果(バタフライこうか、butterfly effect)は、力学系の状態にわずかな変化を与えると、そのわずかな変化が無かった場合とは、その後の系の状態が大きく異なってしまうという現象

バタフライ効果 - Wikipedia

カオス理論で扱うカオス運動の予測困難性、初期値鋭敏性を意味する標語的、寓意的な表現である

バタフライ効果 - Wikipedia

気象学者エドワード・ローレンツによる、「がはばたく程度の非常に小さな撹乱でも遠くの場所の気象に影響を与えるか?」という問い掛けと、もしそれが正しければ、観測誤差を無くすことができない限り、正確な長期予測は根本的に困難になる、という数値予報の研究から出てきた提言に由来する

バタフライ効果 - Wikipedia

⇧ 僅かな変化が与える影響は、「冪等性」を破壊し得るわけで、誤った情報は無くすのが良い気はしますかね...

2025年4月30日(水)追記:↑ ここまで

Linuxでファイルに追記が行われても更新日時(mtime)が変わらない場合がある罠

業務で携わっていたシステムで、ファイルに追記がされて、ファイルサイズが変わっているのは確認できたので、ファイルに対して変更が行われたのは確実なのだが、「更新日時(mtime)」が変わらない...

具体的には、ホスト側の「ファイルシステム」は、「Azure Data Lake Storage」にマウントされており、ホスト側のディレクトリとマウントされているDockerコンテナ内での話になるのだが。

ちなみに、

learn.microsoft.com

⇧「マルチプロトコルアクセス」のドキュメントなのに、「NFS(Network File System)」の「プロトコル」の話が出てこないという安定の不親切さ、流石は「Microsoft」、相変わらず、顧客を蔑ろにする精神は健在といったところでしょうか。

そもそも、「Azure Data Lake Storage」がサポートしている「プロトコル」の全量を上記のドキュメントのページに記載していないのが『シンジラレナ~イ(トレイ・ヒルマン)』。

「Azure Data Lake Storage」がサポートの対象としている「プロトコル」が把握できないと議論が進まないと思うのだが...

 

ちなみに、確認に実行したコマンドは、

ls -la [対象のファイルのあるディレクトリ]    

⇧ といった感じで、一般的な「Linuxディストリビューション」であれば利用できるコマンドを使用している。

「ll」は、「Dockerコンテナ」とかだと利用できない可能性があるので、「ls」を利用するのが無難かと思われる。

ちなみに、

stackoverflow.com

⇧「find」コマンドがインストールされていない場合もあるという...

 

で、ファイルを更新したら、「更新日時(mtime)」が変わるのが常識と思い込んでいたのだが、「更新日時(mtime)」が変わらない事象に遭遇したので、「更新日時(mtime)」が変わらないことをどのように実現すれば良いのか調べてみた。

ネットの情報を漁っていたところ、

genzouw.com

一口に「日時情報」といっても、Linux ファイルシステムには以下の 3 つの「タイムスタンプ」があり、 更新されるタイミングが異なります。

  • mtime : 中身(コンテンツ)が変更された日時
  • atime : アクセスされた日時
  • ctime : 属性が変更された日時

Linux ファイルシステムにおけるタイムスタンプ(mtime、atime、ctime)の違い、確認方法、変更方法 | ゲンゾウ用ポストイット

⇧ 上記サイト様によりますと、3つの「日時情報」が存在するらしいのですが、

mtime、atime、ctime の更新タイミングと確認方法は以下の表に表現できます。

タイムスタンプ 「内容」を変更 「属性」を変更 「内容」を参照 タイムスタンプを確認
mtime 更新 - - stat / ls -l
atime - - 更新(ファイルシステムの設定による) stat / ls -lu
ctime 更新 更新 - stat / ls -lc

Linux ファイルシステムにおけるタイムスタンプ(mtime、atime、ctime)の違い、確認方法、変更方法 | ゲンゾウ用ポストイット

⇧ とあり、更新されるのが一般的ではあるらしい。

ということは、デフォルトの状態では、「更新日時(mtime)」が変更されるのが常識ということになるので、「更新日時(mtime)」が変更れない原因は、人為的に行われているという何某かの処理ということになりますと。

ネットの情報を漁っていたところ、

atmarkit.itmedia.co.jp

 Linuxファイルシステムには、ファイルを読んだ時刻が「atime」というタイムスタンプとして保存される。1ファイルアクセス当たりのオーバーヘッドはささやかなものだが、大量のファイルに対して頻繁にアクセスするシステムでは、atimeの更新にかかる時間も無視できなくなる。atimeが不要なシステムであれば、atimeの更新を無効化することでディスクのパフォーマンスが向上する可能性がある。

https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/659noatime.html

 atimeの更新は、/etc/fstabのマウントオプションとして「noatime」を指定することで無効化できる。

https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/659noatime.html

⇧ 上記サイト様によりますと、「マウント」の「オプション」によっては、「アクセス日時(atime)」を不変にすることはできるらしい。

ただ、今回は「更新日時(mtime)」が変わらないという事象なので、原因は異なるということになりそうではある。

ちなみに、「マウント」の「オプション」は他にもあるようで、

qiita.com

mountのオプションとして渡される文字列は**mount(8)**コマンド(util-linuxの一部)が解釈し、MNT_NOATIMEなどのオプションに変換して、**mount(2)**システムコールを呼ぶ。util-linuxのoptmap.cより

Linuxのrelatimeマウントオプションの詳細 #lazytime - Qiita

⇧ 上記サイト様によりますと、「util-linux」の「optmap.c」が「オプション」として利用されるっぽい。

GitHubで公開されている情報を確認したところ、

github.com

https://github.com/util-linux/util-linux/blob/master/libmount/src/optmap.c

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * This file is part of libmount from util-linux project.
 *
 * Copyright (C) 2010-2018 Karel Zak <kzak@redhat.com>
 *
 * libmount is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 */

/**
 * SECTION: optmap
 * @title: Option maps
 * @short_description: description for mount options
 *
 * The mount(2) linux syscall uses two arguments for mount options:
 *
 *	@mountflags: (see MS_* macros in linux/fs.h)
 *
 *	@mountdata: (usually a comma separated string of options)
 *
 * The libmount uses options-map(s) to describe mount options.
 *
 * The option description (map entry) includes:
 *
 *	@name: and argument name
 *
 *	@id: (in the map unique identifier or a mountflags, e.g MS_RDONLY)
 *
 *	@mask: (MNT_INVERT, MNT_NOMTAB)
 *
 * The option argument value is defined by:
 *
 *	"="   -- required argument, e.g "comment="
 *
 *	"[=]" -- optional argument, e.g. "loop[=]"
 *
 * Example:
 *
 * <informalexample>
 *   <programlisting>
 *     #define MY_MS_FOO   (1 << 1)
 *     #define MY_MS_BAR   (1 << 2)
 *
 *     libmnt_optmap myoptions[] = {
 *       { "foo",   MY_MS_FOO },
 *       { "nofoo", MY_MS_FOO | MNT_INVERT },
 *       { "bar=",  MY_MS_BAR },
 *       { NULL }
 *     };
 *   </programlisting>
 * </informalexample>
 *
 * The libmount defines two basic built-in options maps:
 *
 *	@MNT_LINUX_MAP: fs-independent kernel mount options (usually MS_* flags)
 *
 *	@MNT_USERSPACE_MAP: userspace specific mount options (e.g. "user", "loop")
 *
 * For more details about option map struct see "struct mnt_optmap" in
 * mount/mount.h.
 */
#include "mountP.h"
#include "strutils.h"

/*
 * fs-independent mount flags (built-in MNT_LINUX_MAP)
 */
static const struct libmnt_optmap linux_flags_map[] =
{
   { "ro",       MS_RDONLY },                 /* read-only */
   { "rw",       MS_RDONLY, MNT_INVERT },     /* read-write */
   { "exec",     MS_NOEXEC, MNT_INVERT },     /* permit execution of binaries */
   { "noexec",   MS_NOEXEC },                 /* don't execute binaries */
   { "suid",     MS_NOSUID, MNT_INVERT },     /* honor suid executables */
   { "nosuid",   MS_NOSUID },                 /* don't honor suid executables */
   { "dev",      MS_NODEV, MNT_INVERT },      /* interpret device files  */
   { "nodev",    MS_NODEV },                  /* don't interpret devices */

   { "sync",     MS_SYNCHRONOUS, MNT_SUPERBLOCK },            /* synchronous I/O */
   { "async",    MS_SYNCHRONOUS, MNT_INVERT | MNT_SUPERBLOCK },/* asynchronous I/O */

   { "dirsync",  MS_DIRSYNC, MNT_SUPERBLOCK },/* synchronous directory modifications */
   { "remount",  MS_REMOUNT, MNT_NOMTAB },    /* alter flags of mounted FS */
   { "bind",     MS_BIND },                   /* Remount part of the tree elsewhere */
   { "rbind",    MS_BIND | MS_REC },          /* Idem, plus mounted subtrees */
#ifdef MS_NOSUB
   { "sub",      MS_NOSUB, MNT_INVERT },      /* allow submounts */
   { "nosub",    MS_NOSUB },                  /* don't allow submounts */
#endif
#ifdef MS_SILENT
   { "silent",	 MS_SILENT },                 /* be quiet  */
   { "loud",     MS_SILENT, MNT_INVERT },     /* print out messages. */
#endif
#ifdef MS_MANDLOCK
   { "mand",     MS_MANDLOCK, MNT_SUPERBLOCK },               /* Allow mandatory locks on this FS */
   { "nomand",   MS_MANDLOCK, MNT_INVERT | MNT_SUPERBLOCK},   /* Forbid mandatory locks on this FS */
#endif
#ifdef MS_NOATIME
   { "atime",    MS_NOATIME, MNT_INVERT },    /* Update access time */
   { "noatime",	 MS_NOATIME },                /* Do not update access time */
#endif
#ifdef MS_I_VERSION
   { "iversion", MS_I_VERSION },              /* Update inode I_version time */
   { "noiversion", MS_I_VERSION,  MNT_INVERT},/* Don't update inode I_version time */
#endif
#ifdef MS_NODIRATIME
   { "diratime", MS_NODIRATIME, MNT_INVERT }, /* Update dir access times */
   { "nodiratime", MS_NODIRATIME },           /* Do not update dir access times */
#endif
#ifdef MS_RELATIME
   { "relatime", MS_RELATIME },               /* Update access times relative to mtime/ctime */
   { "norelatime", MS_RELATIME, MNT_INVERT }, /* Update access time without regard to mtime/ctime */
#endif
#ifdef MS_STRICTATIME
   { "strictatime", MS_STRICTATIME },         /* Strict atime semantics */
   { "nostrictatime", MS_STRICTATIME, MNT_INVERT }, /* kernel default atime */
#endif
#ifdef MS_LAZYTIME
   { "lazytime", MS_LAZYTIME, MNT_SUPERBLOCK },               /* Update {a,m,c}time on the in-memory inode only */
   { "nolazytime", MS_LAZYTIME, MNT_INVERT | MNT_SUPERBLOCK },
#endif
#ifdef MS_PROPAGATION
   { "unbindable",  MS_UNBINDABLE,          MNT_NOHLPS | MNT_NOMTAB }, /* Unbindable */
   { "runbindable", MS_UNBINDABLE | MS_REC, MNT_NOHLPS | MNT_NOMTAB },
   { "private",     MS_PRIVATE,             MNT_NOHLPS | MNT_NOMTAB }, /* Private */
   { "rprivate",    MS_PRIVATE | MS_REC,    MNT_NOHLPS | MNT_NOMTAB },
   { "slave",       MS_SLAVE,               MNT_NOHLPS | MNT_NOMTAB }, /* Slave */
   { "rslave",      MS_SLAVE | MS_REC,      MNT_NOHLPS | MNT_NOMTAB },
   { "shared",      MS_SHARED,              MNT_NOHLPS | MNT_NOMTAB }, /* Shared */
   { "rshared",     MS_SHARED | MS_REC,     MNT_NOHLPS | MNT_NOMTAB },
#endif
#ifdef MS_NOSYMFOLLOW
   { "symfollow", MS_NOSYMFOLLOW, MNT_INVERT }, /* Don't follow symlinks */
   { "nosymfollow", MS_NOSYMFOLLOW },
#endif
#ifdef MS_MOVE
   { "move",	MS_MOVE,	MNT_NOHLPS | MNT_NOMTAB | MNT_NOFSTAB }, /* --move */
#endif
   { NULL, 0, 0 }
};

/*
 * userspace mount option (built-in MNT_USERSPACE_MAP)
 */
static const struct libmnt_optmap userspace_opts_map[] =
{
   { "defaults", 0, MNT_NOHLPS },      /* default options */

   { "auto",    MNT_MS_NOAUTO, MNT_NOHLPS | MNT_INVERT | MNT_NOMTAB },  /* Can be mounted using -a */
   { "noauto",  MNT_MS_NOAUTO, MNT_NOHLPS | MNT_NOMTAB },  /* Can only be mounted explicitly */

   { "user[=]", MNT_MS_USER },                             /* Allow ordinary user to mount (mtab) */
   { "nouser",  MNT_MS_USER, MNT_INVERT | MNT_NOMTAB },    /* Forbid ordinary user to mount */

   { "users",   MNT_MS_USERS, MNT_NOMTAB },                /* Allow ordinary users to mount */
   { "nousers", MNT_MS_USERS, MNT_INVERT | MNT_NOMTAB },   /* Forbid ordinary users to mount */

   { "owner",   MNT_MS_OWNER, MNT_NOMTAB },                /* Let the owner of the device mount */
   { "noowner", MNT_MS_OWNER, MNT_INVERT | MNT_NOMTAB },   /* Device owner has no special privs */

   { "group",   MNT_MS_GROUP, MNT_NOMTAB },                /* Let the group of the device mount */
   { "nogroup", MNT_MS_GROUP, MNT_INVERT | MNT_NOMTAB },   /* Device group has no special privs */

   /*
    * Note that traditional init scripts assume the _netdev option in /etc/mtab to
    * umount network block devices on shutdown.
    */
   { "_netdev", MNT_MS_NETDEV },                           /* Device requires network */

   { "comment=", MNT_MS_COMMENT, MNT_NOHLPS | MNT_NOMTAB },/* fstab comment only */

   { "x-",      MNT_MS_XCOMMENT,   MNT_NOHLPS | MNT_PREFIX },              /* persistent comments (utab) */
   { "X-",      MNT_MS_XFSTABCOMM, MNT_NOHLPS | MNT_NOMTAB | MNT_PREFIX }, /* fstab only comments */

   { "loop[=]", MNT_MS_LOOP, MNT_NOHLPS },                             /* use the loop device */
   { "offset=", MNT_MS_OFFSET, MNT_NOHLPS | MNT_NOMTAB },		   /* loop device offset */
   { "sizelimit=", MNT_MS_SIZELIMIT, MNT_NOHLPS | MNT_NOMTAB },	   /* loop device size limit */
   { "encryption=", MNT_MS_ENCRYPTION, MNT_NOHLPS | MNT_NOMTAB },	   /* loop device encryption */

   { "nofail",  MNT_MS_NOFAIL, MNT_NOMTAB },               /* Do not fail if ENOENT on dev */

   { "uhelper=", MNT_MS_UHELPER },			   /* /sbin/umount.<helper> */

   { "helper=", MNT_MS_HELPER },			   /* /sbin/mount.<helper> */

   { "verity.hashdevice=", MNT_MS_HASH_DEVICE, MNT_NOHLPS | MNT_NOMTAB },     /* mount a verity device */
   { "verity.roothash=",   MNT_MS_ROOT_HASH, MNT_NOHLPS | MNT_NOMTAB },		   /* verity device root hash */
   { "verity.hashoffset=", MNT_MS_HASH_OFFSET, MNT_NOHLPS | MNT_NOMTAB },	   /* verity device hash offset */
   { "verity.roothashfile=", MNT_MS_ROOT_HASH_FILE, MNT_NOHLPS | MNT_NOMTAB },/* verity device root hash (read from file) */
   { "verity.fecdevice=",   MNT_MS_FEC_DEVICE, MNT_NOHLPS | MNT_NOMTAB },		/* verity FEC device */
   { "verity.fecoffset=", MNT_MS_FEC_OFFSET, MNT_NOHLPS | MNT_NOMTAB },	      /* verity FEC area offset */
   { "verity.fecroots=", MNT_MS_FEC_ROOTS, MNT_NOHLPS | MNT_NOMTAB },	      /* verity FEC roots */
   { "verity.roothashsig=",    MNT_MS_ROOT_HASH_SIG, MNT_NOHLPS | MNT_NOMTAB },	/* verity device root hash signature file */
   { "verity.oncorruption=",   MNT_MS_VERITY_ON_CORRUPTION, MNT_NOHLPS | MNT_NOMTAB },	/* verity: action the kernel takes on corruption */

   { NULL, 0, 0 }
};

/**
 * mnt_get_builtin_map:
 * @id: map id -- MNT_LINUX_MAP or MNT_USERSPACE_MAP
 *
 * MNT_LINUX_MAP - Linux kernel fs-independent mount options
 *                 (usually MS_* flags, see linux/fs.h)
 *
 * MNT_USERSPACE_MAP - userspace mount(8) specific mount options
 *                     (e.g user=, _netdev, ...)
 *
 * Returns: static built-in libmount map.
 */
const struct libmnt_optmap *mnt_get_builtin_optmap(int id)
{
	assert(id);

	if (id == MNT_LINUX_MAP)
		return linux_flags_map;
	if (id == MNT_USERSPACE_MAP)
		return userspace_opts_map;
	return NULL;
}

/*
 * Looks up the @name in @maps and returns a map and in @mapent
 * returns the map entry
 */
const struct libmnt_optmap *mnt_optmap_get_entry(
				struct libmnt_optmap const **maps,
				int nmaps,
				const char *name,
				size_t namelen,
				const struct libmnt_optmap **mapent)
{
	int i;

	assert(maps);
	assert(nmaps);
	assert(name);
	assert(namelen);

	if (mapent)
		*mapent = NULL;

	for (i = 0; i < nmaps; i++) {
		const struct libmnt_optmap *map = maps[i];
		const struct libmnt_optmap *ent;
		const char *p;

		for (ent = map; ent && ent->name; ent++) {
			if (ent->mask & MNT_PREFIX) {
				if (startswith(name, ent->name)) {
					if (mapent)
						*mapent = ent;
					return map;
				}
				continue;
			}
			if (strncmp(ent->name, name, namelen) != 0)
				continue;
			p = ent->name + namelen;
			if (*p == '\0' || *p == '=' || *p == '[') {
				if (mapent)
					*mapent = ent;
				return map;
			}
		}
	}
	return NULL;
}

⇧「mtime」の変更を無効化するような「マウント」の「オプション」は見当たらない...

ちなみに、

blog.goo.ne.jp

atimeはアクセスされた日でFinderでそのファイルが入ったフォルダにアクセスするだけで更新されます。これはサムネイルを作るためにアクセスしちゃっているということでしょう(とはいえキャッシュされるのか、Finderで一旦そのフォルダを閉じてまた開いた程度では更新されないみたい)。
mtimeはModification Dateと同じでファイルをなんかのアプリで開いて上書き保存すればこの日時が更新される、と。
ctimeはInode情報が更新されたときに書き換わるものらしく、ファイルを別のストレージにコピーしたときにbtimeやmtimeは変わらないけど、これは変更されてます。

ファイルのアクセス日時の表示 - 日々適当

以上を踏まえてParallels Desktop上で動くUbuntumacOSのFinderからドラッグ&ドロップでjpgファイルをコピーした時、コピー先のファイルの情報は
atime:macOSが保持していたatimeの値と同じ
mtime:macOSが保持していたatimeの値と同じ
ctime:ファイルがコピーされた日時
となっておりました。mtimeはそっちの日付が複製されんのかよwって思いました。

ファイルのアクセス日時の表示 - 日々適当

⇧ とあり、「更新日時(mtime)」については、罠が多そう...

ネットの情報を漁っていたところ、

github.com

⇧ とあり、「Docker」でも「更新日時(mtime)」のissueが上がっており、2015年のissueなのだが、2025年の時点でも未だにクローズされていない...

 

そもそも、「更新日時(mtime)」を変更することなく、ファイルの内容を変えることができるのか?

unix.stackexchange.com

⇧ できるらしい。

へぇ~、「atime」の更新が無効になっている「マウント」の「オプション」が機能している場合は、「捏造」し放題ってことかね...

まぁ、

qiita.com

システム上に存在する個人情報の扱いが厳しくなった昨今、そこにセンシティブなデータがあるなら、「いつ・だれが・なにを・どうした・どうなった」という記録を取り、不正なアクセスがなかったかを監査しなければいけない、というセキュリティ要件が一般的になっている。
というわけで、Linux標準機能(audit)を使用したファイルアクセス監査の設定と、レポート出力(加工)の覚書。

RHELのAudit設定(ファイルアクセス監査) #Linux - Qiita

⇧「Red Hat」系の「Linuxディストリビューション」であれば、「audit」で「ファイル」への「アクセス」を追跡できるらしいですが...

 

By the way、

qiita.com

find -mtime は POSIX で標準化されていますが互換性がありません。find -mtime nfind -mtime +nfind -mtime -n の範囲が環境によって違うのを知っていますか? find -mtime を使うシェルスクリプトは違う OS に持っていったら正しく動かないでしょう。

【find -mtimeに移植性はない】Unix標準コマンドを使ってる限り、どこでも動くシェルスクリプトなんて書けるわけねーだろ #Linux - Qiita

⇧ 上記サイト様によりますと、「シェルスクリプト」は「環境」による挙動の違いを排除するのが難しそうですね...

とは言え、「シェルスクリプト」を利用せざるを得ない時が往々にしてあるのが辛いところですな…

そして、

amano41.hatenablog.jp

⇧ 上記サイト様によりますと、

デフォルトでは ls -l で表示されるタイムスタンプは以下のようになります。 直近 6 ヵ月以内のファイルは月日時分表示,それ以外は過去のファイルも未来のファイルも年月日表示です。

とありますが、このあたりの情報の出典が気になりますな...

www.gnu.org

10.1.5 Formatting file timestamps

A timestamp is considered to be recent if it is less than six months old, and is not dated in the future. If a timestamp dated today is not listed in recent form, the timestamp is in the future, which means you probably have clock skew problems which may break programs like make that rely on file timestamps. See File timestamps.

https://www.gnu.org/software/coreutils/manual/html_node/Formatting-file-timestamps.html

⇧ このあたりの情報が似てそうではあるが...

 

結局のところ、Linux環境において「更新日時(mtime)」が変わらないようにすることが実現できるということは分かったのだが、自分の携わっているシステムにおいて、どういう仕組みで「更新日時(mtime)」が変わらないように実現しているのかが分からない...

「更新日時(mtime)」が変わらないように実現しているのは、携わっているシステム固有の仕様な気がするのでドキュメント化しておいて欲しいお気持ち...

毎度モヤモヤ感が半端ない…

今回はこのへんで。