I am using Linux Mint 19.2 Cinnamon, with ZSH as login shell for my user.

When I login, I see that my $PATH includes $HOME/.local/bin two times, even though it is specified only once across all my ZSH startup scripts (in $HOME/.zshenv).

I looked at the other dotfiles of my $HOME, and found the offending modification of the $PATH in $HOME/.profile:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then

This was surprising, because the documentation of ZSH says that .profile is only sourced in a "compatibility" mode, when it is being invoked as sh or ksh:

Zsh tries to emulate sh or ksh when it is invoked as sh or ksh respectively; more precisely, it looks at the first letter of the name by which it was invoked, excluding any initial 'r' (assumed to stand for 'restricted'), and if that is 'b', 's' or 'k' it will emulate sh or ksh. Furthermore, if invoked as su (which happens on certain systems when the shell is executed by the su command), the shell will try to find an alternative name from the SHELL environment variable and perform emulation based on that.

I checked from where .profile was being source from by appending the following lines at the end of it:

logger "Opened .profile with this shell: $SHELL"
PARENT_COMMAND=$(ps -o args= $PPID)
logger "Parent command: $PARENT_COMMAND"

After logging out and logging back in again, the syslog contained the following:

Opened .profile with this shell: /usr/bin/zsh
Parent command: lightdm --session-child 13 20

What is the sequence of events that leads the display manager lightdm to source .profile even though my $SHELL is ZSH, and what is the rationale behind it?


From the Arch-Linux Wiki page for lightdm (which I imagine may be valid for your situation in Linux Mint too):

If you are migrating from xinit, you will notice that the display is not launched by your shell. This is because, as opposed to your shell starting the display (and the display inheriting the environment of your shell), LightDM starts your display and does not source your shell. LightDM launches the display by running a wrapper script and that finally exec's your graphic environment. By default, /etc/lightdm/Xsessions.conf is run.

Environment variables

The script checks and sources /etc/profile, ~/.profile, /etc/xprofile and ~/.xprofile, in that order. If you are using a shell that does not source any of these files, you can create an ~/.xprofile to do so. (In this example, the login shell is zsh)


[[ -f ~/.config/zsh/.zshenv ]] && source ~/.config/zsh/.zshenv

So, get your ~/.profile file sourced because that's what the wrapper scripts of lightdm does when it starts. The wiki text furthermore has a specific example for zsh users which includes sourcing your ~/.zshenv from ~/.xprofile.

The #!-line in that example doesn't make much sense though as the file is sourced and therefore shouldn't need it, and I wonder if they got the order of parsing right as it would make more sense to prioritise ~/.xprofile over ~/.profile (i.e don't read ~/.profile at all if ~/.xprofile exists).

If the suggestion in that wiki doesn't do it for you, you can get your ~/.profile to source ~/.zshenv when read by zsh by using

case $SHELL in (*/zsh) . ~/.zshenv; return ;; esac


if [ "$SHELL" = "/usr/bin/zsh" ]; then
    . ~/.zshenv

at its top.

  • Thanks for the explanation, the wrapper script /usr/sbin/lightdm-session was indeed responsible for explicitly sourcing $HOME/.profile, regardless of the login shell. For future readers, the relevant line in the LightDM code base can be found here. – Pierre Nov 16 '19 at 15:12
  • Interestingly enough, there were a few occurrences of people arguing about this topic. Some people are in favor of LightDM sourcing .profile while some are strongly against. – Pierre Nov 16 '19 at 15:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.