2

The existing question how to run a user script after systemd wakeup? already has answers that allow running scripts after wakeup from sleep. However, the solutions provided to that question require hardcoding user.

How to create a script that is automatically run by all currently logged graphical desktop sessions? (That is, when fast user switching / "Switch Account" is used to have multiple desktops in parallel on different virtual terminals, the script should be run with each user with correct environment variable values for DISPLAY and XAUTHORITY.)

I'm personally using lightdm for creating new sessions / logging back to existing session but I'd prefer display manager independent solution.

  • On resume enumerate X.org logged in users and run whatever you need for them. – Artem S. Tashkinov Sep 05 '22 at 15:56
  • @ArtemS.Tashkinov if you add a high-level description of how to do that evaluation (eg parse the output of the "w" or "who" command), I'd say your comment should be the answer. – Phil Hudson Sep 05 '22 at 16:48

1 Answers1

2

On resume you could enumerate logged in X.org users and run whatever you need for them. There are many solutions of how to get the list of currently logged in users but most of them are outdated and may not work in modern Linux distros, including: w, who and last, e.g. w and who return nothing on my Fedora 36 machine. last shows the last reboot:

last | head -1
reboot   system boot  5.19.4-az2       Sun Sep  4 01:56   still running

You can use them if they work for you.

Here's a contemporary method which must work as of September, 2022 (time stamping answers for Linux is always a good idea):

$ loginctl --no-legend list-sessions # or run it without any parameters
SESSION  UID USER   SEAT  TTY 
      2 1000 birdie seat0 tty7

Or gdbus if you're into programming:

$ gdbus call --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1 --method org.freedesktop.login1.Manager.ListSessions
([('2', uint32 1000, 'birdie', 'seat0', objectpath '/org/freedesktop/login1/session/_32')],)

Let's continue working with loginctl. You may need to know Xorg displays for the users, here's how you can do that:

#! /bin/bash

for session in loginctl --no-legend list-sessions | awk '{print $1}'; do echo -e "ID\tName\tDisplay" eval loginctl show-session $session | egrep '^Display|^User|^Name' echo -e "$User\t$Name\t$Display" done

output

ID Name Display 1000 birdie :0

Instead of the echo statement you can run what you need, e.g.

    export XAUTHORITY="`getent passwd $Name | cut -f6 -d:`/.Xauthority"
    export DISPLAY=$Display
    command
  • Great answer! To avoid grepping, you could do something like export DISPLAY="$(loginctl show-session $SESSIONID --value --property Display)" – Mikko Rantalainen Sep 06 '22 at 09:52
  • That eval statement exports three variables in a single command, so I thought it would be neat. – Artem S. Tashkinov Sep 06 '22 at 09:54
  • As this code is going to run as root if I'm understanding correctly, I'd avoid using eval for anything that can be affected by non-root users even in theory. If you're sure that all the output of loginctl show-session is trusted and cannot be afffected by the normal users, eval works fine here. – Mikko Rantalainen Sep 06 '22 at 09:57
  • 1
    All these three variables are not controlled by the user but assigned to them, so I wouldn't worry. – Artem S. Tashkinov Sep 06 '22 at 10:11