What is the difference between the various shell profiles? - bash

What's the difference between ~/.bashrc, ~/.bash_login, ~/.bash_logout, ~/.bash_profile, ~/.profile, /etc/profile, /etc/bash.bashrc, /etc/ssh/ssh_config and sshd_config, when are they loaded and what are their purposes?

The man page for bash says there are the following initialization files for bash shells:
/etc/profile
The systemwide initialization file, executed for login shells
/etc/bash.bashrc
The systemwide per-interactive-shell startup file
/etc/bash.bash.logout
The systemwide login shell cleanup file, executed when a login shell exits
~/.bash_profile
The personal initialization file, executed for login shells
~/.bashrc
The individual per-interactive-shell startup file
~/.bash_logout
The individual login shell cleanup file, executed when a login shell exits
~/.inputrc
Individual readline initialization file
Apparently there seem to be different configuration files for the different shells (bash, zsh, csh, and others). There seem to be as many shells as different linux and unix versions: csh, ksh, bash, zsh, ... Bash has a .bashrc, Zsh has a .zshrc, etc. One can also distinguish between login shells and non-login shells and between system-wide defaults and user-specific defaults.
It makes sense to distinguish between login and non-login shells, because some commands should be processed only at login, while other commands should run everytime you open a new terminal window. That is the difference between .bash_profile and .bashrc. For bash the .bashrc is reloaded every time you start a new copy of bash, i.e. when you start a new bash but do not login. The .bash_profile or .profile is loaded only when you login. The abbtreviation rc in bashrc stands for "run commands" or "run control" and is a convention adopted from older Unix systems.
system-wide defaults for..
/etc/profile ..login shells, for interactive shells with login
/etc/bashrc ..non-login Bash shells
user-specific defaults in home directory ~ for..
~/.profile ..login shells, called after login
~/.bashrc ..non-login shells, if already logged in
~/.bash_profile ..login shells, called after login (lower priority)
user-specific defaults in home directory for login and logout
~/.bash_login ..login shells (called upon login)
~/.bash_logout ..login shells (called upon logout)
The following links were helpful: .bashrc vs .bashprofile and .bash_profile vs .bashrc, the bash manual page (man bash), and Zsh/Bash startup files loading order (.bashrc, .zshrc etc.).

I happen to be curious about these files and did some experiment myself. It turns out to be a little different than what is in the documents.
I know the differences between interactive and non-interactive or login and non-login.
I tried on two computers, my macbook pro with OS 10.9 and a server with ubuntu server 13.10. I add the following command into the /etc/profile:
echo "Loading /etc/profile"
And similar commands into /etc/bash.bashrc, /etc/bashrc, /etc/bash.bashrc, ~/.profile, ~/.bash_profile, ~/.bashrc, ~/.bash_login and make sure that these files do not source each other inside themselves.
(OS 10.9, GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13))
On the mac, with interactive login bash, I have:
Loading /etc/profile
Loading ~/.bash_profile
Which means that the files loaded directly are only /etc/profile and ~/.bash_profile.
with interactive non-login bash, I have:
Loading ~/.bashrc
which means that the file loaded directly is ~/.bashrc.
(ubuntu server 13.10 GNU bash, version 4.2.45(1)-release (x86_64-pc-linux-gnu))
On the ubuntu, with interactive login bash, I have:
Loading /etc/profile
Loading ~/.bash_profile
Which means that the files loaded directly are only /etc/profile and ~/.bash_profile.
with interactive non-login bash, I have:
Loading /etc/bash.bashrc
Loading ~/.bashrc
which means that the files loaded directly are /etc/bash.bashrc and ~/.bashrc.
I do not know why~

Related

Terminal opened in vim doesn't have .bash_profile sourced implicitly

I am running vim 8.2 and when I execute the command "term" inside vim, it opens up a terminal in the same window but it doesn't have the .bash_profile sourced implicitly. I need to do that before using the terminal.
Is there a way to fix this?
According to the bash man page:
.bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells.
When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists.
Since you are using, non-login shell, I would suggest you to put all your aliases, shell options in the bashrc.

Where to place $PATH variable assertions in zsh?

