Why are interactive shells on OSX login shells by default?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
34
down vote

favorite
20












In Linux and, to my knowledge, all Unix systems, terminal emulators run interactive, non-login shells by default. This means that, for bash, the started shell will:




When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This may be inhibited by using the --norc option.



The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.




And for login shells:




When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, 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.



The --noprofile option may be used when the shell is started to inhibit this behavior.




On OSX, however, the default shell (which is bash) started in the default terminal (Terminal.app) actually sources ~/.bash_profile or ~.profile etc. In other words, it acts like a login shell.



Main question: Why is the default interactive shell a login shell on OSX? Why did OSX choose to do this? This means that all instructions/tutorials for shell based things that mention changing things in ~/.bashrc will fail on OSX or vice versa for ~/.profile. Still, while many accusations can be leveled at Apple, hiring incompetent or idiotic devs is not one of them. Presumably, they had a good reason for this, so why?



Subquestions: Does Terminal.app actually run an interactive login shell or have they changed bash's behavior? Is this specific to Terminal.app or is it independent of the terminal emulator?










share|improve this question



















  • 1




    Terminal.app runs a login shell. I don't know why Apple chose to do that.
    – Gilles
    Mar 14 '14 at 1:29














up vote
34
down vote

favorite
20












In Linux and, to my knowledge, all Unix systems, terminal emulators run interactive, non-login shells by default. This means that, for bash, the started shell will:




When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This may be inhibited by using the --norc option.



The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.




And for login shells:




When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, 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.



The --noprofile option may be used when the shell is started to inhibit this behavior.




On OSX, however, the default shell (which is bash) started in the default terminal (Terminal.app) actually sources ~/.bash_profile or ~.profile etc. In other words, it acts like a login shell.



Main question: Why is the default interactive shell a login shell on OSX? Why did OSX choose to do this? This means that all instructions/tutorials for shell based things that mention changing things in ~/.bashrc will fail on OSX or vice versa for ~/.profile. Still, while many accusations can be leveled at Apple, hiring incompetent or idiotic devs is not one of them. Presumably, they had a good reason for this, so why?



Subquestions: Does Terminal.app actually run an interactive login shell or have they changed bash's behavior? Is this specific to Terminal.app or is it independent of the terminal emulator?










share|improve this question



















  • 1




    Terminal.app runs a login shell. I don't know why Apple chose to do that.
    – Gilles
    Mar 14 '14 at 1:29












up vote
34
down vote

favorite
20









up vote
34
down vote

favorite
20






20





In Linux and, to my knowledge, all Unix systems, terminal emulators run interactive, non-login shells by default. This means that, for bash, the started shell will:




When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This may be inhibited by using the --norc option.



The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.




And for login shells:




When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, 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.



The --noprofile option may be used when the shell is started to inhibit this behavior.




On OSX, however, the default shell (which is bash) started in the default terminal (Terminal.app) actually sources ~/.bash_profile or ~.profile etc. In other words, it acts like a login shell.



Main question: Why is the default interactive shell a login shell on OSX? Why did OSX choose to do this? This means that all instructions/tutorials for shell based things that mention changing things in ~/.bashrc will fail on OSX or vice versa for ~/.profile. Still, while many accusations can be leveled at Apple, hiring incompetent or idiotic devs is not one of them. Presumably, they had a good reason for this, so why?



Subquestions: Does Terminal.app actually run an interactive login shell or have they changed bash's behavior? Is this specific to Terminal.app or is it independent of the terminal emulator?










share|improve this question















In Linux and, to my knowledge, all Unix systems, terminal emulators run interactive, non-login shells by default. This means that, for bash, the started shell will:




When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This may be inhibited by using the --norc option.



The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.




And for login shells:




When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, 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.



The --noprofile option may be used when the shell is started to inhibit this behavior.




On OSX, however, the default shell (which is bash) started in the default terminal (Terminal.app) actually sources ~/.bash_profile or ~.profile etc. In other words, it acts like a login shell.



Main question: Why is the default interactive shell a login shell on OSX? Why did OSX choose to do this? This means that all instructions/tutorials for shell based things that mention changing things in ~/.bashrc will fail on OSX or vice versa for ~/.profile. Still, while many accusations can be leveled at Apple, hiring incompetent or idiotic devs is not one of them. Presumably, they had a good reason for this, so why?



Subquestions: Does Terminal.app actually run an interactive login shell or have they changed bash's behavior? Is this specific to Terminal.app or is it independent of the terminal emulator?







bash osx






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 13 '14 at 1:34

























asked Mar 14 '14 at 1:14









terdon

127k31244421




127k31244421







  • 1




    Terminal.app runs a login shell. I don't know why Apple chose to do that.
    – Gilles
    Mar 14 '14 at 1:29












  • 1




    Terminal.app runs a login shell. I don't know why Apple chose to do that.
    – Gilles
    Mar 14 '14 at 1:29







1




1




Terminal.app runs a login shell. I don't know why Apple chose to do that.
– Gilles
Mar 14 '14 at 1:29




Terminal.app runs a login shell. I don't know why Apple chose to do that.
– Gilles
Mar 14 '14 at 1:29










5 Answers
5






active

oldest

votes

















up vote
29
down vote



accepted










The way it's supposed work is that, at the point when you get a shell prompt, both .profile and .bashrc have been run. The specific details of how you get to that point are of secondary relevance, but if either of the files didn't get run at all, you'd have a shell with incomplete settings.



The reason terminal emulators on Linux (and other X-based systems) don't need to run .profile themselves is that it will normally have been run already when you logged in to X. The settings in .profile are supposed to be of the kind that can be inherited by subprocesses, so as long as it's executed once when you log in (e.g. via .Xsession), any further subshells don't need to re-run it.



As the Debian wiki page linked by Alan Shutko explains:




"Why is .bashrc a separate file from .bash_profile, then? This is done for mostly historical reasons, when machines were extremely slow compared to today's workstations. Processing the commands in .profile or .bash_profile could take quite a long time, especially on a machine where a lot of the work had to be done by external commands (pre-bash). So the difficult initial set-up commands, which create environment variables that can be passed down to child processes, are put in .bash_profile. The transient settings and aliases which are not inherited are put in .bashrc so that they can be re-read by every subshell."




All the same rules hold on OSX, too, except for one thing — the OSX GUI doesn't run .profile when you log in, apparently because it has its own method of loading global settings. But that means that a terminal emulator on OSX does need to run .profile (by telling the shell it launches that it's a login shell), otherwise you'd end up with a potentially crippled shell.




Now, a kind of a silly peculiarity of bash, not shared by most other shells, is that it will not automatically run .bashrc if it's started as a login shell. The standard work-around for that is to include something like the following commands in .bash_profile:



[[ -e ~/.profile ]] && source ~/.profile # load generic profile settings
[[ -e ~/.bashrc ]] && source ~/.bashrc # load aliases etc.


Alternatively, it's possible to have no .bash_profile at all, and just include some bash-specific code in the generic .profile file to run .bashrc if needed.



If the OSX default .bash_profile or .profile doesn't do this, then that's arguably a bug. In any case, the proper work-around is to simply add those lines to .bash_profile.




Edit: As strugee notes, the default shell on OSX used to be tcsh, whose behavior is much saner in this respect: when run as an interactive login shell, tcsh automatically reads both .profile and .tcshrc / .cshrc, and thus does not need any workarounds like the .bash_profile trick shown above.



Based on this, I'm 99% sure that the failure of OSX to supply an appropriate default .bash_profile is because, when they switched from tcsh to bash, the folks at Apple simply didn't notice this little wart in bash's startup behavior. With tcsh, no such tricks were needed — starting tcsh as a login shell from an OSX terminal emulator Just Plain Works and does the right thing without such kluges.






share|improve this answer


















  • 1




    Thanks, I sort of knew all that. My question is why did OSX choose to set up in such a way as to render .bashrc irrelevant? Why did they choose to make all shells login shells? As far as I can tell, only your last sentence addresses that and only to say that it's a bug.
    – terdon
    Mar 14 '14 at 15:31






  • 1




    No, the issue is that they start login shells in their terminal emulators. The dotfiles are default bash behavior, starting login shells will read profile etc, not bashrc etc. The question is why login shells are run instead of non-login ones.
    – terdon
    Mar 14 '14 at 16:53






  • 2




    Yes, and both I and Alan have explained that it's because, unlike Linux, OSX doesn't execute .profile when the user logs into the GUI, so they have to execute it later to get environment variables like $PATH, which are normally set in .profile, configured correctly. The fact that, as a side effect, this causes .bashrc not to be sourced is a bug; you can argue about whether it's a bug in bash or in OSX, but that doesn't change the fact that the correct behavior would be to ensure that both the environment variables from .profile and the bash config setting from .bashrc are loaded.
    – Ilmari Karonen
    Mar 14 '14 at 17:01






  • 1




    And I'm saying the answer to "why do they use a login shell?" is "because they need to load .profile", while the answer to "why don't they source .bashrc from .profile, then?" is "because it's a bug!" Seriously, that cannot possibly be an intentional decision; it's just something they overlooked, presumably because, in the Mac ecosystem, shells are second-class citizens that most users aren't supposed to deal with. (Ps. See also strugee's answer for a historical explanation; it's almost certainly a regression from the switch from tcsh to bash.)
    – Ilmari Karonen
    Mar 14 '14 at 17:29






  • 1




    @huangzonghao: I'm assuming you're on some type of Linux system? It's likely that your GUI login manager is set up to source /etc/profile and ~/.profile when you log in; but since it's not bash, it won't source ~/.bash_profile, since that's purely a bash-only thing. When you log in via Ctrl+Alt+1, you're logging directly into your shell, which will take care of setting up the profile; if your login shell is bash, that means it will source ~/.bash_profile if it exists (and will try to source ~/.profile otherwise).
    – Ilmari Karonen
    Jun 12 at 20:58


















