
我正在遷移綁定到區塊設備的更改操作並運行給定腳本的現有 udev 規則。
SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", RUN+="/usr/local/bin/script"
在此配置中,udev 傳遞了與硬體設備關聯的環境變量,例如ID_CDROM_MEDIA-0
和ID_FS_LABEL
。此後,我更新了 udev 規則,以使用 systemd 在硬體變更時啟動服務。
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
為了延續偉大回答通過@本·坎貝爾..
以下是裝置觸發 udev 規則後如何從 udev 環境資料庫存取屬性。例如,假設剛剛連接了一個 USB 驅動器,並且您想要取得其標籤。
在 systemd 服務運行的腳本中,在該eval $(udevadm info --query=env --export $1)
行後面新增以下內容:
echo $ID_FS_LABEL >> "/tmp/file.txt"
ID_PART_ENTRY_UUID
同樣,您可以獲得ID_VENDOR
等的值。