I love zsh, but I am not sure where to place my $PATH and other variable assertions? I find that they are scattered between the files .zshrc .zprofile .bashrc .bash_profile, and sometimes doubled.
I realize that having anything inside the bash files doesn't make much sense seeing as I'm using zsh, but where exactly should I be placing my rvm, python, node etc additions to my $PATH?
Is there a specific file I should be using (i.e. .zshenv which does not currently exist in my installation), one of the ones I am currently using, or does it even matter?
tl;dr version: use ~/.zshrc
And read the man page to understand the differences between:
~/.zshrc, ~/.zshenv and ~/.zprofile.
Regarding my comment
In my comment attached to the answer kev gave, I said:
This seems to be incorrect - /etc/profile isn't listed in any zsh documentation I can find.
This turns out to be partially incorrect: /etc/profile may be sourced by zsh. However, this only occurs if zsh is "invoked as sh or ksh"; in these compatibility modes:
The usual zsh startup/shutdown scripts are not executed. Login shells source /etc/profile followed by $HOME/.profile. If the ENV environment variable is set on invocation, $ENV is sourced after the profile scripts. The value of ENV is subjected to parameter expansion, command substitution, and arithmetic expansion before being interpreted as a pathname. [man zshall, "Compatibility"].
The ArchWiki ZSH link says:
At login, Zsh sources the following files in this order:
/etc/profile
This file is sourced by all Bourne-compatible shells upon login
This implys that /etc/profile is always read by zsh at login - I haven't got any experience with the Arch Linux project; the wiki may be correct for that distribution, but it is not generally correct. The information is incorrect compared to the zsh manual pages, and doesn't seem to apply to zsh on OS X (paths in $PATH set in /etc/profile do not make it to my zsh sessions).
To address the question:
where exactly should I be placing my rvm, python, node etc additions to my $PATH?
Generally, I would export my $PATH from ~/.zshrc, but it's worth having a read of the zshall man page, specifically the "STARTUP/SHUTDOWN FILES" section - ~/.zshrc is read for interactive shells, which may or may not suit your needs - if you want the $PATH for every zsh shell invoked by you (both interactive and not, both login and not, etc), then ~/.zshenv is a better option.
Is there a specific file I should be using (i.e. .zshenv which does not currently exist in my installation), one of the ones I am currently using, or does it even matter?
There's a bunch of files read on startup (check the linked man pages), and there's a reason for that - each file has it's particular place (settings for every user, settings for user-specific, settings for login shells, settings for every shell, etc).
Don't worry about ~/.zshenv not existing - if you need it, make it, and it will be read.
.bashrc and .bash_profile are not read by zsh, unless you explicitly source them from ~/.zshrc or similar; the syntax between bash and zsh is not always compatible. Both .bashrc and .bash_profile are designed for bash settings, not zsh settings.
Here is the docs from the zsh man pages under STARTUP/SHUTDOWN FILES section.
Commands are first read from /etc/zshenv this cannot be overridden.
Subsequent behaviour is modified by the RCS and GLOBAL_RCS options; the
former affects all startup files, while the second only affects global
startup files (those shown here with an path starting with a /). If
one of the options is unset at any point, any subsequent startup
file(s) of the corresponding type will not be read. It is also possi-
ble for a file in $ZDOTDIR to re-enable GLOBAL_RCS. Both RCS and
GLOBAL_RCS are set by default.
Commands are then read from $ZDOTDIR/.zshenv. If the shell is a login
shell, commands are read from /etc/zprofile and then $ZDOTDIR/.zpro-
file. Then, if the shell is interactive, commands are read from
/etc/zshrc and then $ZDOTDIR/.zshrc. Finally, if the shell is a login
shell, /etc/zlogin and $ZDOTDIR/.zlogin are read.
From this we can see the order files are read is:
/etc/zshenv # Read for every shell
~/.zshenv # Read for every shell except ones started with -f
/etc/zprofile # Global config for login shells, read before zshrc
~/.zprofile # User config for login shells
/etc/zshrc # Global config for interactive shells
~/.zshrc # User config for interactive shells
/etc/zlogin # Global config for login shells, read after zshrc
~/.zlogin # User config for login shells
~/.zlogout # User config for login shells, read upon logout
/etc/zlogout # Global config for login shells, read after user logout file
You can get more information here.
I had similar problem (in bash terminal command was working correctly but zsh showed command not found error)
Solution:
just paste whatever you were earlier pasting in ~/.bashrc to:
~/.zshrc

Why do I have to keep using `source ~/.profile` to get settings in place?

I have a couple of bash scripts that I want to make sure runs by default and I'm currently storing them in ~/.profile on my mac. Is that the wrong place to be storing them? I've heard of others and tried them (like ~/.bashrc, ~/.bash_profile, etc), but they don't seem to be working.
What is the difference between all of these and which one do I put the scripts in so that it configures on runtime and I don't have to call $ source ~/.profile every time I open the terminal?
If both ~/.bash_profile and ~/.profile exist, bash only reads ~/.bash_profile when it is invoked as an interactive login shell.
https://www.gnu.org/s/bash/manual/html_node/Bash-Startup-Files.html:
Invoked as an interactive login shell, or with --login
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.
[...]
Invoked as an interactive non-login shell
When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists.
~/.profile is also used by other shells.
Terminal and iTerm open new shells as login shells by default (by executing something like login -pf $USER), but many GNU/Linux terminal applications open new shells as non-login shells. OS X users often use ~/.bash_profile instead of ~/.bashrc.
+-----------------+
| |
interactive shell -->| ~/.bashrc |
| |
+-----------------+
interactive shell will source ~/.bashrc automatically.
Take a look at Should the .bashrc in the home directory load automatically?
I did these to rectify the problem:
cat .bash_profile >> .profile
rm .bash_profile
the alternative is:
echo "source ~/.profile" >> .bash_profile
Make sure if you do source ~/.profile in your .bashrc that you comment out or remove any commands (in .profile) to call or source .bashrc in your .profile or it will loop forever and you will never get a prompt.
Different setups of bash will automatically source different files depending on their configuration. The nearly universal file that is always sourced is ~/.bashrc - this is a bash core thing that it will load this file. In that file, you should add your line to source ~/.profile and you'll be good to go!
-Edit-
From my Linux and my colleague's Mac:
$ echo "echo hello" >> ~/.profile
$ echo "source ~/.profile" >> ~/.bashrc
$ bash
Hello
$