up vote
13
down vote













The main reason that X terminal applications run non-login shells by default is that in the beginning of time, your .Xsession would have run the .profile to set up your initial login items. Then, since that was all set up already, terminal apps didn't need to run it, they could run the .bashrc. Discussion of why this would matter is at https://wiki.debian.org/DotFiles:




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.




On OS X, the user environments aren't started by a pile of shell scripts, and launchd doesn't source .profile at any time. (That's sort of a shame, since it means it's a lot more annoying to set environment variables, but such is life.) Since it doesn't, when would it run .profile? Only if you ssh'd in? That seems kind of pointless, since many boxes will never be targets of ssh. Might as well make the terminals run login shells by default, so that .profile will be run sometime.



What about .bashrc, then? Is it useless? No. It still has the purpose that it had in the days of the VT100. It is used for any time you open a shell other than opening a Terminal window. So if you shell out of Emacs or vi, or if you do a su user.






share|improve this answer






















  • The Debian page you're quoting explains why Debian's .profile sources .bashrc, not why OSX decided to make all shells login shells by default. Actually, you are answering another question of mine, and thanks! However, your answer does not explain the OSX choice and the Debian quote is completely irrelevant here as far as I can tell (please let me know if I'm just missing the point). The OSX way make .bashrc etc useless and does not make .profile any more useful.
    – terdon
    Mar 14 '14 at 4:28

















up vote
4
down vote













I don't know why they would have done that. However, here's my guess.



To start with, it's worth noting that on a GNU/Linux system, you can of course switch to vt1, vt2, etc. You get a login shell there. On an OS X system, there's no equivalent. The only way to access the UNIX underpinnings is through a terminal emulator or through single user mode (disclaimer: I've never actually used single user mode; it's commandline-driven IIRC but I may be wrong). Therefore, in OS X whatever the default is in the emulator is the default for the entire system.



Now, why would you make the default a login shell? There are a couple (read: not many) reasons I can think of to do this.



  • It provides a consistent user experience if you SSH into the box. (Especially important for the server edition of OS X - presumably if you're running an OS X server, you're a newbie.)

  • The default shell of OS X used to be tcsh. This is about as wild a guess as you can get, but it may be that tcsh normally did something when run as a login shell, and the historical pattern stuck. (I doubt it, though - maybe one of the older regulars could tell us.)

  • "We are Apple. We are the vendors of the largest UNIX distribution on the planet. It doesn't matter how trivial our reasons are; if we make a decision, your tool must deal with it."

Honestly, I've been using Darwin for ~6 years and I can't answer this question properly. It doesn't really make sense to me, either.



To answer your subquestion, bash is not patched or anything (at least for this). The default terminal emulator runs login shells by default, and presumably iTerm copies that.






share|improve this answer
















  • 1




    +1 for mentioning tcsh, since its behavior is far saner in this respect than that of bash: when started as an interactive login shell, tcsh sources both .profile and .tcshrc / .cshrc without requiring any kluges like the one I gave in my answer. Given that, I suspect this behavior is an unfixed regression caused by the switch from tcsh to bash.
    – Ilmari Karonen
    Mar 14 '14 at 17:09











  • @IlmariKaronen Do you mean (here and there) that tcsh sources .login and .tcshrc/.cshrc? It would make no sense for tcsh to source .profile; it typically contains commands with sh syntax that tcsh won't accept. I don't have macOS but I made /bin/tcsh my login shell on Ubuntu 16.04. .profile isn't sourced. tcsh(1) doesn't mention that file, nor does this tcsh(1).
    – Eliah Kagan
    Oct 17 '17 at 19:23

















up vote
3
down vote













This is an update to current status: the answers have become stale as new MacOSX versions have been released and login behavior has changed.



This question was asked and answered in 2014. I've been researching the subject in an attempt to build a common .bashrc & .bash_profile set to use across different Linux distros and BSD (whatever they call them if they're not distros).



I recently bought a used Mac Mini with Sierra installed, so I now have systems with 10.6, 10.10, 10.11, and 10.12. Although I have munged the older ones (leaving clues to their previous status), the 10.12 Sierra installation is untouched.



Results: In 10.12 Sierra, there is NO default .bashrc, .bash_profile, or .profile created. In /etc, there are bashrc, bashrc_Apple_Terminal, and profile. Contents of /etc/profile:



# System-wide .profile for sh(1)

if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi

if [ "$BASH-no" != "no" ]; then
[ -r /etc/bashrc ] && . /etc/bashrc
fi


Contents of /etc/bashrc:



# System-wide .bashrc file for interactive bash(1) shells.
if [ -z "$PS1" ]; then
return
fi

PS1='h:W u$ '
# Make bash check its window size after a process completes
shopt -s checkwinsize

[ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"


The /etc/bashrc_Apple_Terminal script sets the PROMPT_COMMAND variable and sets up a mechanism for preserving session state for each terminal; if the terminal app is quit, the status of previous session is restored when the app is started again. Otherwise, almost nothing (minimal $PS1) is set in /etc/bashrc, leaving any other customization (real $PS1, aliases, functions) to be set in ~/.bashrc and $PATH settings in .bash_profile (or in .profile, sourced in by .bash_profile).



I have confirmed that iTerm2 behaves the same way as the Terminal app, except that the default behavior of starting a login session is visible and can be edited.



If you run an X11 (now XQuartz) XTerm terminal session, you will see a non-login session, the same as on a Linux system; .bash_profile (or .profile) is skipped, and you just get .bashrc.



And, here's my answer:



Although the Terminal app claims to be an xterm (TERM=xterm-256color), it does not set the $DISPLAY variable unless X11 is installed. We are seeing a simulation of an X environment, but not a completely real one. If you SSH into another system with the -X switch (enable X11 forwarding), it will fail because there is no $DISPLAY variable. If you have installed X11, then SSH into another system, X11 forwarding will succeed.



Bottom line (and short answer): The Terminal app is not a true X11 terminal (does not set $DISPLAY); it behaves much more like an SSH login than an XTerm session, in that it has to be a login session in order to set values from /etc/profile and ~/.bash_profile or ~/.profile






share|improve this answer



























    up vote
    0
    down vote













    The answers above explained the reason why interactive shells are login shells on macOS by default: settings in /etc/profile, ~/.profile are inherited by a non-login shell on X-based systems, but not on macOS. Here I wanna remind you that you should always use login shell on macOS because of the existence of path_helper:



    ❯ cat /etc/profile # or cat /etc/zprofile
    # System-wide .profile for sh(1)

    if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
    fi

    if [ "$BASH-no" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
    fi



    The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d
    and appends their contents to the PATH and MANPATH environment variables respectively. (The MANPATH envi-
    ronment variable will not be modified unless it is already set in the environment.)




    If you're using a non-login shell, some paths will not be imported.



    I think it's always a good idea for developer to put a file into /etc/paths.d to import their path values, but not to symlink the callable binaries into locations like /usr/bin or /bin. (The default PATH is /usr/bin:/bin:/usr/sbin:/sbin. Not everyone uses Homebrew or MacPorts adding custom values into PATH. So there's not always a safe place to put the symlinks of callable commands.)



    Here is an example of files in /etc/paths.d. Basically you're putting one value each line.



    ❯ cat /etc/paths.d/Wireshark
    /Applications/Wireshark.app/Contents/MacOS


    Reference:



    • Mastering the path_helper utility of MacOSX

    • man path_helper





    share|improve this answer






















      Your Answer








      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "106"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f119627%2fwhy-are-interactive-shells-on-osx-login-shells-by-default%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      29
      down vote



      accepted










      The way it's supposed work is that, at the point when you get a shell prompt, both .profile and .bashrc have been run. The specific details of how you get to that point are of secondary relevance, but if either of the files didn't get run at all, you'd have a shell with incomplete settings.



      The reason terminal emulators on Linux (and other X-based systems) don't need to run .profile themselves is that it will normally have been run already when you logged in to X. The settings in .profile are supposed to be of the kind that can be inherited by subprocesses, so as long as it's executed once when you log in (e.g. via .Xsession), any further subshells don't need to re-run it.



      As the Debian wiki page linked by Alan Shutko explains:




      "Why is .bashrc a separate file from .bash_profile, then? This is done for mostly historical reasons, when machines were extremely slow compared to today's workstations. Processing the commands in .profile or .bash_profile could take quite a long time, especially on a machine where a lot of the work had to be done by external commands (pre-bash). So the difficult initial set-up commands, which create environment variables that can be passed down to child processes, are put in .bash_profile. The transient settings and aliases which are not inherited are put in .bashrc so that they can be re-read by every subshell."




      All the same rules hold on OSX, too, except for one thing — the OSX GUI doesn't run .profile when you log in, apparently because it has its own method of loading global settings. But that means that a terminal emulator on OSX does need to run .profile (by telling the shell it launches that it's a login shell), otherwise you'd end up with a potentially crippled shell.




      Now, a kind of a silly peculiarity of bash, not shared by most other shells, is that it will not automatically run .bashrc if it's started as a login shell. The standard work-around for that is to include something like the following commands in .bash_profile:



      [[ -e ~/.profile ]] && source ~/.profile # load generic profile settings
      [[ -e ~/.bashrc ]] && source ~/.bashrc # load aliases etc.


      Alternatively, it's possible to have no .bash_profile at all, and just include some bash-specific code in the generic .profile file to run .bashrc if needed.



      If the OSX default .bash_profile or .profile doesn't do this, then that's arguably a bug. In any case, the proper work-around is to simply add those lines to .bash_profile.




      Edit: As strugee notes, the default shell on OSX used to be tcsh, whose behavior is much saner in this respect: when run as an interactive login shell, tcsh automatically reads both .profile and .tcshrc / .cshrc, and thus does not need any workarounds like the .bash_profile trick shown above.



      Based on this, I'm 99% sure that the failure of OSX to supply an appropriate default .bash_profile is because, when they switched from tcsh to bash, the folks at Apple simply didn't notice this little wart in bash's startup behavior. With tcsh, no such tricks were needed — starting tcsh as a login shell from an OSX terminal emulator Just Plain Works and does the right thing without such kluges.






      share|improve this answer


















      • 1




        Thanks, I sort of knew all that. My question is why did OSX choose to set up in such a way as to render .bashrc irrelevant? Why did they choose to make all shells login shells? As far as I can tell, only your last sentence addresses that and only to say that it's a bug.
        – terdon
        Mar 14 '14 at 15:31






      • 1




        No, the issue is that they start login shells in their terminal emulators. The dotfiles are default bash behavior, starting login shells will read profile etc, not bashrc etc. The question is why login shells are run instead of non-login ones.
        – terdon
        Mar 14 '14 at 16:53






      • 2




        Yes, and both I and Alan have explained that it's because, unlike Linux, OSX doesn't execute .profile when the user logs into the GUI, so they have to execute it later to get environment variables like $PATH, which are normally set in .profile, configured correctly. The fact that, as a side effect, this causes .bashrc not to be sourced is a bug; you can argue about whether it's a bug in bash or in OSX, but that doesn't change the fact that the correct behavior would be to ensure that both the environment variables from .profile and the bash config setting from .bashrc are loaded.
        – Ilmari Karonen
        Mar 14 '14 at 17:01






      • 1




        And I'm saying the answer to "why do they use a login shell?" is "because they need to load .profile", while the answer to "why don't they source .bashrc from .profile, then?" is "because it's a bug!" Seriously, that cannot possibly be an intentional decision; it's just something they overlooked, presumably because, in the Mac ecosystem, shells are second-class citizens that most users aren't supposed to deal with. (Ps. See also strugee's answer for a historical explanation; it's almost certainly a regression from the switch from tcsh to bash.)
        – Ilmari Karonen
        Mar 14 '14 at 17:29






      • 1




        @huangzonghao: I'm assuming you're on some type of Linux system? It's likely that your GUI login manager is set up to source /etc/profile and ~/.profile when you log in; but since it's not bash, it won't source ~/.bash_profile, since that's purely a bash-only thing. When you log in via Ctrl+Alt+1, you're logging directly into your shell, which will take care of setting up the profile; if your login shell is bash, that means it will source ~/.bash_profile if it exists (and will try to source ~/.profile otherwise).
        – Ilmari Karonen
        Jun 12 at 20:58















      up vote
      29
      down vote



      accepted










      The way it's supposed work is that, at the point when you get a shell prompt, both .profile and .bashrc have been run. The specific details of how you get to that point are of secondary relevance, but if either of the files didn't get run at all, you'd have a shell with incomplete settings.



      The reason terminal emulators on Linux (and other X-based systems) don't need to run .profile themselves is that it will normally have been run already when you logged in to X. The settings in .profile are supposed to be of the kind that can be inherited by subprocesses, so as long as it's executed once when you log in (e.g. via .Xsession), any further subshells don't need to re-run it.



      As the Debian wiki page linked by Alan Shutko explains:




      "Why is .bashrc a separate file from .bash_profile, then? This is done for mostly historical reasons, when machines were extremely slow compared to today's workstations. Processing the commands in .profile or .bash_profile could take quite a long time, especially on a machine where a lot of the work had to be done by external commands (pre-bash). So the difficult initial set-up commands, which create environment variables that can be passed down to child processes, are put in .bash_profile. The transient settings and aliases which are not inherited are put in .bashrc so that they can be re-read by every subshell."




      All the same rules hold on OSX, too, except for one thing — the OSX GUI doesn't run .profile when you log in, apparently because it has its own method of loading global settings. But that means that a terminal emulator on OSX does need to run .profile (by telling the shell it launches that it's a login shell), otherwise you'd end up with a potentially crippled shell.




      Now, a kind of a silly peculiarity of bash, not shared by most other shells, is that it will not automatically run .bashrc if it's started as a login shell. The standard work-around for that is to include something like the following commands in .bash_profile:



      [[ -e ~/.profile ]] && source ~/.profile # load generic profile settings
      [[ -e ~/.bashrc ]] && source ~/.bashrc # load aliases etc.


      Alternatively, it's possible to have no .bash_profile at all, and just include some bash-specific code in the generic .profile file to run .bashrc if needed.



      If the OSX default .bash_profile or .profile doesn't do this, then that's arguably a bug. In any case, the proper work-around is to simply add those lines to .bash_profile.




      Edit: As strugee notes, the default shell on OSX used to be tcsh, whose behavior is much saner in this respect: when run as an interactive login shell, tcsh automatically reads both .profile and .tcshrc / .cshrc, and thus does not need any workarounds like the .bash_profile trick shown above.



      Based on this, I'm 99% sure that the failure of OSX to supply an appropriate default .bash_profile is because, when they switched from tcsh to bash, the folks at Apple simply didn't notice this little wart in bash's startup behavior. With tcsh, no such tricks were needed — starting tcsh as a login shell from an OSX terminal emulator Just Plain Works and does the right thing without such kluges.






      share|improve this answer


















      • 1




        Thanks, I sort of knew all that. My question is why did OSX choose to set up in such a way as to render .bashrc irrelevant? Why did they choose to make all shells login shells? As far as I can tell, only your last sentence addresses that and only to say that it's a bug.
        – terdon
        Mar 14 '14 at 15:31






      • 1




        No, the issue is that they start login shells in their terminal emulators. The dotfiles are default bash behavior, starting login shells will read profile etc, not bashrc etc. The question is why login shells are run instead of non-login ones.
        – terdon
        Mar 14 '14 at 16:53






      • 2




        Yes, and both I and Alan have explained that it's because, unlike Linux, OSX doesn't execute .profile when the user logs into the GUI, so they have to execute it later to get environment variables like $PATH, which are normally set in .profile, configured correctly. The fact that, as a side effect, this causes .bashrc not to be sourced is a bug; you can argue about whether it's a bug in bash or in OSX, but that doesn't change the fact that the correct behavior would be to ensure that both the environment variables from .profile and the bash config setting from .bashrc are loaded.
        – Ilmari Karonen
        Mar 14 '14 at 17:01






      • 1




        And I'm saying the answer to "why do they use a login shell?" is "because they need to load .profile", while the answer to "why don't they source .bashrc from .profile, then?" is "because it's a bug!" Seriously, that cannot possibly be an intentional decision; it's just something they overlooked, presumably because, in the Mac ecosystem, shells are second-class citizens that most users aren't supposed to deal with. (Ps. See also strugee's answer for a historical explanation; it's almost certainly a regression from the switch from tcsh to bash.)
        – Ilmari Karonen
        Mar 14 '14 at 17:29






      • 1




        @huangzonghao: I'm assuming you're on some type of Linux system? It's likely that your GUI login manager is set up to source /etc/profile and ~/.profile when you log in; but since it's not bash, it won't source ~/.bash_profile, since that's purely a bash-only thing. When you log in via Ctrl+Alt+1, you're logging directly into your shell, which will take care of setting up the profile; if your login shell is bash, that means it will source ~/.bash_profile if it exists (and will try to source ~/.profile otherwise).
        – Ilmari Karonen
        Jun 12 at 20:58













      up vote
      29
      down vote



      accepted







      up vote
      29
      down vote



      accepted






      The way it's supposed work is that, at the point when you get a shell prompt, both .profile and .bashrc have been run. The specific details of how you get to that point are of secondary relevance, but if either of the files didn't get run at all, you'd have a shell with incomplete settings.



      The reason terminal emulators on Linux (and other X-based systems) don't need to run .profile themselves is that it will normally have been run already when you logged in to X. The settings in .profile are supposed to be of the kind that can be inherited by subprocesses, so as long as it's executed once when you log in (e.g. via .Xsession), any further subshells don't need to re-run it.



      As the Debian wiki page linked by Alan Shutko explains:




      "Why is .bashrc a separate file from .bash_profile, then? This is done for mostly historical reasons, when machines were extremely slow compared to today's workstations. Processing the commands in .profile or .bash_profile could take quite a long time, especially on a machine where a lot of the work had to be done by external commands (pre-bash). So the difficult initial set-up commands, which create environment variables that can be passed down to child processes, are put in .bash_profile. The transient settings and aliases which are not inherited are put in .bashrc so that they can be re-read by every subshell."




      All the same rules hold on OSX, too, except for one thing — the OSX GUI doesn't run .profile when you log in, apparently because it has its own method of loading global settings. But that means that a terminal emulator on OSX does need to run .profile (by telling the shell it launches that it's a login shell), otherwise you'd end up with a potentially crippled shell.




      Now, a kind of a silly peculiarity of bash, not shared by most other shells, is that it will not automatically run .bashrc if it's started as a login shell. The standard work-around for that is to include something like the following commands in .bash_profile:



      [[ -e ~/.profile ]] && source ~/.profile # load generic profile settings
      [[ -e ~/.bashrc ]] && source ~/.bashrc # load aliases etc.


      Alternatively, it's possible to have no .bash_profile at all, and just include some bash-specific code in the generic .profile file to run .bashrc if needed.



      If the OSX default .bash_profile or .profile doesn't do this, then that's arguably a bug. In any case, the proper work-around is to simply add those lines to .bash_profile.




      Edit: As strugee notes, the default shell on OSX used to be tcsh, whose behavior is much saner in this respect: when run as an interactive login shell, tcsh automatically reads both .profile and .tcshrc / .cshrc, and thus does not need any workarounds like the .bash_profile trick shown above.



      Based on this, I'm 99% sure that the failure of OSX to supply an appropriate default .bash_profile is because, when they switched from tcsh to bash, the folks at Apple simply didn't notice this little wart in bash's startup behavior. With tcsh, no such tricks were needed — starting tcsh as a login shell from an OSX terminal emulator Just Plain Works and does the right thing without such kluges.






      share|improve this answer














      The way it's supposed work is that, at the point when you get a shell prompt, both .profile and .bashrc have been run. The specific details of how you get to that point are of secondary relevance, but if either of the files didn't get run at all, you'd have a shell with incomplete settings.



      The reason terminal emulators on Linux (and other X-based systems) don't need to run .profile themselves is that it will normally have been run already when you logged in to X. The settings in .profile are supposed to be of the kind that can be inherited by subprocesses, so as long as it's executed once when you log in (e.g. via .Xsession), any further subshells don't need to re-run it.



      As the Debian wiki page linked by Alan Shutko explains:




      "Why is .bashrc a separate file from .bash_profile, then? This is done for mostly historical reasons, when machines were extremely slow compared to today's workstations. Processing the commands in .profile or .bash_profile could take quite a long time, especially on a machine where a lot of the work had to be done by external commands (pre-bash). So the difficult initial set-up commands, which create environment variables that can be passed down to child processes, are put in .bash_profile. The transient settings and aliases which are not inherited are put in .bashrc so that they can be re-read by every subshell."




      All the same rules hold on OSX, too, except for one thing — the OSX GUI doesn't run .profile when you log in, apparently because it has its own method of loading global settings. But that means that a terminal emulator on OSX does need to run .profile (by telling the shell it launches that it's a login shell), otherwise you'd end up with a potentially crippled shell.




      Now, a kind of a silly peculiarity of bash, not shared by most other shells, is that it will not automatically run .bashrc if it's started as a login shell. The standard work-around for that is to include something like the following commands in .bash_profile:



      [[ -e ~/.profile ]] && source ~/.profile # load generic profile settings
      [[ -e ~/.bashrc ]] && source ~/.bashrc # load aliases etc.


      Alternatively, it's possible to have no .bash_profile at all, and just include some bash-specific code in the generic .profile file to run .bashrc if needed.



      If the OSX default .bash_profile or .profile doesn't do this, then that's arguably a bug. In any case, the proper work-around is to simply add those lines to .bash_profile.




      Edit: As strugee notes, the default shell on OSX used to be tcsh, whose behavior is much saner in this respect: when run as an interactive login shell, tcsh automatically reads both .profile and .tcshrc / .cshrc, and thus does not need any workarounds like the .bash_profile trick shown above.



      Based on this, I'm 99% sure that the failure of OSX to supply an appropriate default .bash_profile is because, when they switched from tcsh to bash, the folks at Apple simply didn't notice this little wart in bash's startup behavior. With tcsh, no such tricks were needed — starting tcsh as a login shell from an OSX terminal emulator Just Plain Works and does the right thing without such kluges.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Apr 13 '17 at 12:36









      Community

      1




      1










      answered Mar 14 '14 at 9:54









      Ilmari Karonen

      67559




      67559







      • 1




        Thanks, I sort of knew all that. My question is why did OSX choose to set up in such a way as to render .bashrc irrelevant? Why did they choose to make all shells login shells? As far as I can tell, only your last sentence addresses that and only to say that it's a bug.
        – terdon
        Mar 14 '14 at 15:31






      • 1




        No, the issue is that they start login shells in their terminal emulators. The dotfiles are default bash behavior, starting login shells will read profile etc, not bashrc etc. The question is why login shells are run instead of non-login ones.
        – terdon
        Mar 14 '14 at 16:53






      • 2




        Yes, and both I and Alan have explained that it's because, unlike Linux, OSX doesn't execute .profile when the user logs into the GUI, so they have to execute it later to get environment variables like $PATH, which are normally set in .profile, configured correctly. The fact that, as a side effect, this causes .bashrc not to be sourced is a bug; you can argue about whether it's a bug in bash or in OSX, but that doesn't change the fact that the correct behavior would be to ensure that both the environment variables from .profile and the bash config setting from .bashrc are loaded.
        – Ilmari Karonen
        Mar 14 '14 at 17:01






      • 1




        And I'm saying the answer to "why do they use a login shell?" is "because they need to load .profile", while the answer to "why don't they source .bashrc from .profile, then?" is "because it's a bug!" Seriously, that cannot possibly be an intentional decision; it's just something they overlooked, presumably because, in the Mac ecosystem, shells are second-class citizens that most users aren't supposed to deal with. (Ps. See also strugee's answer for a historical explanation; it's almost certainly a regression from the switch from tcsh to bash.)
        – Ilmari Karonen
        Mar 14 '14 at 17:29






      • 1




        @huangzonghao: I'm assuming you're on some type of Linux system? It's likely that your GUI login manager is set up to source /etc/profile and ~/.profile when you log in; but since it's not bash, it won't source ~/.bash_profile, since that's purely a bash-only thing. When you log in via Ctrl+Alt+1, you're logging directly into your shell, which will take care of setting up the profile; if your login shell is bash, that means it will source ~/.bash_profile if it exists (and will try to source ~/.profile otherwise).
        – Ilmari Karonen
        Jun 12 at 20:58













      • 1




        Thanks, I sort of knew all that. My question is why did OSX choose to set up in such a way as to render .bashrc irrelevant? Why did they choose to make all shells login shells? As far as I can tell, only your last sentence addresses that and only to say that it's a bug.
        – terdon
        Mar 14 '14 at 15:31






      • 1




        No, the issue is that they start login shells in their terminal emulators. The dotfiles are default bash behavior, starting login shells will read profile etc, not bashrc etc. The question is why login shells are run instead of non-login ones.
        – terdon
        Mar 14 '14 at 16:53






      • 2




        Yes, and both I and Alan have explained that it's because, unlike Linux, OSX doesn't execute .profile when the user logs into the GUI, so they have to execute it later to get environment variables like $PATH, which are normally set in .profile, configured correctly. The fact that, as a side effect, this causes .bashrc not to be sourced is a bug; you can argue about whether it's a bug in bash or in OSX, but that doesn't change the fact that the correct behavior would be to ensure that both the environment variables from .profile and the bash config setting from .bashrc are loaded.
        – Ilmari Karonen
        Mar 14 '14 at 17:01






      • 1




        And I'm saying the answer to "why do they use a login shell?" is "because they need to load .profile", while the answer to "why don't they source .bashrc from .profile, then?" is "because it's a bug!" Seriously, that cannot possibly be an intentional decision; it's just something they overlooked, presumably because, in the Mac ecosystem, shells are second-class citizens that most users aren't supposed to deal with. (Ps. See also strugee's answer for a historical explanation; it's almost certainly a regression from the switch from tcsh to bash.)
        – Ilmari Karonen
        Mar 14 '14 at 17:29






      • 1




        @huangzonghao: I'm assuming you're on some type of Linux system? It's likely that your GUI login manager is set up to source /etc/profile and ~/.profile when you log in; but since it's not bash, it won't source ~/.bash_profile, since that's purely a bash-only thing. When you log in via Ctrl+Alt+1, you're logging directly into your shell, which will take care of setting up the profile; if your login shell is bash, that means it will source ~/.bash_profile if it exists (and will try to source ~/.profile otherwise).
        – Ilmari Karonen
        Jun 12 at 20:58








      1




      1




      Thanks, I sort of knew all that. My question is why did OSX choose to set up in such a way as to render .bashrc irrelevant? Why did they choose to make all shells login shells? As far as I can tell, only your last sentence addresses that and only to say that it's a bug.
      – terdon
      Mar 14 '14 at 15:31




      Thanks, I sort of knew all that. My question is why did OSX choose to set up in such a way as to render .bashrc irrelevant? Why did they choose to make all shells login shells? As far as I can tell, only your last sentence addresses that and only to say that it's a bug.
      – terdon
      Mar 14 '14 at 15:31




      1




      1




      No, the issue is that they start login shells in their terminal emulators. The dotfiles are default bash behavior, starting login shells will read profile etc, not bashrc etc. The question is why login shells are run instead of non-login ones.
      – terdon
      Mar 14 '14 at 16:53




      No, the issue is that they start login shells in their terminal emulators. The dotfiles are default bash behavior, starting login shells will read profile etc, not bashrc etc. The question is why login shells are run instead of non-login ones.
      – terdon
      Mar 14 '14 at 16:53




      2




      2




      Yes, and both I and Alan have explained that it's because, unlike Linux, OSX doesn't execute .profile when the user logs into the GUI, so they have to execute it later to get environment variables like $PATH, which are normally set in .profile, configured correctly. The fact that, as a side effect, this causes .bashrc not to be sourced is a bug; you can argue about whether it's a bug in bash or in OSX, but that doesn't change the fact that the correct behavior would be to ensure that both the environment variables from .profile and the bash config setting from .bashrc are loaded.
      – Ilmari Karonen
      Mar 14 '14 at 17:01




      Yes, and both I and Alan have explained that it's because, unlike Linux, OSX doesn't execute .profile when the user logs into the GUI, so they have to execute it later to get environment variables like $PATH, which are normally set in .profile, configured correctly. The fact that, as a side effect, this causes .bashrc not to be sourced is a bug; you can argue about whether it's a bug in bash or in OSX, but that doesn't change the fact that the correct behavior would be to ensure that both the environment variables from .profile and the bash config setting from .bashrc are loaded.
      – Ilmari Karonen
      Mar 14 '14 at 17:01




      1




      1




      And I'm saying the answer to "why do they use a login shell?" is "because they need to load .profile", while the answer to "why don't they source .bashrc from .profile, then?" is "because it's a bug!" Seriously, that cannot possibly be an intentional decision; it's just something they overlooked, presumably because, in the Mac ecosystem, shells are second-class citizens that most users aren't supposed to deal with. (Ps. See also strugee's answer for a historical explanation; it's almost certainly a regression from the switch from tcsh to bash.)
      – Ilmari Karonen
      Mar 14 '14 at 17:29




      And I'm saying the answer to "why do they use a login shell?" is "because they need to load .profile", while the answer to "why don't they source .bashrc from .profile, then?" is "because it's a bug!" Seriously, that cannot possibly be an intentional decision; it's just something they overlooked, presumably because, in the Mac ecosystem, shells are second-class citizens that most users aren't supposed to deal with. (Ps. See also strugee's answer for a historical explanation; it's almost certainly a regression from the switch from tcsh to bash.)
      – Ilmari Karonen
      Mar 14 '14 at 17:29




      1




      1




      @huangzonghao: I'm assuming you're on some type of Linux system? It's likely that your GUI login manager is set up to source /etc/profile and ~/.profile when you log in; but since it's not bash, it won't source ~/.bash_profile, since that's purely a bash-only thing. When you log in via Ctrl+Alt+1, you're logging directly into your shell, which will take care of setting up the profile; if your login shell is bash, that means it will source ~/.bash_profile if it exists (and will try to source ~/.profile otherwise).
      – Ilmari Karonen
      Jun 12 at 20:58





      @huangzonghao: I'm assuming you're on some type of Linux system? It's likely that your GUI login manager is set up to source /etc/profile and ~/.profile when you log in; but since it's not bash, it won't source ~/.bash_profile, since that's purely a bash-only thing. When you log in via Ctrl+Alt+1, you're logging directly into your shell, which will take care of setting up the profile; if your login shell is bash, that means it will source ~/.bash_profile if it exists (and will try to source ~/.profile otherwise).
      – Ilmari Karonen
      Jun 12 at 20:58













      up vote
      13
      down vote













      The main reason that X terminal applications run non-login shells by default is that in the beginning of time, your .Xsession would have run the .profile to set up your initial login items. Then, since that was all set up already, terminal apps didn't need to run it, they could run the .bashrc. Discussion of why this would matter is at https://wiki.debian.org/DotFiles:




      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.




      On OS X, the user environments aren't started by a pile of shell scripts, and launchd doesn't source .profile at any time. (That's sort of a shame, since it means it's a lot more annoying to set environment variables, but such is life.) Since it doesn't, when would it run .profile? Only if you ssh'd in? That seems kind of pointless, since many boxes will never be targets of ssh. Might as well make the terminals run login shells by default, so that .profile will be run sometime.



      What about .bashrc, then? Is it useless? No. It still has the purpose that it had in the days of the VT100. It is used for any time you open a shell other than opening a Terminal window. So if you shell out of Emacs or vi, or if you do a su user.






      share|improve this answer






















      • The Debian page you're quoting explains why Debian's .profile sources .bashrc, not why OSX decided to make all shells login shells by default. Actually, you are answering another question of mine, and thanks! However, your answer does not explain the OSX choice and the Debian quote is completely irrelevant here as far as I can tell (please let me know if I'm just missing the point). The OSX way make .bashrc etc useless and does not make .profile any more useful.
        – terdon
        Mar 14 '14 at 4:28














      up vote
      13
      down vote













      The main reason that X terminal applications run non-login shells by default is that in the beginning of time, your .Xsession would have run the .profile to set up your initial login items. Then, since that was all set up already, terminal apps didn't need to run it, they could run the .bashrc. Discussion of why this would matter is at https://wiki.debian.org/DotFiles:




      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.




      On OS X, the user environments aren't started by a pile of shell scripts, and launchd doesn't source .profile at any time. (That's sort of a shame, since it means it's a lot more annoying to set environment variables, but such is life.) Since it doesn't, when would it run .profile? Only if you ssh'd in? That seems kind of pointless, since many boxes will never be targets of ssh. Might as well make the terminals run login shells by default, so that .profile will be run sometime.



      What about .bashrc, then? Is it useless? No. It still has the purpose that it had in the days of the VT100. It is used for any time you open a shell other than opening a Terminal window. So if you shell out of Emacs or vi, or if you do a su user.






      share|improve this answer






















      • The Debian page you're quoting explains why Debian's .profile sources .bashrc, not why OSX decided to make all shells login shells by default. Actually, you are answering another question of mine, and thanks! However, your answer does not explain the OSX choice and the Debian quote is completely irrelevant here as far as I can tell (please let me know if I'm just missing the point). The OSX way make .bashrc etc useless and does not make .profile any more useful.
        – terdon
        Mar 14 '14 at 4:28












      up vote
      13
      down vote










      up vote
      13
      down vote









      The main reason that X terminal applications run non-login shells by default is that in the beginning of time, your .Xsession would have run the .profile to set up your initial login items. Then, since that was all set up already, terminal apps didn't need to run it, they could run the .bashrc. Discussion of why this would matter is at https://wiki.debian.org/DotFiles:




      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.




      On OS X, the user environments aren't started by a pile of shell scripts, and launchd doesn't source .profile at any time. (That's sort of a shame, since it means it's a lot more annoying to set environment variables, but such is life.) Since it doesn't, when would it run .profile? Only if you ssh'd in? That seems kind of pointless, since many boxes will never be targets of ssh. Might as well make the terminals run login shells by default, so that .profile will be run sometime.



      What about .bashrc, then? Is it useless? No. It still has the purpose that it had in the days of the VT100. It is used for any time you open a shell other than opening a Terminal window. So if you shell out of Emacs or vi, or if you do a su user.






      share|improve this answer














      The main reason that X terminal applications run non-login shells by default is that in the beginning of time, your .Xsession would have run the .profile to set up your initial login items. Then, since that was all set up already, terminal apps didn't need to run it, they could run the .bashrc. Discussion of why this would matter is at https://wiki.debian.org/DotFiles:




      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.




      On OS X, the user environments aren't started by a pile of shell scripts, and launchd doesn't source .profile at any time. (That's sort of a shame, since it means it's a lot more annoying to set environment variables, but such is life.) Since it doesn't, when would it run .profile? Only if you ssh'd in? That seems kind of pointless, since many boxes will never be targets of ssh. Might as well make the terminals run login shells by default, so that .profile will be run sometime.



      What about .bashrc, then? Is it useless? No. It still has the purpose that it had in the days of the VT100. It is used for any time you open a shell other than opening a Terminal window. So if you shell out of Emacs or vi, or if you do a su user.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 14 '14 at 19:22









      Community

      1




      1










      answered Mar 14 '14 at 2:00









      Alan Shutko

      1,4111011




      1,4111011











      • The Debian page you're quoting explains why Debian's .profile sources .bashrc, not why OSX decided to make all shells login shells by default. Actually, you are answering another question of mine, and thanks! However, your answer does not explain the OSX choice and the Debian quote is completely irrelevant here as far as I can tell (please let me know if I'm just missing the point). The OSX way make .bashrc etc useless and does not make .profile any more useful.
        – terdon
        Mar 14 '14 at 4:28
















      • The Debian page you're quoting explains why Debian's .profile sources .bashrc, not why OSX decided to make all shells login shells by default. Actually, you are answering another question of mine, and thanks! However, your answer does not explain the OSX choice and the Debian quote is completely irrelevant here as far as I can tell (please let me know if I'm just missing the point). The OSX way make .bashrc etc useless and does not make .profile any more useful.
        – terdon
        Mar 14 '14 at 4:28















      The Debian page you're quoting explains why Debian's .profile sources .bashrc, not why OSX decided to make all shells login shells by default. Actually, you are answering another question of mine, and thanks! However, your answer does not explain the OSX choice and the Debian quote is completely irrelevant here as far as I can tell (please let me know if I'm just missing the point). The OSX way make .bashrc etc useless and does not make .profile any more useful.
      – terdon
      Mar 14 '14 at 4:28




      The Debian page you're quoting explains why Debian's .profile sources .bashrc, not why OSX decided to make all shells login shells by default. Actually, you are answering another question of mine, and thanks! However, your answer does not explain the OSX choice and the Debian quote is completely irrelevant here as far as I can tell (please let me know if I'm just missing the point). The OSX way make .bashrc etc useless and does not make .profile any more useful.
      – terdon
      Mar 14 '14 at 4:28










      up vote
      4
      down vote













      I don't know why they would have done that. However, here's my guess.



      To start with, it's worth noting that on a GNU/Linux system, you can of course switch to vt1, vt2, etc. You get a login shell there. On an OS X system, there's no equivalent. The only way to access the UNIX underpinnings is through a terminal emulator or through single user mode (disclaimer: I've never actually used single user mode; it's commandline-driven IIRC but I may be wrong). Therefore, in OS X whatever the default is in the emulator is the default for the entire system.



      Now, why would you make the default a login shell? There are a couple (read: not many) reasons I can think of to do this.



      • It provides a consistent user experience if you SSH into the box. (Especially important for the server edition of OS X - presumably if you're running an OS X server, you're a newbie.)

      • The default shell of OS X used to be tcsh. This is about as wild a guess as you can get, but it may be that tcsh normally did something when run as a login shell, and the historical pattern stuck. (I doubt it, though - maybe one of the older regulars could tell us.)

      • "We are Apple. We are the vendors of the largest UNIX distribution on the planet. It doesn't matter how trivial our reasons are; if we make a decision, your tool must deal with it."

      Honestly, I've been using Darwin for ~6 years and I can't answer this question properly. It doesn't really make sense to me, either.



      To answer your subquestion, bash is not patched or anything (at least for this). The default terminal emulator runs login shells by default, and presumably iTerm copies that.






      share|improve this answer
















      • 1




        +1 for mentioning tcsh, since its behavior is far saner in this respect than that of bash: when started as an interactive login shell, tcsh sources both .profile and .tcshrc / .cshrc without requiring any kluges like the one I gave in my answer. Given that, I suspect this behavior is an unfixed regression caused by the switch from tcsh to bash.
        – Ilmari Karonen
        Mar 14 '14 at 17:09











      • @IlmariKaronen Do you mean (here and there) that tcsh sources .login and .tcshrc/.cshrc? It would make no sense for tcsh to source .profile; it typically contains commands with sh syntax that tcsh won't accept. I don't have macOS but I made /bin/tcsh my login shell on Ubuntu 16.04. .profile isn't sourced. tcsh(1) doesn't mention that file, nor does this tcsh(1).
        – Eliah Kagan
        Oct 17 '17 at 19:23














      up vote
      4
      down vote













      I don't know why they would have done that. However, here's my guess.



      To start with, it's worth noting that on a GNU/Linux system, you can of course switch to vt1, vt2, etc. You get a login shell there. On an OS X system, there's no equivalent. The only way to access the UNIX underpinnings is through a terminal emulator or through single user mode (disclaimer: I've never actually used single user mode; it's commandline-driven IIRC but I may be wrong). Therefore, in OS X whatever the default is in the emulator is the default for the entire system.



      Now, why would you make the default a login shell? There are a couple (read: not many) reasons I can think of to do this.



      • It provides a consistent user experience if you SSH into the box. (Especially important for the server edition of OS X - presumably if you're running an OS X server, you're a newbie.)

      • The default shell of OS X used to be tcsh. This is about as wild a guess as you can get, but it may be that tcsh normally did something when run as a login shell, and the historical pattern stuck. (I doubt it, though - maybe one of the older regulars could tell us.)

      • "We are Apple. We are the vendors of the largest UNIX distribution on the planet. It doesn't matter how trivial our reasons are; if we make a decision, your tool must deal with it."

      Honestly, I've been using Darwin for ~6 years and I can't answer this question properly. It doesn't really make sense to me, either.



      To answer your subquestion, bash is not patched or anything (at least for this). The default terminal emulator runs login shells by default, and presumably iTerm copies that.






      share|improve this answer
















      • 1




        +1 for mentioning tcsh, since its behavior is far saner in this respect than that of bash: when started as an interactive login shell, tcsh sources both .profile and .tcshrc / .cshrc without requiring any kluges like the one I gave in my answer. Given that, I suspect this behavior is an unfixed regression caused by the switch from tcsh to bash.
        – Ilmari Karonen
        Mar 14 '14 at 17:09











      • @IlmariKaronen Do you mean (here and there) that tcsh sources .login and .tcshrc/.cshrc? It would make no sense for tcsh to source .profile; it typically contains commands with sh syntax that tcsh won't accept. I don't have macOS but I made /bin/tcsh my login shell on Ubuntu 16.04. .profile isn't sourced. tcsh(1) doesn't mention that file, nor does this tcsh(1).
        – Eliah Kagan
        Oct 17 '17 at 19:23












      up vote
      4
      down vote










      up vote
      4
      down vote









      I don't know why they would have done that. However, here's my guess.



      To start with, it's worth noting that on a GNU/Linux system, you can of course switch to vt1, vt2, etc. You get a login shell there. On an OS X system, there's no equivalent. The only way to access the UNIX underpinnings is through a terminal emulator or through single user mode (disclaimer: I've never actually used single user mode; it's commandline-driven IIRC but I may be wrong). Therefore, in OS X whatever the default is in the emulator is the default for the entire system.



      Now, why would you make the default a login shell? There are a couple (read: not many) reasons I can think of to do this.



      • It provides a consistent user experience if you SSH into the box. (Especially important for the server edition of OS X - presumably if you're running an OS X server, you're a newbie.)

      • The default shell of OS X used to be tcsh. This is about as wild a guess as you can get, but it may be that tcsh normally did something when run as a login shell, and the historical pattern stuck. (I doubt it, though - maybe one of the older regulars could tell us.)

      • "We are Apple. We are the vendors of the largest UNIX distribution on the planet. It doesn't matter how trivial our reasons are; if we make a decision, your tool must deal with it."

      Honestly, I've been using Darwin for ~6 years and I can't answer this question properly. It doesn't really make sense to me, either.



      To answer your subquestion, bash is not patched or anything (at least for this). The default terminal emulator runs login shells by default, and presumably iTerm copies that.






      share|improve this answer












      I don't know why they would have done that. However, here's my guess.



      To start with, it's worth noting that on a GNU/Linux system, you can of course switch to vt1, vt2, etc. You get a login shell there. On an OS X system, there's no equivalent. The only way to access the UNIX underpinnings is through a terminal emulator or through single user mode (disclaimer: I've never actually used single user mode; it's commandline-driven IIRC but I may be wrong). Therefore, in OS X whatever the default is in the emulator is the default for the entire system.



      Now, why would you make the default a login shell? There are a couple (read: not many) reasons I can think of to do this.



      • It provides a consistent user experience if you SSH into the box. (Especially important for the server edition of OS X - presumably if you're running an OS X server, you're a newbie.)

      • The default shell of OS X used to be tcsh. This is about as wild a guess as you can get, but it may be that tcsh normally did something when run as a login shell, and the historical pattern stuck. (I doubt it, though - maybe one of the older regulars could tell us.)

      • "We are Apple. We are the vendors of the largest UNIX distribution on the planet. It doesn't matter how trivial our reasons are; if we make a decision, your tool must deal with it."

      Honestly, I've been using Darwin for ~6 years and I can't answer this question properly. It doesn't really make sense to me, either.



      To answer your subquestion, bash is not patched or anything (at least for this). The default terminal emulator runs login shells by default, and presumably iTerm copies that.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Mar 14 '14 at 1:42









      strugee

      8,1141253102




      8,1141253102







      • 1




        +1 for mentioning tcsh, since its behavior is far saner in this respect than that of bash: when started as an interactive login shell, tcsh sources both .profile and .tcshrc / .cshrc without requiring any kluges like the one I gave in my answer. Given that, I suspect this behavior is an unfixed regression caused by the switch from tcsh to bash.
        – Ilmari Karonen
        Mar 14 '14 at 17:09











      • @IlmariKaronen Do you mean (here and there) that tcsh sources .login and .tcshrc/.cshrc? It would make no sense for tcsh to source .profile; it typically contains commands with sh syntax that tcsh won't accept. I don't have macOS but I made /bin/tcsh my login shell on Ubuntu 16.04. .profile isn't sourced. tcsh(1) doesn't mention that file, nor does this tcsh(1).
        – Eliah Kagan
        Oct 17 '17 at 19:23












      • 1




        +1 for mentioning tcsh, since its behavior is far saner in this respect than that of bash: when started as an interactive login shell, tcsh sources both .profile and .tcshrc / .cshrc without requiring any kluges like the one I gave in my answer. Given that, I suspect this behavior is an unfixed regression caused by the switch from tcsh to bash.
        – Ilmari Karonen
        Mar 14 '14 at 17:09











      • @IlmariKaronen Do you mean (here and there) that tcsh sources .login and .tcshrc/.cshrc? It would make no sense for tcsh to source .profile; it typically contains commands with sh syntax that tcsh won't accept. I don't have macOS but I made /bin/tcsh my login shell on Ubuntu 16.04. .profile isn't sourced. tcsh(1) doesn't mention that file, nor does this tcsh(1).
        – Eliah Kagan
        Oct 17 '17 at 19:23







      1




      1




      +1 for mentioning tcsh, since its behavior is far saner in this respect than that of bash: when started as an interactive login shell, tcsh sources both .profile and .tcshrc / .cshrc without requiring any kluges like the one I gave in my answer. Given that, I suspect this behavior is an unfixed regression caused by the switch from tcsh to bash.
      – Ilmari Karonen
      Mar 14 '14 at 17:09





      +1 for mentioning tcsh, since its behavior is far saner in this respect than that of bash: when started as an interactive login shell, tcsh sources both .profile and .tcshrc / .cshrc without requiring any kluges like the one I gave in my answer. Given that, I suspect this behavior is an unfixed regression caused by the switch from tcsh to bash.
      – Ilmari Karonen
      Mar 14 '14 at 17:09













      @IlmariKaronen Do you mean (here and there) that tcsh sources .login and .tcshrc/.cshrc? It would make no sense for tcsh to source .profile; it typically contains commands with sh syntax that tcsh won't accept. I don't have macOS but I made /bin/tcsh my login shell on Ubuntu 16.04. .profile isn't sourced. tcsh(1) doesn't mention that file, nor does this tcsh(1).
      – Eliah Kagan
      Oct 17 '17 at 19:23




      @IlmariKaronen Do you mean (here and there) that tcsh sources .login and .tcshrc/.cshrc? It would make no sense for tcsh to source .profile; it typically contains commands with sh syntax that tcsh won't accept. I don't have macOS but I made /bin/tcsh my login shell on Ubuntu 16.04. .profile isn't sourced. tcsh(1) doesn't mention that file, nor does this tcsh(1).
      – Eliah Kagan
      Oct 17 '17 at 19:23










      up vote
      3
      down vote













      This is an update to current status: the answers have become stale as new MacOSX versions have been released and login behavior has changed.



      This question was asked and answered in 2014. I've been researching the subject in an attempt to build a common .bashrc & .bash_profile set to use across different Linux distros and BSD (whatever they call them if they're not distros).



      I recently bought a used Mac Mini with Sierra installed, so I now have systems with 10.6, 10.10, 10.11, and 10.12. Although I have munged the older ones (leaving clues to their previous status), the 10.12 Sierra installation is untouched.



      Results: In 10.12 Sierra, there is NO default .bashrc, .bash_profile, or .profile created. In /etc, there are bashrc, bashrc_Apple_Terminal, and profile. Contents of /etc/profile:



      # System-wide .profile for sh(1)

      if [ -x /usr/libexec/path_helper ]; then
      eval `/usr/libexec/path_helper -s`
      fi

      if [ "$BASH-no" != "no" ]; then
      [ -r /etc/bashrc ] && . /etc/bashrc
      fi


      Contents of /etc/bashrc:



      # System-wide .bashrc file for interactive bash(1) shells.
      if [ -z "$PS1" ]; then
      return
      fi

      PS1='h:W u$ '
      # Make bash check its window size after a process completes
      shopt -s checkwinsize

      [ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"


      The /etc/bashrc_Apple_Terminal script sets the PROMPT_COMMAND variable and sets up a mechanism for preserving session state for each terminal; if the terminal app is quit, the status of previous session is restored when the app is started again. Otherwise, almost nothing (minimal $PS1) is set in /etc/bashrc, leaving any other customization (real $PS1, aliases, functions) to be set in ~/.bashrc and $PATH settings in .bash_profile (or in .profile, sourced in by .bash_profile).



      I have confirmed that iTerm2 behaves the same way as the Terminal app, except that the default behavior of starting a login session is visible and can be edited.



      If you run an X11 (now XQuartz) XTerm terminal session, you will see a non-login session, the same as on a Linux system; .bash_profile (or .profile) is skipped, and you just get .bashrc.



      And, here's my answer:



      Although the Terminal app claims to be an xterm (TERM=xterm-256color), it does not set the $DISPLAY variable unless X11 is installed. We are seeing a simulation of an X environment, but not a completely real one. If you SSH into another system with the -X switch (enable X11 forwarding), it will fail because there is no $DISPLAY variable. If you have installed X11, then SSH into another system, X11 forwarding will succeed.



      Bottom line (and short answer): The Terminal app is not a true X11 terminal (does not set $DISPLAY); it behaves much more like an SSH login than an XTerm session, in that it has to be a login session in order to set values from /etc/profile and ~/.bash_profile or ~/.profile






      share|improve this answer
























        up vote
        3
        down vote













        This is an update to current status: the answers have become stale as new MacOSX versions have been released and login behavior has changed.



        This question was asked and answered in 2014. I've been researching the subject in an attempt to build a common .bashrc & .bash_profile set to use across different Linux distros and BSD (whatever they call them if they're not distros).



        I recently bought a used Mac Mini with Sierra installed, so I now have systems with 10.6, 10.10, 10.11, and 10.12. Although I have munged the older ones (leaving clues to their previous status), the 10.12 Sierra installation is untouched.



        Results: In 10.12 Sierra, there is NO default .bashrc, .bash_profile, or .profile created. In /etc, there are bashrc, bashrc_Apple_Terminal, and profile. Contents of /etc/profile:



        # System-wide .profile for sh(1)

        if [ -x /usr/libexec/path_helper ]; then
        eval `/usr/libexec/path_helper -s`
        fi

        if [ "$BASH-no" != "no" ]; then
        [ -r /etc/bashrc ] && . /etc/bashrc
        fi


        Contents of /etc/bashrc:



        # System-wide .bashrc file for interactive bash(1) shells.
        if [ -z "$PS1" ]; then
        return
        fi

        PS1='h:W u$ '
        # Make bash check its window size after a process completes
        shopt -s checkwinsize

        [ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"


        The /etc/bashrc_Apple_Terminal script sets the PROMPT_COMMAND variable and sets up a mechanism for preserving session state for each terminal; if the terminal app is quit, the status of previous session is restored when the app is started again. Otherwise, almost nothing (minimal $PS1) is set in /etc/bashrc, leaving any other customization (real $PS1, aliases, functions) to be set in ~/.bashrc and $PATH settings in .bash_profile (or in .profile, sourced in by .bash_profile).



        I have confirmed that iTerm2 behaves the same way as the Terminal app, except that the default behavior of starting a login session is visible and can be edited.



        If you run an X11 (now XQuartz) XTerm terminal session, you will see a non-login session, the same as on a Linux system; .bash_profile (or .profile) is skipped, and you just get .bashrc.



        And, here's my answer:



        Although the Terminal app claims to be an xterm (TERM=xterm-256color), it does not set the $DISPLAY variable unless X11 is installed. We are seeing a simulation of an X environment, but not a completely real one. If you SSH into another system with the -X switch (enable X11 forwarding), it will fail because there is no $DISPLAY variable. If you have installed X11, then SSH into another system, X11 forwarding will succeed.



        Bottom line (and short answer): The Terminal app is not a true X11 terminal (does not set $DISPLAY); it behaves much more like an SSH login than an XTerm session, in that it has to be a login session in order to set values from /etc/profile and ~/.bash_profile or ~/.profile






        share|improve this answer






















          up vote
          3
          down vote










          up vote
          3
          down vote









          This is an update to current status: the answers have become stale as new MacOSX versions have been released and login behavior has changed.



          This question was asked and answered in 2014. I've been researching the subject in an attempt to build a common .bashrc & .bash_profile set to use across different Linux distros and BSD (whatever they call them if they're not distros).



          I recently bought a used Mac Mini with Sierra installed, so I now have systems with 10.6, 10.10, 10.11, and 10.12. Although I have munged the older ones (leaving clues to their previous status), the 10.12 Sierra installation is untouched.



          Results: In 10.12 Sierra, there is NO default .bashrc, .bash_profile, or .profile created. In /etc, there are bashrc, bashrc_Apple_Terminal, and profile. Contents of /etc/profile:



          # System-wide .profile for sh(1)

          if [ -x /usr/libexec/path_helper ]; then
          eval `/usr/libexec/path_helper -s`
          fi

          if [ "$BASH-no" != "no" ]; then
          [ -r /etc/bashrc ] && . /etc/bashrc
          fi


          Contents of /etc/bashrc:



          # System-wide .bashrc file for interactive bash(1) shells.
          if [ -z "$PS1" ]; then
          return
          fi

          PS1='h:W u$ '
          # Make bash check its window size after a process completes
          shopt -s checkwinsize

          [ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"


          The /etc/bashrc_Apple_Terminal script sets the PROMPT_COMMAND variable and sets up a mechanism for preserving session state for each terminal; if the terminal app is quit, the status of previous session is restored when the app is started again. Otherwise, almost nothing (minimal $PS1) is set in /etc/bashrc, leaving any other customization (real $PS1, aliases, functions) to be set in ~/.bashrc and $PATH settings in .bash_profile (or in .profile, sourced in by .bash_profile).



          I have confirmed that iTerm2 behaves the same way as the Terminal app, except that the default behavior of starting a login session is visible and can be edited.



          If you run an X11 (now XQuartz) XTerm terminal session, you will see a non-login session, the same as on a Linux system; .bash_profile (or .profile) is skipped, and you just get .bashrc.



          And, here's my answer:



          Although the Terminal app claims to be an xterm (TERM=xterm-256color), it does not set the $DISPLAY variable unless X11 is installed. We are seeing a simulation of an X environment, but not a completely real one. If you SSH into another system with the -X switch (enable X11 forwarding), it will fail because there is no $DISPLAY variable. If you have installed X11, then SSH into another system, X11 forwarding will succeed.



          Bottom line (and short answer): The Terminal app is not a true X11 terminal (does not set $DISPLAY); it behaves much more like an SSH login than an XTerm session, in that it has to be a login session in order to set values from /etc/profile and ~/.bash_profile or ~/.profile






          share|improve this answer












          This is an update to current status: the answers have become stale as new MacOSX versions have been released and login behavior has changed.



          This question was asked and answered in 2014. I've been researching the subject in an attempt to build a common .bashrc & .bash_profile set to use across different Linux distros and BSD (whatever they call them if they're not distros).



          I recently bought a used Mac Mini with Sierra installed, so I now have systems with 10.6, 10.10, 10.11, and 10.12. Although I have munged the older ones (leaving clues to their previous status), the 10.12 Sierra installation is untouched.



          Results: In 10.12 Sierra, there is NO default .bashrc, .bash_profile, or .profile created. In /etc, there are bashrc, bashrc_Apple_Terminal, and profile. Contents of /etc/profile:



          # System-wide .profile for sh(1)

          if [ -x /usr/libexec/path_helper ]; then
          eval `/usr/libexec/path_helper -s`
          fi

          if [ "$BASH-no" != "no" ]; then
          [ -r /etc/bashrc ] && . /etc/bashrc
          fi


          Contents of /etc/bashrc:



          # System-wide .bashrc file for interactive bash(1) shells.
          if [ -z "$PS1" ]; then
          return
          fi

          PS1='h:W u$ '
          # Make bash check its window size after a process completes
          shopt -s checkwinsize

          [ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"


          The /etc/bashrc_Apple_Terminal script sets the PROMPT_COMMAND variable and sets up a mechanism for preserving session state for each terminal; if the terminal app is quit, the status of previous session is restored when the app is started again. Otherwise, almost nothing (minimal $PS1) is set in /etc/bashrc, leaving any other customization (real $PS1, aliases, functions) to be set in ~/.bashrc and $PATH settings in .bash_profile (or in .profile, sourced in by .bash_profile).



          I have confirmed that iTerm2 behaves the same way as the Terminal app, except that the default behavior of starting a login session is visible and can be edited.



          If you run an X11 (now XQuartz) XTerm terminal session, you will see a non-login session, the same as on a Linux system; .bash_profile (or .profile) is skipped, and you just get .bashrc.



          And, here's my answer:



          Although the Terminal app claims to be an xterm (TERM=xterm-256color), it does not set the $DISPLAY variable unless X11 is installed. We are seeing a simulation of an X environment, but not a completely real one. If you SSH into another system with the -X switch (enable X11 forwarding), it will fail because there is no $DISPLAY variable. If you have installed X11, then SSH into another system, X11 forwarding will succeed.



          Bottom line (and short answer): The Terminal app is not a true X11 terminal (does not set $DISPLAY); it behaves much more like an SSH login than an XTerm session, in that it has to be a login session in order to set values from /etc/profile and ~/.bash_profile or ~/.profile







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jul 9 '17 at 18:42









          donls

          312




          312




















              up vote
              0
              down vote













              The answers above explained the reason why interactive shells are login shells on macOS by default: settings in /etc/profile, ~/.profile are inherited by a non-login shell on X-based systems, but not on macOS. Here I wanna remind you that you should always use login shell on macOS because of the existence of path_helper:



              ❯ cat /etc/profile # or cat /etc/zprofile
              # System-wide .profile for sh(1)

              if [ -x /usr/libexec/path_helper ]; then
              eval `/usr/libexec/path_helper -s`
              fi

              if [ "$BASH-no" != "no" ]; then
              [ -r /etc/bashrc ] && . /etc/bashrc
              fi



              The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d
              and appends their contents to the PATH and MANPATH environment variables respectively. (The MANPATH envi-
              ronment variable will not be modified unless it is already set in the environment.)




              If you're using a non-login shell, some paths will not be imported.



              I think it's always a good idea for developer to put a file into /etc/paths.d to import their path values, but not to symlink the callable binaries into locations like /usr/bin or /bin. (The default PATH is /usr/bin:/bin:/usr/sbin:/sbin. Not everyone uses Homebrew or MacPorts adding custom values into PATH. So there's not always a safe place to put the symlinks of callable commands.)



              Here is an example of files in /etc/paths.d. Basically you're putting one value each line.



              ❯ cat /etc/paths.d/Wireshark
              /Applications/Wireshark.app/Contents/MacOS


              Reference:



              • Mastering the path_helper utility of MacOSX

              • man path_helper





              share|improve this answer


























                up vote
                0
                down vote













                The answers above explained the reason why interactive shells are login shells on macOS by default: settings in /etc/profile, ~/.profile are inherited by a non-login shell on X-based systems, but not on macOS. Here I wanna remind you that you should always use login shell on macOS because of the existence of path_helper:



                ❯ cat /etc/profile # or cat /etc/zprofile
                # System-wide .profile for sh(1)

                if [ -x /usr/libexec/path_helper ]; then
                eval `/usr/libexec/path_helper -s`
                fi

                if [ "$BASH-no" != "no" ]; then
                [ -r /etc/bashrc ] && . /etc/bashrc
                fi



                The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d
                and appends their contents to the PATH and MANPATH environment variables respectively. (The MANPATH envi-
                ronment variable will not be modified unless it is already set in the environment.)




                If you're using a non-login shell, some paths will not be imported.



                I think it's always a good idea for developer to put a file into /etc/paths.d to import their path values, but not to symlink the callable binaries into locations like /usr/bin or /bin. (The default PATH is /usr/bin:/bin:/usr/sbin:/sbin. Not everyone uses Homebrew or MacPorts adding custom values into PATH. So there's not always a safe place to put the symlinks of callable commands.)



                Here is an example of files in /etc/paths.d. Basically you're putting one value each line.



                ❯ cat /etc/paths.d/Wireshark
                /Applications/Wireshark.app/Contents/MacOS


                Reference:



                • Mastering the path_helper utility of MacOSX

                • man path_helper





                share|improve this answer
























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  The answers above explained the reason why interactive shells are login shells on macOS by default: settings in /etc/profile, ~/.profile are inherited by a non-login shell on X-based systems, but not on macOS. Here I wanna remind you that you should always use login shell on macOS because of the existence of path_helper:



                  ❯ cat /etc/profile # or cat /etc/zprofile
                  # System-wide .profile for sh(1)

                  if [ -x /usr/libexec/path_helper ]; then
                  eval `/usr/libexec/path_helper -s`
                  fi

                  if [ "$BASH-no" != "no" ]; then
                  [ -r /etc/bashrc ] && . /etc/bashrc
                  fi



                  The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d
                  and appends their contents to the PATH and MANPATH environment variables respectively. (The MANPATH envi-
                  ronment variable will not be modified unless it is already set in the environment.)




                  If you're using a non-login shell, some paths will not be imported.



                  I think it's always a good idea for developer to put a file into /etc/paths.d to import their path values, but not to symlink the callable binaries into locations like /usr/bin or /bin. (The default PATH is /usr/bin:/bin:/usr/sbin:/sbin. Not everyone uses Homebrew or MacPorts adding custom values into PATH. So there's not always a safe place to put the symlinks of callable commands.)



                  Here is an example of files in /etc/paths.d. Basically you're putting one value each line.



                  ❯ cat /etc/paths.d/Wireshark
                  /Applications/Wireshark.app/Contents/MacOS


                  Reference:



                  • Mastering the path_helper utility of MacOSX

                  • man path_helper





                  share|improve this answer














                  The answers above explained the reason why interactive shells are login shells on macOS by default: settings in /etc/profile, ~/.profile are inherited by a non-login shell on X-based systems, but not on macOS. Here I wanna remind you that you should always use login shell on macOS because of the existence of path_helper:



                  ❯ cat /etc/profile # or cat /etc/zprofile
                  # System-wide .profile for sh(1)

                  if [ -x /usr/libexec/path_helper ]; then
                  eval `/usr/libexec/path_helper -s`
                  fi

                  if [ "$BASH-no" != "no" ]; then
                  [ -r /etc/bashrc ] && . /etc/bashrc
                  fi



                  The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d
                  and appends their contents to the PATH and MANPATH environment variables respectively. (The MANPATH envi-
                  ronment variable will not be modified unless it is already set in the environment.)




                  If you're using a non-login shell, some paths will not be imported.



                  I think it's always a good idea for developer to put a file into /etc/paths.d to import their path values, but not to symlink the callable binaries into locations like /usr/bin or /bin. (The default PATH is /usr/bin:/bin:/usr/sbin:/sbin. Not everyone uses Homebrew or MacPorts adding custom values into PATH. So there's not always a safe place to put the symlinks of callable commands.)



                  Here is an example of files in /etc/paths.d. Basically you're putting one value each line.



                  ❯ cat /etc/paths.d/Wireshark
                  /Applications/Wireshark.app/Contents/MacOS


                  Reference:



                  • Mastering the path_helper utility of MacOSX

                  • man path_helper






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 25 at 13:27

























                  answered Nov 25 at 13:21









                  Simba

                  11




                  11



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f119627%2fwhy-are-interactive-shells-on-osx-login-shells-by-default%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown






                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Bahrain

                      Postfix configuration issue with fips on centos 7; mailgun relay