Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

These are the contents of the stock ~/.profile that came with my 13.10 (commented lines removed):

if [ -n "$BASH_VERSION" ]; then
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

This is inherited from Debian but why did Canonical decide to keep it? As far as I know, it's not the standard *nix way and I have seen various systems where this did not happen, so I assume they must have had a good reason to. This can cause unexpected behavior when running login shells (such as when sshing into the machine for example) where the user would not expect to have ~/.bashrc sourced.

The only benefit I can think of is to not confuse the user with many startup files and allow them to edit .bashrc alone and have that read irrespective of shell type. That, however, is a dubious benefit since it is often useful to have different settings for login and for interactive shells and this blocks you from doing so. Also, login shells are very often not run in a graphical environment and that can cause errors and warnings and problems (oh my!) depending on what you've set in those files.

So why does Ubuntu do this, what am I missing?

share|improve this question
    
Why would -n "$BASH_VERSION" be true outside of bash? –  Elliott Frisch Mar 11 at 3:05
    
@ElliottFrisch it won't be. My question is why does .profile source .bashrc, that is not the case in all Linux versions and I'm wondering what the rationale behind it is. –  terdon Mar 11 at 3:34
    
Seems to be implemented that way in debian upstream. –  Elliott Frisch Mar 11 at 3:37
    
@ElliottFrisch yes, I thought it wasn't and looked it up and saw it was in time to edit my comment. Nevertheless, it's not the case on a SuSe system I have access to (thought it is on a CentOS one) and was not the case on various systems (RHs,Fedoras, older Ubuntus) as far as I recall. So I'm wondering why. –  terdon Mar 11 at 3:42
add comment

2 Answers 2

up vote 5 down vote accepted

This is an upstream decision coming from Debian. The rationale for it is explained in this very nice wiki post, of which the following is an excerpt. The executive summary is "to ensure that GUI and non GUI logins work in the same way":

Let's take xdm as an example. pierre comes back from vacation one day and discovers that his system administrator has installed xdm on the Debian system. He logs in just fine, and xdm reads his .xsession file and runs fluxbox. Everything seems to be OK until he gets an error message in the wrong locale! Since he overrides the LANG variable in his .bash_profile, and since xdm never reads .bash_profile, his LANG variable is now set to en_US instead of fr_CA.

Now, the naive solution to this problem is that instead of launching "xterm", he could configure his window manager to launch "xterm -ls". This flag tells xterm that instead of launching a normal shell, it should launch a login shell. Under this setup, xterm spawns /bin/bash but it puts "-/bin/bash" (or maybe "-bash") in the argument vector, so bash acts like a login shell. This means that every time he opens up a new xterm, it will read /etc/profile and .bash_profile (built-in bash behavior), and then .bashrc (because .bash_profile says to do that). This may seem to work fine at first -- his dot files aren't heavy, so he doesn't even notice the delay -- but there's a more subtle problem. He also launches a web browser directly from his fluxbox menu, and the web browser inherits the LANG variable from fluxbox, which is now set to the wrong locale. So while his xterms may be fine, and anything launched from his xterms may be fine, his web browser is still giving him pages in the wrong locale.

So, what's the best solution to this problem? There really isn't a universal one. A better approach is to modify the .xsession file to look something like this:

[ -r /etc/profile ] && source /etc/profile
[ -r ~/.bash_profile ] && source ~/.bash_profile
xmodmap -e 'keysym Super_R = Multi_key'
xterm &
exec fluxbox

This causes the shell that's interpreting the .xsession script to read in /etc/profile and .bash_profile if they exist and are readable, before running xmodmap or xterm or "execing" the window manager. However, there's one potential drawback to this approach: under xdm, the shell that reads .xsession runs without a controlling terminal. If either /etc/profile or .bash_profile uses any commands that assume the presence of a terminal (such as "fortune" or "stty"), those commands may fail. This is the primary reason why xdm doesn't read those files by default. If you're going to use this approach, you must make sure that all of the commands in your "dot files" are safe to run when there's no terminal.

share|improve this answer
    
I still think it's not a great idea. The ideal one would be make sure that the display manager will source a global profile (check) and the user shell .profile. Now I know why I have duplicated paths in some variables... –  Rmano Mar 18 at 17:51
add comment

This is Ubuntu's standard behaviour, ~/.bashrc is user-level per-interactive-shell start up file. When you open a terminal basically you start a non-login, interactive shell which reads ~/.bashrc and contents of ~/.bashrc get sourced and exported into your current shell environment. It helps one to obtain all his user defined shell variables and functions in the current shell. Also you could find lines like this

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

to obtain user defined aliases in current shell environment.

This is important in order to provide good user experience also. For example one could store proxy credential in .bashrc, unless it get sourced none of terminal applications (viz, ping, wget, curl, lynx etc.) will work properly. Or you have to provide the proxy credentials every time you open a terminal.

Besides Ubuntu's default .bashrc contains many user friendly aliases (for ls and grep to print colourized output), many new definitions for different shell variables which increases user experience.

But in case of your ssh login, or login in virtual console, you basically get an interactive login shell. There the shell initiation file is ~/.profile. Hence unless you source ~/.bashrc you miss all those helpful settings in your .bashrc. That is why Ubuntu's default ~/.profile source ~/.bashrc

Case to avoid

  • you should never source ~/.profile form inside ~/.bashrc at the same time when ~/.bashrc is being sourced from ~/.profile. It will create an infinite loop of situation and as a result your terminal prompt will be suspended unless you hit Ctrl+C. In such a situation if you put a line in your ~/.bashrc
set -x

Then you could see that the file descriptor is stopping when you open a terminal.

share|improve this answer
    
Thanks, this is all true and useful information. It just doesn't address my question. I am familiar with the differences between login and non-login shells. My question is why, on Ubuntu systems, is .profile sourcing .bashrc? SuSe Enterprise 10 does not do it, neither did any of the Fedora versions I've used but that was years ago, I may be wrong. CentOS 5.8 does oddly enough. Anyway, you see my point? This is a design choice and I'm wondering why it was made. –  terdon Mar 11 at 3:33
    
I have not used rigorously the other Linux distributions that you named. can you tell me how they handle situations like aliased commands in ssh session that are defined in .bashrc or in .bash_aliases. For example I have an alias for ls as ls --color=auto in my .bashrc and my .bashrc got sourced from my .profile. Here I can use the alias even from ssh. Or I could use proxy in ssh session. If I do not source my .bashrc from .profile I loose those features. I think it is all about better user experience. –  souravc Mar 11 at 3:57
    
They don't, those aliases won't work. And yes, sourcing .bashrc fixes that. But it also causes problems, I remember the first time I used a system that had this behavior I kept getting these weird messages when sshing to it cause I was using xset b off in my .bashrc which used to disable the terminal bell but only in an X system so it was giving error messages. Took me ages to figure out what was going on since I didn't think that .bashrc would be read when running a login shell. I'm just wondering if there's an "official" statement about this. –  terdon Mar 11 at 4:05
    
I agree with you. I also faced some trouble earlier. But it is mostly helpful and user friendly, if you keep in mind and avoid a few special cases. Is not it :) –  souravc Mar 11 at 4:16
    
Yeah, there are valid reasons for this. I was just curious as to whether Canonical had ever given their rationale for keeping this upstream decision. –  terdon Mar 11 at 4:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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