$0 FILE
- FILEは /dev/stdout が指定可能である。
引数で与えられたファイルFILE(何かのログファイルを想定)に、次のような行を末尾に付加する。
1. その時点の日時を表す文字列。たとえば「=== 2022-02-03 14:55+09:00(wed)」。
2. そのファイルFILEの末尾の2行が、このプログラム$0が追加したと判断される場合には、
そのファイルFILEの末尾の1行のみを、その時点の日時を表す文字列で置き換える。
上記のようにプログラム$0を反復実行させることで(cron等を用いる)、
何かのログファイルであるFILEは次の様になり、どの時点で書き込まれたのか分かり安くなる。
- LOGFILEに別のプログラムの実行結果が随時書き込まれているとする。
- 毎分 cronで $0 LOGFILE を実行しているとする。
- すると、随時LOGFILEに書き込まれた各行L1の1行前L0と1行後L2に、cronにより起動された$0が
日時情報を書き込まれているので、L1の書込日時は、L0とL2に書かれた2個の日時の間だと判明する。
オプション:
-a : 上記の2.の判断をして実行をすることはせず、単純に日時文字列を書き足す。
-b STR : 日時情報の先頭に付加する文字列。指定無しの場合は「=== 」の4文字。
-d 0 : 日時情報の内、日付を出さない。日付より下の時刻情報のみになる。
-s : 日時情報を秒単位にする。このオプションが無い場合は、分単位。
-w 0 : 曜日を出力しない。
-z 0 : 時差情報(例 +09:00) を出力しない。
内部動作のメモ :
+ このプログラムが多重起動された場合も想定して、ファイルロックを掛ける。ファイルロックを
検出したら、0.25秒間待つ。
+ 最後の2行を読み出すときに、その直前にバイトが無いか、改行文字であるか検査しても良いかも
しれないが、アルゴリズムが少し複雑化することになるので、実装していない。
+ 最後の2行の文字列の検査は、簡便である。バイト数と文字列の先頭の一致とコロンの存在のみしか
調べていない。従って、偶然または巧妙なしかけによって、意図しない(このプログラムが想定しない)
動作をさせることが可能である。(従って、-aというオプションを作った。)
開発上のメモ:
* ログファイルであるから、他のプロセスも同じファイルに同時に書込みをする可能性があるので、
それによって起こされる弊害を最小化する必要がある。
* このプログラムが追記する日時を表す文字列は、32バイトなどと決めた長さで書き込むようにする。
* このことで、上記の動作2.において、置き換える場合に、同時書込の不都合が起きなくなる。
* このブログラム自体を複数個起動しても問題無いように、関数flockを使う。
* その場合、lockが1秒以内に解除されない場合に、返り値を非正常にして、終了する。
* 標準入力から入力を受け取った場合、その入力の文字列の先頭に、日時文字列を追加することはできないか?