株式会社オズビジョンのユッコ (@terra_yucco) です。
今日は業務内で同僚のシェアしてくれた find コマンドが感動的だったのでついつい記事にしてしまいました。
find
is so powerful!!
TL;DR
find [starting-point...] -newerXY reference
Premise
vagrant@homestead:~$ find --version
find (GNU findutils) 4.7.0-git
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2)
今までは
find
に -newer
があるのは知っており、これを使って「より新しいファイル」「より古いファイル」などを探すことはよくやっていました。
ただし皆様ご存知のように -newer
は man にもあるように1、比較対象はあくまでファイルです。なので、このようにやっていました。
touch -t 201905051213.30 /tmp/baseline
find /path -type f -newer /tmp/baseline
rm -f /tmp/baseline
比較用の /tmp/baseline
ファイルを時間指定で作成し、そのファイルとの比較で find -newer
を使用し、終わってから削除するという流れです。
-newerXY
があれば
find /path -type f -newermt "2019-05-05 12:13:30"
なんてシンプル!
-newerXY
の X
と Y
せっかくなので、この神オプション (個人的) について man をベースに調べてみました。
-newerXY reference
Succeeds if timestamp X of the file being considered is newer than timestamp Y of the file reference.
X
のタイムスタンプが参照したファイルの Y
のタイムスタンプより新しいと考えられる場合に成功する。
The letters X and Y can be any of the following letters:
- a The access time of the file reference
- B The birth time of the file reference
- c The inode status change time of reference
- m The modification time of the file reference
- t reference is interpreted directly as a time
X
と Y
に使えるのは以下の文字
letter | 意味 |
---|---|
a | 参照されたファイルのアクセス時間 |
B | 参照されたファイルの生成時間 |
c | 参照先の i-node 状態が変化した時間 |
m | 参照されたファイルの更新時間 |
t | 参照先を直接時間として解釈する |
Some combinations are invalid; for example, it is invalid for X to be t. Some combinations are not implemented on all systems;
for example B is not supported on all systems. If an invalid or unsupported combination of XY is specified, a fatal error results. Time specifications are interpreted as for the argument to the -d option of GNU date. If you try to use the birth time of a reference file, and the birth time cannot be determined, a fatal error message results. If you specify a test which refers to the birth time of files being examined, this test will fail for any files where the birth time is unknown.
組み合わせによっては不正になる。例えば X
に t
は指定できない。
組み合わせによっては特定のシステムで動かないことがある。例えば B
は全てのシステムでサポートされているわけではない。
もし不正、もしくはサポートされていない XY
の組み合わせが指定された場合、致命的なエラーが発生する。
時間を指定した場合は GNU date に -d
で渡した引数と同じように解釈される。
もし生成時間を参照しようとして、それが定義されていない場合は、致命的エラーのメッセージが出力される。ファイルの生成時間を検証しようとした場合、生成時間が不明なファイルに対してはその検証は失敗する。
エンジニアとしては気になる不等号
-newer
= より新しい なので、おそらく等しい場合は合致しないと予想しましたが、念のために検証しました。
まずファイル作成して
$ vagrant@homestead:~$ touch -t 201905051213.30 /tmp/baseline
vagrant@homestead:~$ stat /tmp/baseline
File: /tmp/baseline
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 1449540 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ vagrant) Gid: ( 1000/ vagrant)
Access: 2019-05-05 12:13:30.000000000 +0000
Modify: 2019-05-05 12:13:30.000000000 +0000
Change: 2019-05-30 11:41:32.741698485 +0000
Birth: -
同じ日時で検証。
合致しませんでした。
vagrant@homestead:~$ find /tmp/ -newermt "2019-05-05 12:13:30"
vagrant@homestead:~$
次に 1s 前を指定。
合致しました!
vagrant@homestead:~$ find /tmp/ -type f -newermt "2019-05-05 12:13:29"
/tmp/baseline
vagrant@homestead:~$
ちなみに、同じ日時を否定してあげると、きちんと合致しました。
vagrant@homestead:~$ find /tmp/ -type f ! -newermt "2019-05-05 12:13:30"
/tmp/baseline
vagrant@homestead:~$
vagrant@homestead:~$ find /tmp/ -type f -not -newermt "2019-05-05 12:13:30"
/tmp/baseline
vagrant@homestead:~$
-
[referred files] -newer [base]
は[referred files] > [base]
-
[referred files] ! -newer [base]
は[referred files] <= [base]
Birth の存在しないファイル
検証に touch で作成したファイルが stat で参照したら Birth: -
となっていますので、せっかくなので man 記載の内容を試してみました。
vagrant@homestead:/tmp$ find /tmp/ -type f -newerBt "2019-05-05 12:13:30"
find: This system does not provide a way to find the birth time of a file.
find: invalid predicate `-newerBt'
vagrant@homestead:/tmp$ echo $?
1
こんな感じになりました。話のネタにしかなりませんが。
※ちなみにここで立ち上げているのは Homestead の Vagrant です。
Conclusion
今日のまとめとしては find
コマンドめっちゃ便利という点です。
前にいた現場は HP-UX だったので、そもそも GNU の恩恵を受けられず、今の現場に来て最初に感動したのは date -d
だったのも覚えています。
膨大なオプションのうち -newerXY
しか紹介できなかったので、折に触れて他もまた触れ、使いこなしていきたいと思います。
-
-newer file
: File was modified more recently thanfile
. If file is a symbolic link and the-H
option or the-L
option is in effect, the modification time of the file it points to is always used.-newer file
: ファイルがfile
より最近に変更されたかを示す。ファイルがシンボリックリンクで-H
オプションもしくは-L
オプションが効果的な場合は、リンク先のファイルの更新日時が参照される。 ↩