Hello.
env var RUNLEVEL seems not to be defined with systemd.
Systemctl status runlevel3.target show “loaded” in graphical.target (runlevel 5) and in runlevel3.target (runlevel 3)
Same thing with multi-user.target.
“Runlevels” are an obsolete way to start and stop groups of services used in SysV init. systemd provides a compatibility layer that maps runlevels to targets, and associated binaries like runlevel. Nevertheless, only one runlevel can be “active” at a given time, while systemd can activate multiple targets concurrently, so the mapping to runlevels is confusing and only approximate. Runlevels should not be used in new code, and are mostly useful as a shorthand way to refer the matching systemd targets in kernel boot parameters.
> echo $RUNLEVEL
> echo $PREVLEVEL
> runlevel
Der absolute Pfad für 'runlevel' ist '/sbin/runlevel', daher kann das Programm möglicherweise nur von Benutzern mit Superuser-Rechten gestartet werden (z. B. root).
>
Sorry – “LANG=C” doesn’t help – you’ll have to live with the German …
runlevel prints the previous and current SysV runlevel if they are known.
Which is not what the OP asked for. He asked
to know if the system booted in text mode ( old runlevel 3 ) or in graphical mode ( old runlevel 5 ).
But runlevel does not show that, but what it is. And of course things could have changed several times since the boot was done.
And of course (I quote the man page again):
“Runlevels” are an obsolete way to start and stop groups of services used in SysV init. systemd provides a compatibility layer that maps runlevels to targets, and associated binaries like runlevel.
I would say that using runlevels is not really future-proof.
who -r displays record in utmp. Under systemd this record is filled in by systemd service that runs on boot and basically is equivalent to “it is run-level 5 is graphical.target is being activated else it is run-level 3 if multi-user.target is being activated else it is run-level 1 if rescue.target is being activated”. As long as you ignore booting into custom unit (using systemd.unit option) where runlevel is not defined at all it is probably the most usable option under systemd currently.
systemctl get-default
graphical.target
default.target link may change after boot; it does not answer “what unit system has been booted into”. systemd does not preserve this information. It is actually trivial to add if someone can present valid use case when this information is necessary.
It does not even show “what unit system has been booted into” when default.target link is not changed. It is only a default.
It is the target the system will boot into when nothing contrary is specified. You can e.g. use Grub to specify what target the system should boot into. That does not change the default. After that you can change the default, but that does not change the target in use at all. And when you change the target (systemctl isolate …) 10 times after boot? (May there is some logging to see which target the system was was booted in some months ago).
A Linux system always boots to text mode (multi-user.target) before optionally continuing to load a DE (graphical.target).
And, Linux systems are multi-user (unlike Windows) so I’m guessing you should actually be querying whether the default display is actively used and maybe test for a function of that running DE.
But,
I’m guessing that there is not even a purpose to this whole exercise.
Why should you even care if a person is logged in interactively or not? Do you intend to display something to the User, If so there are ways to send a notification to every active display on the machine which would render your wanting to know a person is logged in and running a graphical DE moot.
The way I look at this is that what you’re asking for doesn’t conform with how a Linux system works…
Apart from malcolmlewis’s only response, is there any systemd guru to find a solution with systemd.
It is good to comment on the questions asked, but it is still better to answer them.
Please be clear on “type” – as in “integer” or “string” …
[HR][/HR]For the RUNLEVEL solution, one should declare the variable RUNLEVEL to be an integer and, possibly, after the assignment of the value, make it read-only:
[HR][/HR]For the case of “systemd-only”, unfortunately, systemd has at any point in time, several targets active in parallel …
systemctl list-units --type target --state active
N.B.: In Bash, a name has to be word consisting only of alphanumeric characters and underscores, and beginning with an alphabetic character or an underscore.
The variable used to store the current active target of interest has to be of type “string” – use “declare” to make sure of this …