USBにドライブが接続されたら自動的にバックアップを作成したい
目的
USB 接続のディスクドライブにバックアップを作成するシェルスクリプトbackup.sh
があります。USB にディスクドライブが接続されたら、このスクリプトを自動的に実行するようにしてバックアップの手間を減らしたい。
環境
- OS
- Ubuntu 16.04
解決策
方針
Ubuntu 16.04 を含む最近の Linux は、デバイスの管理にudev
を使用しています。そのため適当な rule ファイルを作成すると、デバイスが接続されたり取り外された時に決まったプログラムを実行させることができます。
そこでudev
にドライブが USB に接続されたらバックアップ用のシェルスクリプトbackup.sh
を実行するルールを作成します。
ただしudev
のルールから起動できるプログラムは、短時間で終了する必要があります。バックアップなど終了までに時間がかかるプログラムを実行させようとすると、途中で強制的に終了させられてしまいます。
この制限を回避するために、バックアプをsystemd
のサービスとして、udev
からはそのサービスを開始するようにします。
systemd サービス
まずバックアップを作成するサービスを定義します。
/etc/systemd/system/backup.service
[Unit]
Description=Backup to Removable USB Drive
[Service]
Type=simple
ExecStart=/root/bin/backup.sh
サービスを定義したら次のコマンドでsystemd
に登録します。
# systemctl daemon-reload
# systemctl status backup
* backup.service
Loaded: not-found (Reason: No such file or directory)
Active: inactive (dead)
なおsystemd
から起動されたプログラムの標準出力は、syslog に記録されると同時にsystemctl status SERVICE_NAME
で確認できます。
udev ルール
サービスを登録したら、そのサービスを起動するルールを作成します。
/etc/udev/rules.d/91-backup.rules
ACTION=="add",ENV{ID_BUS}=="ata",ENV{ID_PART_ENTRY_UUID}=="xxxx-xxxx-xxxx-xxxx",RUN+="/bin/systemctl --no-block start backup.service"
デバイスを識別するENV
には、udev
が認識している値を設定します。認識している値は、udevadm info --name=XXX
コマンドで取得できます。
ルールを作成したら、次のコマンドでudev
にルールを登録します。
# udevadm control --reload
これでxxxx-xxxx-xxxx-xxxx
という UUID を持つディスクパーティションがata
に接続されたらbackup.service
が起動されます。
参照と脚注
- Script run from udev rule gets killed shortly after startl
- How to run long time process on Udev event? – Unix & Linux
- 終了までに時間がかかるプログラムを
udev
から起動すると途中で強制終了させられる問題を回避するためにバックグラウンドで処理させるようにしても終了させられてしまいます。この問題は、setsid コマンドでセッション ID を変えて、自分がセッションリーダーとなれば終了させられないという記述を見たことがあります。