
ブロック デバイスの変更アクションにバインドされ、指定されたスクリプトを実行する既存の udev ルールを移行しています。
SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", RUN+="/usr/local/bin/script"
ID_CDROM_MEDIA-0
この構成では、 udev は、やなどのハードウェア デバイスに関連付けられた環境変数を渡しましたID_FS_LABEL
。その後、ハードウェアの変更時に systemd を使用してサービスを開始するように udev ルールを更新しました。
SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", TAG+="systemd", ENV{SYSTEMD_WANTS}=="drive-change.service"
systemd サービス ファイル:
[Unit]
Description=changes to dvd drive
[Service]
Type=oneshot
ExecStart=/usr/local/bin/script
[Install]
WantedBy=multi-user.target
この時点では、サービスは変更イベント時に実行されますが、udev の RUN コマンドによって渡される環境変数はサービスの実行に渡されません。
udev から systemd の実行環境に環境を渡すことは可能ですか、それとも明示的にパラメータを渡す必要がありますか?
答え1
udevからsystemdに環境を渡す方法は見つかりませんでしたが、udevデータベースで環境プロパティを照会することは可能です。udevadm info
指示には、環境プロパティのみを照会し、評価可能な形式で出力できる パラメータ--query
とパラメータの両方があります。--export
systemd インスタンス変数とコマンドの組み合わせを使用して、udevadm
環境変数を初期化しました。
SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", TAG+="systemd", ENV{SYSTEMD_WANTS}=="drive-change@%E{DEVNAME}.service"
この udev ルールは、次のサービス ファイルを実行し、DEVNAME
変数をインスタンス変数としてサービスに渡します。
[Unit]
Description=changes to dvd drive
[Service]
Type=oneshot
ExecStart=/usr/local/bin/script %I
[Install]
WantedBy=multi-user.target
このインスタンス変数を使用して udev 要素の環境プロパティを評価し、問題を解決しました。
#!/bin/sh
# Systemd passes the DEVNAME as the first parameter to the script
eval $(udevadm info --query=env --export $1)
# The rest of the script that depends on the udev environment
...
答え2
偉大な答え@Ben Campbell による投稿。
デバイスが udev ルールをトリガーした後に、udev 環境データベースからプロパティにアクセスする方法は次のとおりです。たとえば、USB ドライブが接続されたばかりで、そのラベルを取得したいとします。
systemd サービスによって実行されるスクリプトで、eval $(udevadm info --query=env --export $1)
行の後に次のような内容を追加します。
echo $ID_FS_LABEL >> "/tmp/file.txt"
ID_PART_ENTRY_UUID
同様に、などの値を取得することもできますID_VENDOR
。