USBメモリをパソコンに刺して、バックアップをしたりデータを取り込んだりと定期的に行っている操作があると思います。Linuxには、udev というデバイス管理ツールがあります。新しいデバイスがコンピュータに接続もしくは接続解除された時のルールを事前に定義できるので、USBメモリを刺しただけで、事前に用意したスクリプトを実行することができます。もっとも簡単な記述方法は以下のとおりです。/dev/sd*[0-9] にUSBメモリが接続(add)、解除(remove) された時にadd_script.sh, rm_script.sh が実行されるというものです。
$ sudo nano /etc/udev/rules.d/99-usb.rules
/etc/udev/rules.d/99-usb.rules
KERNEL=="sd*[0-9]*", SUBSYSTEMS=="usb",ACTION=="add",RUN+="add_script.sh"
KERNEL=="sd*[0-9]*", SUBSYSTEMS=="usb",ACTION=="remove",RUN+="rm_script.sh"
しかしこれでは、どんなUSBメモリを刺しても同じ動きをしてしまいます。特定のUSBメモリを刺した時、特定の動きをする設定方法を紹介したいと思います。USBメモリには、パーティションを切ったり、フォーマットした時に固有のUUIDが割当られます。
USBメモリを刺した時、UbuntuはUSBメモリを自動マウントしてくれます。dfコマンドを実行すると USBメモリは /dev/sdb1 に割り当てられて、/media/$USER/UUIDにマウントされた事がわかります。
$ df
:
/dev/sdb1 3996640 16 3996624 1% /media/taro/182C-57AE
詳細はudevadmコマンドを使用して以下のように参照すると ID_FS_UUID を使用してマウントポイントが自動で作成された事がわかります。
$ udevadm info --name=/dev/sdb1|grep UUID
E: ID_PART_TABLE_UUID=5cbd03f8-2226-4ab1-b42a-634391deb0f1
E: ID_FS_UUID=182C-57AE
E: ID_FS_UUID_ENC=182C-57AE
E: ID_PART_ENTRY_UUID=324453cc-92df-0844-b59d-d79b1b19cbb9
この値をキーに、ID_FS_UUIDが”182C-57AE”のUSBが差し込まれた時だけ、add_script.sh にパラメータ ID_FS_UUIDが渡されて実行されるという設定を記述することができます。
/etc/udev/rules.d/99-usb.rules
KERNEL=="sd*[0-9]*", SUBSYSTEMS=="usb",ENV{ID_FS_UUID}=="182C-57AE",ACTION=="add",RUN+="/usr/local/bin/add_script.sh $env{ID_FS_UUID} $kernel"
↓ パターンにマッチすれば良いので以下だけでも良いですし、以下だけであれば、SDカードでも同様の方法でスクリプトを動かすことができます。
ENV{ID_FS_UUID}=="182C-57AE",ACTION=="add",RUN+="/usr/local/bin/add_script.sh $env{ID_FS_UUID} $kernel"
$env には、デバイス・プロパティ、$kernelはデバイスのカーネル名の値が入っており、その他用意されている変数については man udev を参照して利用して下さい。
スクリプトは以下のようになります。USB挿入時UbuntuはUSBメモリを自動マウントしてくれますが、設定ファイルに記述したスクリプトが動くタイミングはマウントされる前なのでスクリプト内でマウントします。実際スクリプトが動作したかは分からないのでnotify-send ‘タイトル’ ‘メッセージ’ コマンドで完了通知をディスクトップに表示します。
/usr/local/bin/add_script.sh
#!/bin/bash
#区切り文字を改行にする
IFS=$'\n'
# パラメータでUUIDを取得する
UUID=$1
# パラメータでデバイス名を取得する
DEVNAME=$2
# 実行するユーザ名
NAME="taro"
# ディレクトリを作成する
if [ ! -d /media/${NAME}/${UUID}/ ]; then
mkdir -p /media/${NAME}/${UUID}/
fi
# マウントします。
mount /dev/$DEVNAME /media/${NAME}/${UUID}/
# USB 内にあるファイルをコピーします。
cd /media/${NAME}/${UUID}/
for file in `ls *.[Pp][Nn][Gg] *.[Jj][Pp][Gg] *.[Jj][Pp][Ee][Gg] 2>/dev/null`
do
cp -a "${file}" "/home/${NAME}/ピクチャ/${file}"
chown ${NAME}:${NAME} "/home/${NAME}/ピクチャ/${file}"
done
# ディスクトップに完了を通知します
export DISPLAY=:0
su ${NAME} -c "notify-send '自動マウント' '画像ファイルをコピーしました。'"