为何zenity无法在udev脚本中弹出USB设备授权确认窗口?
USB设备插入时Zenity确认窗口不弹出的问题排查与解决
现有配置
udev规则文件(80-block-usb.rules)
ACTION=="add", SUBSYSTEMS=="usb", RUN+="/usr/local/bin/usb-check.sh $env{DEVPATH}"
配套脚本(/usr/local/bin/usb-check.sh)
#!/bin/bash devpath="$1" name="$2" export DISPLAY=:1 echo $devpath /bin/sh -c 'echo 0 > /sys'${devpath}'/authorized' zenity --question --text='Do you want to authorize "'$name'"?' && /bin/sh -c 'echo 1 > /sys'${devpath}'/authorized'
插入USB设备时,设备未自动授权符合预期,但Zenity确认窗口始终不弹出,核心原因及解决办法如下:
核心问题分析
- DISPLAY与权限隔离:udev运行在无桌面的后台环境,硬编码
DISPLAY=:1不一定匹配当前用户的桌面会话,且udev进程没有访问X服务器的权限,需要同时指定XAUTHORITY环境变量。 - 参数缺失:udev规则仅传递了
DEVPATH作为第一个参数,但脚本中用到的$name(第二个参数)为空,不仅会导致弹窗文本异常,还可能干扰脚本逻辑。 - 脚本语法错误:原脚本中
echo $devpath /bin/sh -c 'echo 0 > /sys'${devpath}'/authorized'只是打印字符串,并未实际执行禁用设备的命令。 - 会话隔离:udev以root身份运行,直接调用Zenity无法在当前登录用户的桌面会话中显示窗口,必须切换到用户身份执行。
修正后的配置
1. 更新udev规则(80-block-usb.rules)
添加设备产品名称参数,并避免重复触发:
ACTION=="add", SUBSYSTEM=="usb", ATTR{authorized}=="1", RUN+="/usr/local/bin/usb-check.sh $env{DEVPATH} $attr{product}"
2. 修正后的脚本(/usr/local/bin/usb-check.sh)
#!/bin/bash devpath="$1" device_name="$2" # 先禁用USB设备 echo 0 > "/sys${devpath}/authorized" # 获取当前登录桌面的用户信息 USER=$(who | grep '(:0)' | awk '{print $1}' | head -n1) USER_HOME=$(getent passwd "$USER" | cut -d: -f6) # 设置桌面环境变量 export DISPLAY=:0 export XAUTHORITY="${USER_HOME}/.Xauthority" # 切换到登录用户执行Zenity弹窗 su - "$USER" -c "zenity --question --text='是否授权USB设备:\"${device_name}\"?' --width=300" # 根据用户选择决定是否授权设备 if [ $? -eq 0 ]; then echo 1 > "/sys${devpath}/authorized" fi
3. 配置脚本权限
确保脚本可执行:
sudo chmod +x /usr/local/bin/usb-check.sh
4. 重载udev规则
sudo udevadm control --reload-rules sudo udevadm trigger
内容的提问来源于stack exchange,提问作者Golden Melky
相关产品推荐
相关产品推荐

