You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:31:16