如何在用户点击GUI关机按钮时触发系统通知?附polkit关机锁定场景
Great work getting the polkit-based shutdown lock working with U盘 detection! Since you're stuck on adding a GUI notification when the user tries to shut down with a U盘 plugged in (and polkit 0.105 doesn't support JS rules), here's a practical approach using dbus monitoring and desktop notifications that plays nicely with your existing setup.
Core Idea
We'll add a background script that listens for system shutdown requests, checks if a U盘 is connected, and pops up a desktop notification explaining why the shutdown was blocked. We'll tie this script to your existing U盘 insertion/removal workflow so it only runs when needed.
Step 1: Create the Notification & Shutdown Listener Script
Create a script (e.g., shutdown-block-notify.sh) that monitors shutdown events and sends notifications. This runs in the background as root, but we'll ensure notifications show up in the user's desktop session.
#!/bin/bash # Customize this function to match how you detect connected U盘 has_connected_usb() { # Example: Check for removable block devices (adjust to your U盘 detection logic) lsblk -no rm,type | grep -q "1 removable" } # Listen for the system's "Prepare for Shutdown" signal via dbus dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Manager',member='PrepareForShutdown'" | while read -r line; do # Trigger only when the system starts preparing to shut down if echo "$line" | grep -q "true"; then if has_connected_usb; then # Get the active desktop user (adjust if you have multiple users) ACTIVE_USER=$(who | grep -E "(tty1|pts/0)" | awk '{print $1}' | head -n1) # Fetch the user's DBus session address (required to send notifications from root) DBUS_SESSION_ADDR=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u "$ACTIVE_USER" -l | grep -E "(session|desktop)" | head -n1 | awk '{print $1}')/environ | cut -d= -f2-) # Send the critical notification to the user's desktop su - "$ACTIVE_USER" -c "DBUS_SESSION_BUS_ADDRESS='$DBUS_SESSION_ADDR' notify-send -u critical 'Shutdown Blocked' 'Please remove your U盘 before shutting down the system.'" fi fi done
Make the script executable:
chmod +x /path/to/shutdown-block-notify.sh
Step 2: Update Your U盘 Insert/Remove Scripts
Modify your existing scripts that handle U盘 insertion and removal to start/stop the listener:
U盘 Insert Script (e.g., usb-insert.sh)
#!/bin/bash # Your existing polkit rule copy cp /path/to/your/shutdown-block.pkla /etc/polkit-1/localauthority/50-local.d/ # Start the notification listener if it's not already running if ! pgrep -f "shutdown-block-notify.sh" > /dev/null; then /path/to/shutdown-block-notify.sh & fi
U盘 Remove Script (e.g., usb-remove.sh)
#!/bin/bash # Your existing polkit rule removal rm /etc/polkit-1/localauthority/50-local.d/shutdown-block.pkla # Stop the notification listener pkill -f "shutdown-block-notify.sh"
Step 3: Verify Udev Rules (If Needed)
Ensure your udev rules correctly trigger the insert/remove scripts. Example rule file (/etc/udev/rules.d/99-usb-shutdown-block.rules):
ACTION=="add", SUBSYSTEM=="block", ENV{ID_BUS}=="usb", RUN+="/path/to/usb-insert.sh" ACTION=="remove", SUBSYSTEM=="block", ENV{ID_BUS}=="usb", RUN+="/path/to/usb-remove.sh"
Reload udev rules to apply changes:
udevadm control --reload-rules
Key Notes
- U盘 Detection: Adjust the
has_connected_usb()function to match your setup (e.g., check for a specific mount point, device name, or udev property). - Desktop Compatibility: The script uses a generic way to find the user's session process. If targeting a specific DE (like GNOME/KDE), replace the session process lookup with
gnome-sessionorplasma-desktopfor reliability. - Permissions: The script runs as root via udev, so we use
suto switch to the active user and pass their DBus session address—this ensures notifications appear in their desktop, not the root session.
Testing
- Plug in your U盘
- Click the desktop shutdown button
- You should see a critical notification explaining the shutdown is blocked, along with the system's default polkit permission prompt (if applicable)
内容的提问来源于stack exchange,提问作者AlmuHS

