Why are interactive shells on OSX login shells by default?
Clash Royale CLAN TAG#URR8PPP
up vote
34
down vote
favorite
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
add a comment |
up vote
34
down vote
favorite
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
1
Terminal.app runs a login shell. I don't know why Apple chose to do that.
– Gilles
Mar 14 '14 at 1:29
add a comment |
up vote
34
down vote
favorite
up vote
34
down vote
favorite
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
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
bash osx
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
add a comment |
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
add a comment |
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.
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
|
show 8 more comments
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.
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
add a comment |
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 thattcsh
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.
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 withsh
syntax thattcsh
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
add a comment |
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
add a comment |
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 thePATH
andMANPATH
environment variables respectively. (TheMANPATH
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
add a comment |
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.
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
|
show 8 more comments
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.
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
|
show 8 more comments
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.
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.
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
|
show 8 more comments
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
|
show 8 more comments
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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 thattcsh
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.
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 withsh
syntax thattcsh
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
add a comment |
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 thattcsh
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.
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 withsh
syntax thattcsh
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
add a comment |
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 thattcsh
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.
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 thattcsh
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.
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 withsh
syntax thattcsh
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
add a comment |
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 withsh
syntax thattcsh
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
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Jul 9 '17 at 18:42
donls
312
312
add a comment |
add a comment |
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 thePATH
andMANPATH
environment variables respectively. (TheMANPATH
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
add a comment |
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 thePATH
andMANPATH
environment variables respectively. (TheMANPATH
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
add a comment |
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 thePATH
andMANPATH
environment variables respectively. (TheMANPATH
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
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 thePATH
andMANPATH
environment variables respectively. (TheMANPATH
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
edited Nov 25 at 13:27
answered Nov 25 at 13:21
Simba
11
11
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
Terminal.app runs a login shell. I don't know why Apple chose to do that.
– Gilles
Mar 14 '14 at 1:29