Zsh
Linux
UNIX
ログ
研究

zshで実行したコマンドのログを残す

シェルをzshに移行したので、zshでのコマンドログの取り方をメモ。
How to save command logs on zsh.

logging.zsh
#!/bin/zsh

export HISTFILE=~/.zhistory  # fc on line 8 won't run without it
DATE=`date +%F`
YESTERDAY=`date +%F -d '1 days ago'`
TIME=`date +%F_%T_%N`
fc -R  # also necessary for line 8, not sure how
fc -l -D -t "%F_%T" 0 >> ~/log/zraw/"$TIME"  # -D for time elapsed for each command, 0 to obtain the entire list

# just to prevent the error not being able to find these files
touch ~/log/zdaily/"$DATE"
touch ~/log/zdaily/"$YESTERDAY"

# using awk to extract today's entries
cat ~/log/zdaily/"$DATE" ~/log/zraw/"$TIME" | awk '$2 ~ /'"${DATE}"'/' | sort -k 2 | uniq > ~/log/zdaily/"$DATE"

# also have to extract yesterday's entries, because there can be some commands yet to be logged, no matter how often you run this script.
cat ~/log/zdaily/"$YESTERDAY" ~/log/zraw/"$TIME" | awk '$2 ~ /'"${YESTERDAY}"'/' | sort -k 2 | uniq > ~/log/zdaily/"$YESTERDAY"
  1. このスクリプトをどこかに保存する(ここでは~/logging.zshとする) / The zsh script above somewhere (~/logging.zsh for the purpose of this post)
  2. chmod u+a ~/logging.zshで実行可能にする。 / execute chmod u+a ~/logging.zsh So that the script can run.
  3. mkdir ~/log/zraw/ ~/log/zdailyを実行して保存先のディレクトリを作成しておく。 / Execute mkdir ~/log/zraw/ ~/log/zdaily to prepare the log directories.
  4. 0 23 * * * zsh -l -c '~/logging.zsh'という内容を適当にmycronとでもファイル名をつけて保存。この例では毎日23:00に実行される。スケジュールを変えたい場合はcrontabの書き方を調べて変更。何回実行してもlog/zrawにデータが重複して溜まる以外には問題ない。 / Save 0 23 * * * zsh -l -c '~/logging.zsh' as mycron (can be any filename though). It runs at 23:00 every day in this example. Check how to write crontab to change the schedule. You can run it as often as you like as long as you're fine with somewhat duplicated date in log/zraw
  5. crontab mycronとしてcronにジョブを取り込む。このとき、すでにcronに入っているジョブは上書きされて消えるので注意。cron -lで確認できる。 / Execute crontab mycron to import the job to cron. Keep in mind that pre-existing jobs (hit cron -l to check) in cron will be overwritten

このスクリプトを実行するたびのコマンド履歴が丸ごと~/log/zraw/に保存され、毎日その日の分だけを取り出したものが~/log/zdaily/に保存される。上の手順で示したようにcronで実行することを推奨。.zlogoutに書いておくような方法だとログインしない限り保存されないが、このスクリプトの~/log/zdaily/への日ごとの保存が取りこぼしを起こさないためには最低毎日一回は実行される必要がある。
The entire command history is saved in ~/log/zraw/ every time you execute this script, and each day's records are separately saved in ~/log/zdaily/. Using cron is preferable to run it to other ways such as using .zlogout, because you must run this script at least once a day to save daily logs in ~/log/zdaily/, which isn't guaranteed if you just run when you log out.

References
https://superuser.com/questions/527299/how-to-call-history-fc-from-a-zsh-script
http://qiita.com/takc923/items/8409a76e8a660f9f329f
http://d.hatena.ne.jp/ozuma/20120711/1342014448
http://qiita.com/jmatsu/items/0a5d80abe188b09644c1
https://stackoverflow.com/questions/15374752/get-yesterdays-date-in-bash-on-linux-dst-safe