如何允许通过pkexec以其他用户身份运行notify-send?
解决polkitd身份下以指定用户执行notify-send的Polkit配置方案
我之前踩过一模一样的坑!Polkit默认用polkitd用户运行脚本,确实没法无密码su到普通用户发通知,必须靠自定义Polkit动作来授权。下面是我亲测有效的完整操作步骤:
1. 创建自定义Polkit动作文件
首先得定义一个允许切换用户执行notify-send的动作,新建文件/usr/share/polkit-1/actions/com.yourdomain.notify.policy,把下面内容贴进去(记得把yourdomain换成你自己的标识,比如你的用户名或者项目名):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd"> <policyconfig> <action id="com.yourdomain.notify.execute"> <description>Allow executing notify-send as another user</description> <message>Authentication is required to send a notification as another user</message> <defaults> <allow_any>no</allow_any> <allow_inactive>no</allow_inactive> <allow_active>yes</allow_active> </defaults> <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/notify-send</annotate> <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate> </action> </policyconfig>
解释下关键部分:
<defaults>里的allow_active: yes表示允许当前活跃登录的用户执行这个动作(如果你需要更严格的权限,可以改成指定用户组,比如<allow_active>auth_admin_keep</allow_active>,但这里我们要让polkitd能触发,后面规则会单独授权)org.freedesktop.policykit.exec.path指定了允许执行的程序路径,就是notify-send的位置org.freedesktop.policykit.exec.allow_gui设为true,确保能调用GUI通知服务
2. 编写Polkit规则文件(适配0.106版本)
Polkit 0.106用的是JavaScript规则,新建文件/etc/polkit-1/rules.d/50-notify.rules,内容如下:
polkit.addRule(function(action, subject) { // 匹配我们自定义的动作ID,并且允许polkitd用户执行 if (action.id == "com.yourdomain.notify.execute" && subject.user == "polkitd") { return polkit.Result.YES; } });
这个规则的作用是:当polkitd用户触发com.yourdomain.notify.execute动作时,直接授权通过,不需要密码验证。
3. 编写触发通知的脚本
现在可以写一个脚本,让polkitd调用它来给目标用户发通知。比如新建/usr/local/bin/send-user-notify.sh,内容:
#!/bin/bash # 获取当前活跃的用户(如果有多个用户登录,你可能需要调整这里的逻辑) TARGET_USER=$(w -h | awk '{print $1}' | head -n1) # 获取用户的DISPLAY环境变量(GUI会话需要) DISPLAY=$(w -h | awk '{print $3}' | head -n1) # 获取用户的DBUS会话地址(notify-send依赖这个) DBUS_ADDR=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $TARGET_USER gnome-session)/environ | cut -d= -f2-) # 用pkexec以目标用户身份执行notify-send pkexec --user $TARGET_USER env DISPLAY=$DISPLAY DBUS_SESSION_BUS_ADDRESS=$DBUS_ADDR notify-send "$1" "$2"
给脚本加执行权限:
chmod +x /usr/local/bin/send-user-notify.sh
4. 测试验证
切换到polkitd用户(或者让你的Polkit触发脚本调用这个通知脚本),执行:
su -s /bin/bash polkitd -c "/usr/local/bin/send-user-notify.sh 'Polkit通知测试' '这条通知是polkitd发的!'"
如果一切正常,你应该能在目标用户的桌面看到通知弹窗。
注意事项
- 如果你的桌面环境不是GNOME,替换
pgrep -u $TARGET_USER gnome-session为对应桌面的会话进程,比如KDE的plasma-desktop,XFCE的xfce4-session - 如果需要指定固定用户,直接把
TARGET_USER改成具体的用户名即可,比如TARGET_USER="john"
内容的提问来源于stack exchange,提问作者AlmuHS
相关产品推荐
相关产品推荐

