You are not logged in.

#1 2015-02-13 00:13:33

cfr
Member
From: Cymru
Registered: 2011-11-27
Posts: 7,131

[60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

I have a script which posts desktop notifications. It can be used from a terminal emulator but it is primarily designed to work from scripts run as cron jobs (or otherwise running in the background). For example, I have a script which checks for system updates and then sends a notification if any packages are out of date.

Originally, I had this set up so that it did one thing in a KDE session and another otherwise. The magic lines were:

# ref.: http://unix.stackexchange.com/questions/28463/run-a-dbus-program-in-crontab-how-to-know-about-the-session-id

ksession_pid=$(ps -o pid= -C 'kwin -session' | sed 's/ //g')

if [ "$ksession_pid" = "" ]
then
        dbus_session_file=~/.dbus/session-bus/$(cat /var/lib/dbus/machine-id)-0
        if [ -e "$dbus_session_file" ]
        then
                . "$dbus_session_file"
                [ $? == 0 ] || ((allan++))
                export DBUS_SESSION_BUS_ADDRESS DBUS_SESSION_BUS_PID
        else
                error "Gwall! Allwn i ddim canfod $dbus_session_file."
        fi
else
        dbus_session_address=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$ksession_pid/environ | sed 's/^DBUS_SESSION_BUS_ADDRESS=//')
        [ "$dbus_session_address" != "" ] || error "Could not get DBUS_SESSION_BUS_ADDRESS for session." 
        export DBUS_SESSION_BUS_ADDRESS="$dbus_session_address"
fi

However, this no longer works since I "upgraded" to Plasma 5. I tried simply removing the KDE stuff and relying on the DBUS information, but this failed.

notify-send works from a terminal emulator, but the setting of DBUS_SESSION_BUS_ADDRESS is not the same as the one written to ~/.dbus/session-bus/$(cat /var/lib/dbus/machine-id)-0.

I then tried setting up a DBUS socket as if for use by systemd in a user session using the instructions in the wiki. This gives me a socket at /run/user/1000/dbus/user_bus_socket= but setting DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/dbus/user_bus_socket is apparently not the right thing to do. If I do this in a new shell, I break my ability to send notifications from the command line. I think this tells me two things:


1. Getting DBUS_SESSION_BUS_ADDRESS right is the key to getting this working, since setting it wrongly stops notifications with no other changes to the environment.

2. I have no idea how this environmental variable is getting set or how to figure out what it is from a cron job.

How can I recover the correct value from a cron job?

Last edited by cfr (2015-02-13 03:19:25)


CLI Paste | How To Ask Questions

Arch Linux | x86_64 | GPT | EFI boot | refind | stub loader | systemd | LVM2 on LUKS
Lenovo x270 | Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz | Intel Wireless 8265/8275 | US keyboard w/ Euro | 512G NVMe INTEL SSDPEKKF512G7L

Offline

#2 2015-02-13 00:28:35

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

I used the same U&L answer for a similar script, only I don't use KDE.

if [[ $? -eq 0 ]]; then
	pids=$(pgrep dwm)
	for p in $pids; do
    	dbus=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$p/environ \
			| sed 's/DBUS_SESSION_BUS_ADDRESS=//')
    	user=$(grep -z USER /proc/$p/environ | sed 's/USER=//')
    	dply=$(grep -z DISPLAY /proc/$p/environ | sed 's/DISPLAY=//')

		icon="/usr/share/icons/elementary/status/48/aptdaemon-upgrade.svg"
		title="Sync Complete"
		body="Music transferred to Apollo…"

    	sudo -u $user sh -c "DBUS_SESSION_BUS_ADDRESS=\"$dbus\" DISPLAY=\"$dply\" \
			/usr/bin/notify-send -t 3000 -i \"$icon\" \"$title\" \"$body\""
	done
fi

Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#3 2015-02-13 00:45:03

progandy
Member
Registered: 2012-05-17
Posts: 5,184

