当我连接特定的外部驱动器时,我希望zenity
弹出一个对话框询问我是否要运行备份。
不幸的是,我对 UDEV 规则语法有疑问。我有以下规则/etc/udev/rules.d/test.rules
:
ACTION=="add", ATTRS{manufacturer}=="Western Digital", ATTRS{idVendor}=="1058", ATTRS{idProduct}=="1140", RUN+="/usr/local/bin/test.sh"
这是非常基础的,但是:
- 它会触发十几次,而不是一次。
zenity
它无法使用whentest.sh
goes 来“说话”,sudo -Hu <username> zenity --warning --text="Just some random text for now."
因为 udev 隐藏在系统中并且找不到窗口管理器:Gtk-警告**:无法打开显示:- 它不太适合编辑,我希望有某种规则,我只需输入我想要触发某些脚本的某些分区的标签即可。
我希望看到 UDEV 规则的全面改进,因为除了关于它的许多问题和答案之外,这里和其他地方,它们似乎都有点不同,并且大多数都会触发多次。
但最重要的是,我怎样才能从这里连接到我家里的脚本,该脚本可以访问我的会话和屏幕等内容,以便zenity
可以工作?
答案1
您已经找到答案了。脚本 (zenity) 需要 X Window Server 来显示消息。脚本从中运行udev
,但没有附加显示。您可以通过DISPLAY
在脚本中硬连线变量来解决这个问题,即
DISPLAY=:0; export DISPLAY
缺点是,只有当您是唯一的用户和/或提前知道显示内容时,它才有效。如果您的系统上有多个用户,则显示内容可能是其他内容,例如:1
,:2
等等。或者其他用户会在其屏幕上看到 zenity 消息。
更好的方法是将事件的检测与与用户的交互或消息的显示分开。
为此,您可以创建一个脚本或程序,它在您的 GUI 会话中运行并监听来自守护进程或 udev 触发脚本的触发器。
第三种可能性是udisks-daemon
当外部设备插入时,连接到并询问信息。您可以尝试udisks --monitor
或者udisks --monitor-detail
每当事件发生时,解析输出。
似乎有一个udisksctl
命令,它的功能相同,只是语法略有不同。也许它只是udisks
命令的较新版本。
你也可以看看一些 Gui 工具,比如GNOME 磁盘,它们也依赖于 udev/udisks 系统。
更新:
多次调用通常来自各个子系统的报告。您可以看到,当您将环境记录到脚本中的某个日志文件/usr/local/bin/test.sh
时
umask 077
mkdir -p /tmp/udevtest.d
env >>/tmp/udevtest.d/udevtest.log
当我插入 USB 时,我收到以下报告
$ grep -e ACTION -e SUBSYSTEM /tmp/udevtest.d/udevtest.log
ACTION=add
SUBSYSTEM=usb
ACTION=add
SUBSYSTEM=usb
ACTION=add
SUBSYSTEM=scsi
ACTION=add
SUBSYSTEM=scsi_host
ACTION=add
SUBSYSTEM=scsi
ACTION=add
SUBSYSTEM=scsi
ACTION=add
SUBSYSTEM=scsi_disk
ACTION=add
SUBSYSTEM=scsi_generic
ACTION=add
SUBSYSTEM=scsi_device
ACTION=add
SUBSYSTEM=bsg
ACTION=add
SUBSYSTEM=block
ACTION=add
SUBSYSTEM=block
您还可以添加DEVTYPE
以区分两个usb
或disk
报告。因此,为了将报告减少到只有几个甚至只有一个调用,您必须更加具体并在 udev 规则文件中添加其他条件,例如选择SUBSYSTEM=scsi_disk
或任何适合您的设备的内容。
答案2
对于其他读到这篇文章的人来说,我能够让脚本在 Kali Linux 2016 中运行的唯一方法是这样的:
#!/bin/bash
set -x
xhost local:root
export DISPLAY=:0.0
su root -c 'zenity --notification --text="I am a notification!"'