Should aliases go in .bashrc or .bash_profile? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What's the difference between .bashrc, .bash_profile, and .environment?
It seems that if I use
alias ls='ls -F'
inside of .bashrc on Mac OS X, then the newly created shell will not have that alias. I need to type bash again and that alias will be in effect.
And if I log into Linux on the hosting company, the .bashrc file has a comment line that says:
For non-login shell
and the .bash_profile file has a comment that says
for login shell
So where should aliases be written in? How come we separate the login shell and non-login shell?
Some webpage say use .bash_aliases, but it doesn't work on Mac OS X, it seems.
The reason you separate the login and non-login shell is because the .bashrc file is reloaded every time you start a new copy of Bash. The .profile file is loaded only when you either log in or use the appropriate flag to tell Bash to act as a login shell.
Personally,
I put my PATH setup into a .profile file (because I sometimes use other shells);
I put my Bash aliases and functions into my .bashrc file;
I put this
#!/bin/bash
#
# CRM .bash_profile Time-stamp: "2008-12-07 19:42"
#
# echo "Loading ${HOME}/.bash_profile"
source ~/.profile # get my PATH setup
source ~/.bashrc # get my Bash aliases
in my .bash_profile file.
Oh, and the reason you need to type bash again to get the new alias is that Bash loads your .bashrc file when it starts but it doesn't reload it unless you tell it to. You can reload the .bashrc file (and not need a second shell) by typing
source ~/.bashrc
which loads the .bashrc file as if you had typed the commands directly to Bash.
Check out http://mywiki.wooledge.org/DotFiles for an excellent resource on the topic aside from man bash.
Summary:
You only log in once, and that's when ~/.bash_profile or ~/.profile is read and executed. Since everything you run from your login shell inherits the login shell's environment, you should put all your environment variables in there. Like LESS, PATH, MANPATH, LC_*, ... For an example, see: My .profile
Once you log in, you can run several more shells. Imagine logging in, running X, and in X starting a few terminals with bash shells. That means your login shell started X, which inherited your login shell's environment variables, which started your terminals, which started your non-login bash shells. Your environment variables were passed along in the whole chain, so your non-login shells don't need to load them anymore. Non-login shells only execute ~/.bashrc, not /.profile or ~/.bash_profile, for this exact reason, so in there define everything that only applies to bash. That's functions, aliases, bash-only variables like HISTSIZE (this is not an environment variable, don't export it!), shell options with set and shopt, etc. For an example, see: My .bashrc
Now, as part of UNIX peculiarity, a login-shell does NOT execute ~/.bashrc but only ~/.profile or ~/.bash_profile, so you should source that one manually from the latter. You'll see me do that in my ~/.profile too: source ~/.bashrc.
From the bash manpage:
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.
When a login shell exits, bash
reads and executes commands from the
file ~/.bash_logout, if it exists.
When an interactive shell that is not a login shell is started, bash
reads and executes commands from ~/.bashrc, if that file exists. 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
~/.bashrc.
Thus, if you want to get the same behavior for both login shells and interactive non-login shells, you should put all of your commands in either .bashrc or .bash_profile, and then have the other file source the first one.
.bash_profile is loaded for a "login shell". I am not sure what that would be on OS X, but on Linux that is either X11 or a virtual terminal.
.bashrc is loaded every time you run Bash. That is where you should put stuff you want loaded whenever you open a new Terminal.app window.
I personally put everything in .bashrc so that I don't have to restart the application for changes to take effect.

Force base_profile to run

When I login to a sun box: SunOS domain.com 5.8 Generic_117350-57 sun4u sparc SUNW,Sun-Fire-V240
I start in the sh shell: SHELL=/bin/sh
I type bash to start a bash shell, then have to type . .bash_profile to load my profile. Is there a way it can be set to automatically load the profile?
Put
. ~/.bash_profile
in ~/.bashrc (watch out for infinite loops!). I don't use that myself, as I have most stuff in .bashrc to begin with (except, well, env. stuff and so on).
.bash_profile is only used for login shells, for non-login shells (like yours), bash uses .bashrc.
The easiest thing is for you to add . .bash_profile to your .bashrc.
You also have to make sure that you don't print out anything in non-interactive shells, or you can break scp/sftp.
Running bash like this causes it to source /etc/bash.bashrc and then ~/.bashrc in lieu of .bash_profile (and other files). Therefore, put . ~/.bash_profile in ~/.bashrc, (or in /etc/bash.bashrc to do this for all users).
The file .bash_profile is run when upon login. The file .bashrc is run when running bash from a non-login session.
Try adding this to your .bashrc:
source ~/.bash_profile

Resources