The Bash manpage says:

After reading that file (/etc/profile), it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.

So if I have both a ~/.bash_profile and a ~/.profile, only the first will be run.

Because I often share a HOME between different systems I have both, hard linked. On 18.04.2 a login returns to the login screen. With each as a separate but identical file, the same happens. To share between systems and available shells my .profile contains a case statement based on $0, setting up as appropriate or executing a preferred shell. Effectively it does:

case $0 in
*bash) ... some stuff ...
*) exec /bin/bash -il

Putting a # before the exec in the .profile copy and all works well...

The .bash_profile is identical (apart from the # in .profile when I insert one).

It turns out that 18.04.2 is quite happy with that exec in ~/.bash_profile, but not in ~/.profile (which it shouldn't be reading anyway). When it's there, logging in takes the password → black screen briefly → login window again. When it's commented out, login happens properly. Also the shell is Bash, so that branch of the case shouldn't be being taken either.


  • 1
    The code is just "exec /bin/bash -il" (no quotes) and when it's there, logging in takes the password -> black screen briefly -> login window again. When it's commented out login happens properly. – davidledger Feb 26 '19 at 13:21
  • 1
    To be more complete, the .profile (and .bash_profile) in effect do a "case $0 in *bash) ... some stuff ... ;; *) exec /bin/bash -il ;; esac" – davidledger Feb 26 '19 at 13:32

The GUI login process may source /etc/profile and ~/.profile for setting up environment variables, etc., and it may use /bin/dash or /bin/bash for that. Ask Ubuntu has many instances of GUI login failing because of errors in ~/.profile or /etc/profile. You shouldn't be exec'ing something else in these files without checking for interactive usage at the very least. For example, the default .bashrc has this at the top, which you could adapt:

~ head /etc/skel/.bashrc 
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
| improve this answer | |
  • So you are saying that the GUI login process reads these files before the user shell starts? If that's the case then I can see that using exec could cause problems. Of course only a login shell would read these files, so it's not normally a problem. I've been using this basic construct for around 30 years on various flavours of Unix. I do understand that Linux is different, but some differences, like this, are quite subtle. – davidledger Feb 27 '19 at 11:25
  • @davidledger yes, because often environment variables that affect GUI programs (say Java ones with CLASSPATH, etc.) are set there so a login shell is specifically run to source them. For example, here's a bug report from some time ago when LightDM didn't source these: bugs.launchpad.net/ubuntu/+source/lightdm/+bug/794315 – Olorin Feb 28 '19 at 7:55

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.