Linuxサーバからログアウトしたタイミングで処理を実行させる方法(例えばメールを飛ばす)

Bash, CentOS, Linux, Ubuntu

職場の踏み台サーバを経由してオペレーションを実行すると、オペレーションログが1ファイル作成されます。
このファイルのフルパスをログアウトごとに記録しておく必要があったのだが面倒なので自動化してみました。

前提

  1. ログファイルは以下のフォルダに配置される。
    • /var/log/script
  2. ファイル名にはログインユーザ名が付与されている。
  3. ファイル名にはタイムスタンプがが付与されている。

具体的には以下のようなファイル形式となる

/var/log/script/genzouw_20190125_082914.log

検証環境

$ bash -version
GNU bash, バージョン 4.2.46(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <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.

ログアウトタイミングに処理を実行させるための方法

Bashtrapコマンド を使って実現しました。

trapコマンドとは?

Bash Guide for Begnners からの引用 ( Traps )

原文

There might be situations when you don’t want users of your scripts to exit untimely using keyboard abort sequences, for example because input has to be provided or cleanup has to be done. The trap statement catches these sequences and can be programmed to execute a list of commands upon catching those signals.

翻訳

たとえば、入力を提供する必要がある場合やクリーンアップを実行する必要がある場合など、スクリプトのユーザーがキーボードアボートシーケンスを使用して早急に終了したくない場合があります。 trapステートメントはこれらのシーケンスを捕捉し、それらのシグナルを捕捉したときにコマンドのリストを実行するようにプログラムすることができます。

さっぱりわかりませんね。

自分なりに解釈すると実行中のプロセスが発する シグナル というものを検知して処理を実行させるように仕掛けるコマンド。
イベントトリガーのイメージなんですね。

インタラクティブシェルはexitのタイミングで EXIT というシグナルを発するようなので、これを使ってメールを飛ばすようにしてみます。

設定

.bashrc 読み込み時に以下のような trap を仕掛けます。

$ vi ~/.bashrc

これを貼り付ける。

if [[ "$(id -gn)" = "dc_development" ]]; then
  trap '
  {
    echo "Subject: Your operation log file";
    echo "";
    echo "----------------------------------------";
    find /var/log/script/ -type f -name "*$(date +%Y%m%d)*" | grep "${USER}" | sort -r | head -n 1;
    echo "----------------------------------------";
  } | sendmail genzouw@gmail.com
  ' EXIT
fi

EXIT シグナルが送信されるタイミング

sshで接続した後、 exit コマンドを叩いてログアウトしたタイミングで実行されます。

では、 ネットワーク不調や自分のPCの不調で突然接続が切れてしまった場合 にはどうなるか?

試してみたところ上記のケースでもメールが送信されたので、 EXIT シグナルが発生しているようですね。

Bash, CentOS, Linux, Ubuntu