
When managing Linux systems, there are often scenarios where scripts or commands need to be executed based on the type of user login. For example, you might want certain actions to run only during GUI logins (via a display manager) or SSH logins. One commonly used mechanism for detecting GUI sessions is the XDG_SESSION_TYPE environment variable. In this blog, we will explore how this variable works, its limitations, and how to ensure compatibility with various Linux display managers.
What is XDG_SESSION_TYPE?
XDG_SESSION_TYPE is an environment variable set by the display manager or session manager. It indicates the session type for the logged-in user. The values it typically holds are:
x11: Indicates an X11-based graphical session.wayland: Indicates a Wayland-based graphical session.tty: Indicates a terminal (TTY) session.
This variable is particularly useful for distinguishing between graphical and terminal sessions and is supported by most modern Linux display managers.
Supported Display Managers
Here’s how various popular display managers handle XDG_SESSION_TYPE:
- GDM (GNOME Display Manager):
— Fully supportsXDG_SESSION_TYPE.
— Sets the variable tox11orwaylandbased on the session. - LightDM:
— SupportsXDG_SESSION_TYPEfor most configurations.
— Works well with multiple desktop environments like XFCE and MATE. - SDDM (Simple Desktop Display Manager):
— Modern display manager used with KDE Plasma and LXQt.
— SetsXDG_SESSION_TYPEas expected. - LXDM:
— Limited modern support. While it often setsXDG_SESSION_TYPE, this may not be consistent across all distributions. - XDM (X Display Manager):
— An older display manager. It does not guarantee support forXDG_SESSION_TYPE.
Handling GUI and Non-GUI Logins
If you want to detect and handle logins differently based on the session type, you can use XDG_SESSION_TYPE in your scripts. Below is an example of a script that executes a command for GUI logins and skips terminal (TTY) logins:
#!/bin/bash # Command to run
on valid logins(passed as argument
while running this script) COMMAND= # Check
if the PAM event is
for opening a session [ " $PAM_TYPE " = "open_session" ];
then # Check
if login is a GUI session [[ " $XDG_SESSION_TYPE " == "x11" || " $XDG_SESSION_TYPE " == "wayland" ]];
then # Run the command
for GUI login $COMMAND else echo "Non-GUI session detected. Skipping command." else echo "Skipping
for PAM_TYPE= $PAM_TYPE "
on valid logins(passed as argument
while running this script) COMMAND= # Check
if the PAM event is
for opening a session [ " $PAM_TYPE " = "open_session" ];
then # Check
if login is a GUI session [[ " $XDG_SESSION_TYPE " == "x11" || " $XDG_SESSION_TYPE " == "wayland" ]];
then # Run the command
for GUI login $COMMAND else echo "Non-GUI session detected. Skipping command." else echo "Skipping
for PAM_TYPE= $PAM_TYPE "
Challenges with XDG_SESSION_TYPE
While XDG_SESSION_TYPE is reliable for many setups, there are some limitations:
- Older Display Managers (e.g., XDM):
— XDM does not consistently setXDG_SESSION_TYPE. - Inconsistencies Across Environments:
— For some lightweight display managers like LXDM, the behavior may vary based on distribution-specific configurations. - SSH Logins:
— For SSH sessions,XDG_SESSION_TYPEis either unset or not relevant. You need to rely on other variables, likeSSH_CONNECTION, to identify SSH logins.
Fallback Mechanisms for Better Compatibility
To handle cases where XDG_SESSION_TYPE is not set or behaves inconsistently, consider using fallback mechanisms like DISPLAY or loginctl.
Checking DISPLAY
The DISPLAY variable is typically set during GUI sessions. You can use this as a fallback:
[[ -n " $DISPLAY " ]];
then echo "GUI session detected." else echo "Non-GUI session detected."
then echo "GUI session detected." else echo "Non-GUI session detected."
Using loginctl
The loginctl command can provide detailed session information:
SESSION_TYPE=$(loginctl show-session $(loginctl | grep $PAM_USER | awk '{print $1}' ) -p Type --value) [[ " $SESSION_TYPE " == "x11" || " $SESSION_TYPE " == "wayland" ]];
then echo "GUI session detected."
then echo "GUI session detected."
Handling SSH Logins
SSH logins present a unique case where XDG_SESSION_TYPE may not provide useful information. To specifically handle SSH logins, you can use the SSH_CONNECTION variable, which is set during SSH sessions. For example:
[[ -n " $SSH_CONNECTION " ]];
then echo "SSH session detected." $COMMAND # Run the desired command
for SSH logins else echo "Not an SSH session."
then echo "SSH session detected." $COMMAND # Run the desired command
for SSH logins else echo "Not an SSH session."
Additionally, you can add your script to the PAM configuration file for SSH, typically located at /etc/pam.d/sshd. For instance:
session optional pam_exec.so /path/to/your/script
This ensures the script is executed during SSH login events. Always test your changes in a safe environment to avoid locking yourself out of the system.
Best Practices for Script Execution
- Log PAM Events for Debugging:
— Include logging in your scripts to debug unexpected behavior:echo “$(date): PAM_TYPE=$PAM_TYPE
SESSION_TYPE=$XDG_SESSION_TYPE
SSH_CONNECTION=$SSH_CONNECTION” >> /tmp/script.log - Use Conditional Execution:
— Ensure your script only runs during open_session events to avoid redundant executions. - Test Across Multiple Display Managers and SSH:
— Validate your script in environments with different display managers and SSH configurations to ensure compatibility.
Conclusion
The XDG_SESSION_TYPE variable is a powerful tool for distinguishing between GUI and non-GUI sessions in Linux. While it’s widely supported across modern display managers like GDM, LightDM, and SDDM, older managers like XDM may require fallback mechanisms like DISPLAY or loginctl.
For SSH sessions, relying on the SSH_CONNECTION variable or integrating scripts directly into the /etc/pam.d/sshd configuration file ensures reliable execution. By combining XDG_SESSION_TYPE with robust fallback checks and thorough testing, you can create scripts that adapt seamlessly to various Linux environments.
Connect and Share
If you found this blog helpful, please like, share, and comment below with your thoughts or experiences! I’d love to hear how you handle session-based script execution in your setups. Feel free to connect with me on LinkedIn to discuss further and stay updated with more content like this!



