Set a Reliable Per-User X Session with Xsession
By the end of this guide, your X login can start a chosen desktop or window manager from your own home directory, while keeping the change easy to undo. The Debian Xsession script is the hand-off point used by display managers and, by default, by startx. This guide matches x11-common 1:7.7+23ubuntu3, installed on the machine used for these examples.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 15 minutes. You need an existing X installation, a session command that is already installed, and a shell account with write access to your home directory. The examples do not need root. Do not run /etc/X11/Xsession directly: it expects the environment created by startx, xinit or a display manager.
1. Identify the session command
First find the program you intend to start. Use the command name supplied by your desktop environment or window manager. The check below is harmless; replace the placeholder with a real command such as xfce4-session or i3 only if that command is installed on your system.
$ SESSION_COMMAND='your-session-command'
$ command -v "$SESSION_COMMAND"
/usr/bin/your-session-command
If command -v prints nothing, stop here and choose an installed session program. Xsession searches the session command in $PATH when it is passed as an argument, but a missing command falls back to the normal selection process.
Checkpoint
You have a command path and know whether it needs arguments. Keep the command simple for the first test; add options only after the session starts correctly.
2. Back up any existing user session file
With the default options on this installation, Xsession accepts $HOME/.xsession and then $HOME/.Xsession. It uses the first file it finds. A non-executable file is run through the shell, while an executable file is started directly. Check both names before changing anything.
$ ls -l "$HOME/.xsession" "$HOME/.Xsession" 2>/dev/null || true
If either file exists and contains settings you need, make a dated backup. This changes only your home directory and is reversible.
$ BACKUP="$HOME/.xsession.backup-$(date +%Y%m%d-%H%M%S)"
$ if [ -e "$HOME/.xsession" ]; then cp -a "$HOME/.xsession" "$BACKUP"; fi
$ if [ -e "$HOME/.Xsession" ]; then cp -a "$HOME/.Xsession" "$BACKUP-uppercase"; fi
$ ls -l "$BACKUP"* 2>/dev/null
If you later need to undo the change, remove or rename the new .xsession and restore the appropriate backup. Do this while logged out of the graphical session, or use another terminal login.
3. Create the smallest useful .xsession
Write one command as the final line of $HOME/.xsession. Xsession eventually uses exec for the selected startup program, so the session command should remain in the foreground. Do not append an ampersand: a background command can exit immediately and leave the X session without its controlling process.
$ printf '%s\n' '#!/bin/sh' 'exec your-session-command' > "$HOME/.xsession"
$ chmod 700 "$HOME/.xsession"
$ sed -n '1,5p' "$HOME/.xsession"
#!/bin/sh
exec your-session-command
Replace your-session-command before starting X. The executable bit is not required for a shell script, but it makes the intended behaviour explicit and avoids surprises if the file is later selected by a different launcher.
Security boundary
This file is shell code. It can run commands with your user privileges at every graphical login. Keep it owned by you and writable only by you.
$ stat -c '%U:%G %a %n' "$HOME/.xsession"
your-user:your-group 700 /home/your-user/.xsession
4. Check the file before logging in
Run the shell parser against the file. This checks syntax without launching the session command.
$ sh -n "$HOME/.xsession"
$ printf 'syntax check: ok\n'
syntax check: ok
Also confirm that the command named by the file is executable. This extracts the second field from the deliberately simple example; if your file is more complex, inspect it manually instead of trusting this shortcut.
$ SESSION_COMMAND='your-session-command'
$ command -v "$SESSION_COMMAND" && test -x "$(command -v "$SESSION_COMMAND")"
/usr/bin/your-session-command
Checkpoint
The parser exits successfully, the command exists, and the file permissions do not grant group or other write access.
5. Start the session through its normal launcher
Log out and log in through your display manager, or use startx from a text console if that is how your system starts X. Do not test by invoking Xsession itself. The display manager or xinit supplies the display, authorisation and other session state that the script relies on.
The default startup order is useful when diagnosing a failed login. Xsession first sources valid files in /etc/X11/Xsession.d in run-parts order. It merges system X resources and, when allowed, $HOME/.Xresources. It then considers a requested session, .xsession, .Xsession, and finally the first executable of /usr/bin/x-session-manager, /usr/bin/x-window-manager and /usr/bin/x-terminal-emulator.
6. Inspect the right log after a failure
Xsession sends its standard output and standard error to $HOME/.xsession-errors by default. Read the end of that file after returning to a text console or another login.
$ tail -n 80 "$HOME/.xsession-errors"
Xsession: X session started for ...
The exact lines depend on the desktop and installed packages. Look for the first command-not-found, permission or X connection error rather than only the final message. The script limits this log to its latest 500,000 bytes on this installation, so copy useful diagnostics before repeating a noisy test.
If the home-directory log cannot be opened, the script tries a securely created temporary file and may link it as $TMPDIR/xsession-$USER, using /tmp when TMPDIR is unset. A failure to create any log aborts the session. Check both locations when .xsession-errors is absent.
$ ls -l "$HOME/.xsession-errors" "${TMPDIR:-/tmp}/xsession-$USER" 2>/dev/null || true
7. Recover without guessing
If the graphical login loops, use a text console and move the user file out of the way. This is reversible and does not alter system configuration.
$ mv "$HOME/.xsession" "$HOME/.xsession.disabled"
$ chmod 600 "$HOME/.xsession.disabled"
$ printf 'custom session disabled; original saved at %s\n' "$HOME/.xsession.disabled"
Log in again. Xsession should now try the system fallback, assuming a session manager, window manager or terminal emulator is installed. To restore the custom session after fixing it, move the file back and run sh -n once more.
System administrators can change the policy in /etc/X11/Xsession.options, including allow-user-xsession, allow-user-resources and allow-failsafe. Those files require elevated privileges and affect other users. Do not edit them just to repair one account. If an administrator needs to change policy, remember that later no- entries in /etc/X11/Xsession.options.d/*.conf override earlier entries.
Done means
command -vfinds the intended session program.sh -n "$HOME/.xsession"exits with status 0.- The file is owned by your account and is not group- or world-writable.
- The graphical login starts the intended session through the display manager or
startx. - When something fails,
$HOME/.xsession-errorsor the temporary fallback log contains the useful diagnostic.