You use gdbus directly to send notifications
gdbus call \
--session \
--dest org.freedesktop.Notifications \
--object-path /org/freedesktop/Notifications \
--method org.freedesktop.Notifications.Notify \
"App_name" 0 "audio-headphones" "Title" "Message" '[]' '{}' 5000 \
| sed -E 's/.uint32 ([0-9]+).*/\1/' \
| xargs -I{notification_id} sh -c 'sleep 1 && gdbus call \
--session \
--dest org.freedesktop.Notifications \
--object-path /org/freedesktop/Notifications \
--method org.freedesktop.Notifications.CloseNotification {notification_id}'I also made this function that additionally allows to update the notification, and the timer for forced closing will be refreshed
notify() {
local app_name="$1"
local title="$2"
local message="$3"
local duration="$4"
local notification_file="/tmp/${app_name}_notification_id"
local timer_file="/tmp/${app_name}_timer_pid"
# Read existing notification_id if available
local notification_id=0
[ -f "$notification_file" ] && notification_id=$(cat "$notification_file")
# Cancel previous timer if it exists
if [ -f "$timer_file" ]; then
kill $(cat "$timer_file") 2>/dev/null
rm "$timer_file"
fi
# Send notification and save new id
new_id=$(gdbus call \
--session \
--dest org.freedesktop.Notifications \
--object-path /org/freedesktop/Notifications \
--method org.freedesktop.Notifications.Notify \
"$app_name" "$notification_id" "audio-headphones" "$title" "$message" '[]' '{}' "$duration" \
| sed -E 's/.uint32 ([0-9]+).*/\1/')
echo "$new_id" > "$notification_file"
# Schedule closing of notification
(
sleep "$duration"
gdbus call \
--session \
--dest org.freedesktop.Notifications \
--object-path /org/freedesktop/Notifications \
--method org.freedesktop.Notifications.CloseNotification "$new_id"
rm "$timer_file"
) &
echo $! > "$timer_file"
}notify "App_name" "Title" "Message" 5000As long as you use the same App_name the notification will be updated.