Re: [60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

What is the value of your $DISPLAY? That should be part of the filename in ~/.dbus/session-bus/, too. Can you find your DBUS_SESION_BUS_ADDRESS in one of the files there?


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#4 2015-02-13 01:16:06

cfr
Member
From: Cymru
Registered: 2011-11-27
Posts: 7,131

Re: [60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

I figured out that kwin is now kwin_x11, so I tried something else. However, the next post uses jasonwryan's method to get the PID and is much better, so please see below. [I should have edited this, but I'm afraid I didn't think of it until it was too late.]

Last edited by cfr (2015-02-13 02:36:41)


CLI Paste | How To Ask Questions

Arch Linux | x86_64 | GPT | EFI boot | refind | stub loader | systemd | LVM2 on LUKS
Lenovo x270 | Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz | Intel Wireless 8265/8275 | US keyboard w/ Euro | 512G NVMe INTEL SSDPEKKF512G7L

Offline

#5 2015-02-13 02:34:56

cfr
Member
From: Cymru
Registered: 2011-11-27
Posts: 7,131

Re: [60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

Thank you!

jasonwryan wrote:
    	dply=$(grep -z DISPLAY /proc/$p/environ | sed 's/DISPLAY=//')

This, I think, is what I needed. Thank you.

I was using

export DISPLAY=:0

which always worked. Moreover, it matches the value I find in the environment in a terminal emulator. However, the value in the environ file is different and it seems that is the value I need.

The following seems to work in a minimal test:

ksession_pid=$(pgrep kwin)

if [ "$ksession_pid" = "" ]
then
        dbus_session_file=~/.dbus/session-bus/$(cat /var/lib/dbus/machine-id)-0
        if [ -e "$dbus_session_file" ]
        then
                . "$dbus_session_file"
                [ $? == 0 ] || ((allan++))
                export DBUS_SESSION_BUS_ADDRESS DBUS_SESSION_BUS_PID
                export DISPLAY=:0
        else
                error "Gwall! Allwn i ddim canfod $dbus_session_file."
        fi
else
        dbus_session_address=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$ksession_pid/environ | sed 's/^DBUS_SESSION_BUS_ADDRESS=//')
        display=$(grep -z DISPLAY /proc/$ksession_pid/environ | sed 's/^DISPLAY=//')
        [ "$dbus_session_address" != "" ] || error "Could not get DBUS_SESSION_BUS_ADDRESS for session." 
        [ "$display" != "" ] || error "Could not get DISPLAY for session." 
        export DBUS_SESSION_BUS_ADDRESS="$dbus_session_address"
        export DISPLAY="$display"
fi

I doubt that the first part is completely correct. In particular, I suppose the DISPLAY is wrong. However, in practice, it is usually the second part which I need, so this solves the main part of the problem. But I'd be interested to know if there is a way to get the DISPLAY in the first case. (Should it be taken from the name of the dbus_session_file?)

Also, I'm not sure, but I think jasonwryan's answer might solve another issue which I've not managed to resolve since switching from OS X!

EDIT: Alas, not. I can't get it to work at all if I add the user specification. However, at least the script now works as well as it did before I upgraded to KDE 5!

Last edited by cfr (2015-02-13 03:18:37)


CLI Paste | How To Ask Questions

Arch Linux | x86_64 | GPT | EFI boot | refind | stub loader | systemd | LVM2 on LUKS
Lenovo x270 | Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz | Intel Wireless 8265/8275 | US keyboard w/ Euro | 512G NVMe INTEL SSDPEKKF512G7L

Offline

#6 2015-02-13 02:40:15

cfr
Member
From: Cymru
Registered: 2011-11-27
Posts: 7,131

Re: [60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

progandy wrote:

What is the value of your $DISPLAY? That should be part of the filename in ~/.dbus/session-bus/, too. Can you find your DBUS_SESION_BUS_ADDRESS in one of the files there?

Yes. That is the -0 bit. And I have export DISPLAY=:0 in the file. However, the value of DBUS_SESSION_BUS_ADDRESS in this file is not correct for KDE as it is not equal to the value in the environ file.

I am not sure why the DISPLAY is 0 in a terminal emulator and notifications work, but 02 in the environ file and notifications require it. I assumed that the value of DISPLAY would be the same in both cases, and I don't understand how one value can enable notifications in one case and the other be needed for notifications in the other case.

EDIT: OK. I know why it is set to 0 in the terminal. It is because I set it in .bashrc. But I'm not sure why, in that case, notifications work there!

EDIT 2: It seems DISPLAY is not necessary for it to work from the terminal but only from the cron script. I don't know why.

Last edited by cfr (2015-02-13 02:46:39)


CLI Paste | How To Ask Questions

Arch Linux | x86_64 | GPT | EFI boot | refind | stub loader | systemd | LVM2 on LUKS
Lenovo x270 | Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz | Intel Wireless 8265/8275 | US keyboard w/ Euro | 512G NVMe INTEL SSDPEKKF512G7L

Offline

#7 2015-02-13 03:42:24

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

Setting it in .bashrc is a bad idea; overwriting any of those variables is.

Cron doesn't know anything about your environment, the more you tell it, the happier it is...
I set my script up that way because it runs on my desktop which I share with my wife; often she will log in before me and claim :0 (that's also why I have notify-send on that box, she is an Openbox user so dzen2 isn't much good to her smile ).


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#8 2015-02-13 12:45:25

cfr
Member
From: Cymru
Registered: 2011-11-27
Posts: 7,131

Re: [60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

jasonwryan wrote:

Setting it in .bashrc is a bad idea; overwriting any of those variables is.

Yes. My .bashrc has an unfortunately ancient pedigree and includes things which I used to need to set but which would be better not set now. It is just a question of figuring out which things they are...

Cron doesn't know anything about your environment, the more you tell it, the happier it is...
I set my script up that way because it runs on my desktop which I share with my wife; often she will log in before me and claim :0 (that's also why I have notify-send on that box, she is an Openbox user so dzen2 isn't much good to her smile ).

It works fine as long as I don't use the

sudo -u $user

bit. If I use that, it fails.

I've never successfully run a notification from a cron job run by root. I've only ever got it to work for cron jobs run from my user crontab. Do you get notifications for system cron jobs as well?


CLI Paste | How To Ask Questions

Arch Linux | x86_64 | GPT | EFI boot | refind | stub loader | systemd | LVM2 on LUKS
Lenovo x270 | Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz | Intel Wireless 8265/8275 | US keyboard w/ Euro | 512G NVMe INTEL SSDPEKKF512G7L

Offline

#9 2015-02-13 18:22:31

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [60% SOLVED] Getting DBUS_SESSION_BUS_ADDRESS correct in cronie script

No, I only setup notifications for my $user crontabs...


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

Board footer

Powered by FluxBB