touchコマンドの本来の使い方
この記事はImaizumi Lab Advent Calendarの24日目です。
はじめに
空のファイルを作るときに「touch hogehoge」とやりますよね。
本当はファイルのタイムスタンプを変更するためのコマンドというのは結構知られていると思いますが、じゃあどういう使い方ができるの? ということでまとめていきたいと思います。
ファイルのタイムスタンプは3種類ある
ここでちょっと遠回りして、ファイルのタイムスタンプについて解説します。
UNIX系システムのファイルのタイムスタンプには「atime」「mtime」「ctime」の3種類が存在します。*1
atimeはファイルの最終アクセス日時、mtimeはファイルの最終更新日時、ctimeはinodeが更新された日時です。inodeとは、ファイルのアクセス権や実データの場所などの属性情報のことです。
これらはstatコマンドで確認することができます。(以下、コマンドの実行例は全てUbuntuでのものです。statの出力は省略しています。MacOSだとstat -xで似たような表示になります)
$ stat a Access: 2020-12-25 01:25:27.354297000 +0000 Modify: 2020-12-25 01:25:27.354297000 +0000 Change: 2020-12-25 01:25:27.354297000 +0000
例えば「echo "aaaa" > a」で中身を編集すると、
$ stat a Access: 2020-12-25 01:25:27.354297000 +0000 Modify: 2020-12-25 01:25:27.354297000 +0000 Change: 2020-12-25 01:25:27.354297000 +0000 $ echo "aaaa" > a $ stat a Access: 2020-12-25 01:25:27.354297000 +0000 Modify: 2020-12-25 01:26:32.174235000 +0000 Change: 2020-12-25 01:26:32.174235000 +0000
のようにmtimeとctimeが更新されます。
「cat a」とすると、atimeのみが更新されます。
$ stat a Access: 2020-12-25 01:25:27.354297000 +0000 Modify: 2020-12-25 01:26:32.174235000 +0000 Change: 2020-12-25 01:26:32.174235000 +0000 $ cat a $ stat a Access: 2020-12-25 01:27:59.621939000 +0000 Modify: 2020-12-25 01:26:32.174235000 +0000 Change: 2020-12-25 01:26:32.174235000 +0000
「vi a」でファイルの中身を更新すると、3つとも全て更新されます。
$ stat a Access: 2020-12-25 01:27:59.621939000 +0000 Modify: 2020-12-25 01:26:32.174235000 +0000 Change: 2020-12-25 01:26:32.174235000 +0000 $ vi a $ stat a Access: 2020-12-25 01:29:46.577553000 +0000 Modify: 2020-12-25 01:29:46.577553000 +0000 Change: 2020-12-25 01:29:46.579553000 +0000
使ってみる
はじめに以下のようなファイルがあるとします。
$ ls -l -rw-r--r-- 1 root root 6 Dec 25 01:31 a -rw-r--r-- 1 root root 0 Dec 25 01:31 b -rw-r--r-- 1 root root 0 Dec 25 01:31 c $ stat a Access: 2020-12-25 01:31:52.187919000 +0000 Modify: 2020-12-25 01:31:52.187919000 +0000 Change: 2020-12-25 01:31:52.187919000 +0000
オプションなし
「touch a」とするとaのatime、ctime、mtimeが書き換わります。
$ stat a Access: 2020-12-25 01:31:52.187919000 +0000 Modify: 2020-12-25 01:31:52.187919000 +0000 Change: 2020-12-25 01:31:52.187919000 +0000 $ touch a $ stat a Access: 2020-12-25 04:13:09.531173000 +0000 Modify: 2020-12-25 04:13:09.531173000 +0000 Change: 2020-12-25 04:13:09.531173000 +0000
rオプション
「touch -r a b」とすることで、aのタイムスタンプがbのタイムスタンプになります。
$ touch -r a b $ ls -l -rw-r--r-- 1 root root 6 Dec 25 04:13 a -rw-r--r-- 1 root root 0 Dec 25 04:13 b -rw-r--r-- 1 root root 0 Dec 25 01:31 c
このオプションの使い道として、配布するソフトウェアの中身のタイムスタンプを揃えるとかがあるようです。
tオプション、dオプション
任意の時刻にタイムスタンプ(atime、mtime)を指定することができます。
$ touch -t 01011111 a $ stat a Access: 2020-01-01 11:11:00.000000000 +0000 Modify: 2020-01-01 11:11:00.000000000 +0000 Change: 2020-12-25 04:50:34.724411000 +0000 $ touch -d "2020-1-2 22:22" a $ stat a Access: 2020-01-02 22:22:00.000000000 +0000 Modify: 2020-01-02 22:22:00.000000000 +0000 Change: 2020-12-25 04:52:03.686661000 +0000
aオプション
atimeとctimeを変更することができます。
$ stat a Access: 2020-01-02 22:22:00.000000000 +0000 Modify: 2020-01-02 22:22:00.000000000 +0000 Change: 2020-12-25 04:52:03.686661000 +0000 $ touch -a a $ stat a Access: 2020-12-25 04:55:19.327739000 +0000 Modify: 2020-01-02 22:22:00.000000000 +0000 Change: 2020-12-25 04:55:19.327739000 +0000
mオプション
mtimeとctimeを変更することができます。
$ stat a Access: 2020-12-25 04:55:19.327739000 +0000 Modify: 2020-01-02 22:22:00.000000000 +0000 Change: 2020-12-25 04:55:19.327739000 +0000 $ touch -m a $ stat a Access: 2020-12-25 04:55:19.327739000 +0000 Modify: 2020-12-25 04:56:21.502631000 +0000 Change: 2020-12-25 04:56:21.502631000 +0000
余談:Macでのタイムスタンプの挙動が変
この記事を書くにあたってMacOSで最初試していたのですが、「cat a」したときにaのatimeが更新されるはずが更新されないという事象に遭遇してしまいました。
ディスクの書き込みを軽減させる目的でatimeの更新を無効化することがあるそうですが、調べた感じだと明示的に設定しないと有効にならないようなので、今回の場合は違うようです。
何かわかったらまた記事にしたいと思います。
*1:この他にもあるケースもありますが、本稿では取り扱いません