问题
I have user service running shell script, which is trying to access lockscreen state of my session like this:
# Test Unity screen-lock:
isLocked() {
isLocked=$(gdbus call -e -d com.canonical.Unity -o /com/canonical/Unity/Session -m com.canonical.Unity.Session.IsLocked)
}
lock() {
if [[ $isLocked == "(false,)" ]]; then
gnome-screensaver-command -l
elif [[ $isLocked == "(true,)" ]]; then
exit 1
fi
exit 0
}
The problem is service “is a per-user process, and not per-session”, and I don't know how to access session dbus:
GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name com.canonical.Unity was not provided by any .service files
回答1:
I was facing this same problem, and my research turned up nothing. If someone can find a better way to query the lock status of Unity, I'd love to hear about it.
I recently learned about named pipes, and at the time I wondered what I might use such a thing for. This problem, it turns out, happens to be a perfect application.
Create the following script...
#!/bin/bash
# this script is meant to be called in two different ways.
# 1. It can be called as a service by passing "service" as the first argument. In this
# mode, the script listens for requests for lock screen status. The script should be
# run in this mode with startup applications on user logon.
# 2. If this script is called without any arguments, it will call the service to request
# the current lock screen status. Call this script in this manner from your user
# service.
# this will be the named pipe we'll use for requesting and receiving screen lock status
pipe="/tmp/lockscreen-status"
if [ "$1" == "service" ]; then
# setup the named pipe
rm "$pipe"
mkfifo "$pipe"
# start watching for requests
while true
do
# watch the pipe for trigger events requesting lock screen status
read request < "$pipe"
# respond across the same pipe wit the current lock screen status
gdbus call -e -d com.canonical.Unity -o /com/canonical/Unity/Session -m com.canonical.Unity.Session.IsLocked | grep -oP "(true)|(false)" > "$pipe"
done
else
# make sure the pipe exists
if [ ! -e "$pipe" ]; then
echo "This script must started in service mode before lock status can be queried."
exit
fi
# send a request for screen lock status and read the response
touch "$pipe"
read status < "$pipe"
[ "$status" == "" ] && status="This script must started in service mode before lock status can be queried."
# print reponse to screen for use by calling application
echo $status
fi
As noted in the comments, you need to call this script in two ways. When your user logs on, start this script in service mode. I use the "Startup Applications" program to call the script, but it doesn't really matter how it's called so long as its called by your user account on login. Then from within your user service, simply make a call to this script and it will return "true" if the screen is locked or "false" if the screen is unlocked.
来源:https://stackoverflow.com/questions/38623791/how-to-access-session-d-bus-from-systemd-user-service