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

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.

Related

Issue with aliases in Terminal shell

I'm set /bin/bash as my default shell in Terminal (macos) and my aliases, written in '~/.bashrc' don't work (command not found).
But if I write in Terminal /bin/bash command, I'll switch to new bash3.2 shell, and then I can use it.
Is there some another '.bashrc' where I should write down my aliases?
P.S. I used Terminal preferences to made /bin/bash default
and chsh -s /bin/bash/ command too.
Terminal starts a login shell rather than an "ordinary" interactive shell, because Terminal itself is not run from a shell that inherited an environment from a login shell.
Ordinary interactive shells source .bashrc; login shells source the first of .profile, .bash_login, or .bash_profile it finds. I recommend sourcing .bashrc directly from .bash_profile.
Your aliases work when you run /bin/bash directly because that does not start another login shell, and so .bashrc is sourced as expected.
As above, if you add the following line to .profile in your home directory:
source ~/.bashrc
Once you save it and create a new Terminal session, it will automatically source your .bashrc with your alias settings.
You want /bin/bash -l to run as if you used a login shell. See the INVOCATION section of man bash for more information.

How to determine which .bash_profile .profile .bashrc .zshrc to use? [duplicate]

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I've used a number of different *nix-based systems of the years, and it seems like every flavor of Bash I use has a different algorithm for deciding which startup scripts to run. For the purposes of tasks like setting up environment variables and aliases and printing startup messages (e.g. MOTDs), which startup script is the appropriate place to do these?
What's the difference between putting things in .bashrc, .bash_profile, and .environment? I've also seen other files such as .login, .bash_login, and .profile; are these ever relevant? What are the differences in which ones get run when logging in physically, logging in remotely via ssh, and opening a new terminal window? Are there any significant differences across platforms (including Mac OS X (and its Terminal.app) and Cygwin Bash)?
The main difference with shell config files is that some are only read by "login" shells (eg. when you login from another host, or login at the text console of a local unix machine). these are the ones called, say, .login or .profile or .zlogin (depending on which shell you're using).
Then you have config files that are read by "interactive" shells (as in, ones connected to a terminal (or pseudo-terminal in the case of, say, a terminal emulator running under a windowing system). these are the ones with names like .bashrc, .tcshrc, .zshrc, etc.
bash complicates this in that .bashrc is only read by a shell that's both interactive and non-login, so you'll find most people end up telling their .bash_profile to also read .bashrc with something like
[[ -r ~/.bashrc ]] && . ~/.bashrc
Other shells behave differently - eg with zsh, .zshrc is always read for an interactive shell, whether it's a login one or not.
The manual page for bash explains the circumstances under which each file is read. Yes, behaviour is generally consistent between machines.
.profile is simply the login script filename originally used by /bin/sh. bash, being generally backwards-compatible with /bin/sh, will read .profile if one exists.
That's simple. It's explained in man bash:
/bin/bash
The bash executable
/etc/profile
The systemwide initialization file, executed for login shells
~/.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
Login shells are the ones that are read one you login (so, they are not executed when merely starting up xterm, for example). There are other ways to login. For example using an X display manager. Those have other ways to read and export environment variables at login time.
Also read the INVOCATION chapter in the manual. It says "The following paragraphs describe how bash executes its startup files.", i think that's a spot-on :) It explains what an "interactive" shell is too.
Bash does not know about .environment. I suspect that's a file of your distribution, to set environment variables independent of the shell that you drive.
Classically, ~/.profile is used by Bourne Shell, and is probably supported by Bash as a legacy measure. Again, ~/.login and ~/.cshrc were used by C Shell - I'm not sure that Bash uses them at all.
The ~/.bash_profile would be used once, at login. The ~/.bashrc script is read every time a shell is started. This is analogous to /.cshrc for C Shell.
One consequence is that stuff in ~/.bashrc should be as lightweight (minimal) as possible to reduce the overhead when starting a non-login shell.
I believe the ~/.environment file is a compatibility file for Korn Shell.
I found information about .bashrc and .bash_profile here to sum it up:
.bash_profile is executed when you
login. Stuff you put in there might be
your PATH and other important
environment variables.
.bashrc is used for non login shells.
I'm not sure what that means. I know
that RedHat
executes it everytime you start
another shell (su to this user or
simply calling bash again) You might
want to put aliases in there but again
I am not sure what that means. I
simply ignore it myself.
.profile is the equivalent of
.bash_profile for the root. I think
the name is changed to let other
shells (csh, sh, tcsh) use it as well.
(you don't need one as a user)
There is also .bash_logout wich
executes at, yeah good guess...logout.
You might want to stop deamons or even
make a little housekeeping . You can
also add "clear" there if you want to
clear the screen when you log out.
Also there is a complete follow up on each of the configurations files here
These are probably even distro.-dependant, not all distros choose to have each configuraton with them and some have even more. But when they have the same name, they usualy include the same content.
According to Josh Staiger, Mac OS X's Terminal.app actually runs a login shell rather than a non-login shell by default for each new terminal window, calling .bash_profile instead of .bashrc.
He recommends:
Most of the time you don’t want to maintain two separate config files
for login and non-login shells — when you set a PATH, you want it to
apply to both. You can fix this by sourcing .bashrc from your
.bash_profile file, then putting PATH and common settings in .bashrc.
To do this, add the following lines to .bash_profile:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
Now when you login to your
machine from a console .bashrc will be called.
A good place to look at is the man page of bash. Here's an online version. Look for "INVOCATION" section.
I have used Debian-family distros which appear to execute .profile, but not .bash_profile,
whereas RHEL derivatives execute .bash_profile before .profile.
It seems to be a mess when you have to set up environment variables to work in any Linux OS.

Can't figure out how I set my PYTHONPATH in Ubuntu

As soon as I ssh into my ubuntu, my PYTHONPATH shows
:/usr/local/opencv-2.4.13/build/modules/python:/usr/local/mxnet/python:/usr/local/caffe/python
I don't want these starting settings, but I can't figure out how they got set. They are not set in .bashrc or .profile. Where else should I look?
List of places to check (this includes scripts that any of these files source or run, meaning it is not sufficient to grep on this list of files for the variable in question):
/etc/profile
Any files in the folder /etc/profile.d/
/etc/environment
The first existing file of ~/.bash_profile, ~/.bash_login, and ~/.profile
/etc/bash.bashrc (or /etc/bashrc , depending on OS)
~/.bashrc
~/.pam_environment (when using ssh)
/etc/motd (when using ssh)
Explanation:
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 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 contents of /etc/motd are displayed by pam_motd(8) after a successful login but just before it executes the login shell.
The abbreviation "motd" stands for "message of the day", and this file has been traditionally used for exactly that (it requires much less disk space than mail to all users).
On Debian GNU/Linux, the content of /run/motd.dynamic is also displayed. This file is generated by /etc/init.d/motd at boot.

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

What's the difference between .bashrc, .bash_profile, and .environment?

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I've used a number of different *nix-based systems of the years, and it seems like every flavor of Bash I use has a different algorithm for deciding which startup scripts to run. For the purposes of tasks like setting up environment variables and aliases and printing startup messages (e.g. MOTDs), which startup script is the appropriate place to do these?
What's the difference between putting things in .bashrc, .bash_profile, and .environment? I've also seen other files such as .login, .bash_login, and .profile; are these ever relevant? What are the differences in which ones get run when logging in physically, logging in remotely via ssh, and opening a new terminal window? Are there any significant differences across platforms (including Mac OS X (and its Terminal.app) and Cygwin Bash)?
The main difference with shell config files is that some are only read by "login" shells (eg. when you login from another host, or login at the text console of a local unix machine). these are the ones called, say, .login or .profile or .zlogin (depending on which shell you're using).
Then you have config files that are read by "interactive" shells (as in, ones connected to a terminal (or pseudo-terminal in the case of, say, a terminal emulator running under a windowing system). these are the ones with names like .bashrc, .tcshrc, .zshrc, etc.
bash complicates this in that .bashrc is only read by a shell that's both interactive and non-login, so you'll find most people end up telling their .bash_profile to also read .bashrc with something like
[[ -r ~/.bashrc ]] && . ~/.bashrc
Other shells behave differently - eg with zsh, .zshrc is always read for an interactive shell, whether it's a login one or not.
The manual page for bash explains the circumstances under which each file is read. Yes, behaviour is generally consistent between machines.
.profile is simply the login script filename originally used by /bin/sh. bash, being generally backwards-compatible with /bin/sh, will read .profile if one exists.
That's simple. It's explained in man bash:
/bin/bash
The bash executable
/etc/profile
The systemwide initialization file, executed for login shells
~/.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
Login shells are the ones that are read one you login (so, they are not executed when merely starting up xterm, for example). There are other ways to login. For example using an X display manager. Those have other ways to read and export environment variables at login time.
Also read the INVOCATION chapter in the manual. It says "The following paragraphs describe how bash executes its startup files.", i think that's a spot-on :) It explains what an "interactive" shell is too.
Bash does not know about .environment. I suspect that's a file of your distribution, to set environment variables independent of the shell that you drive.
Classically, ~/.profile is used by Bourne Shell, and is probably supported by Bash as a legacy measure. Again, ~/.login and ~/.cshrc were used by C Shell - I'm not sure that Bash uses them at all.
The ~/.bash_profile would be used once, at login. The ~/.bashrc script is read every time a shell is started. This is analogous to /.cshrc for C Shell.
One consequence is that stuff in ~/.bashrc should be as lightweight (minimal) as possible to reduce the overhead when starting a non-login shell.
I believe the ~/.environment file is a compatibility file for Korn Shell.
I found information about .bashrc and .bash_profile here to sum it up:
.bash_profile is executed when you
login. Stuff you put in there might be
your PATH and other important
environment variables.
.bashrc is used for non login shells.
I'm not sure what that means. I know
that RedHat
executes it everytime you start
another shell (su to this user or
simply calling bash again) You might
want to put aliases in there but again
I am not sure what that means. I
simply ignore it myself.
.profile is the equivalent of
.bash_profile for the root. I think
the name is changed to let other
shells (csh, sh, tcsh) use it as well.
(you don't need one as a user)
There is also .bash_logout wich
executes at, yeah good guess...logout.
You might want to stop deamons or even
make a little housekeeping . You can
also add "clear" there if you want to
clear the screen when you log out.
Also there is a complete follow up on each of the configurations files here
These are probably even distro.-dependant, not all distros choose to have each configuraton with them and some have even more. But when they have the same name, they usualy include the same content.
According to Josh Staiger, Mac OS X's Terminal.app actually runs a login shell rather than a non-login shell by default for each new terminal window, calling .bash_profile instead of .bashrc.
He recommends:
Most of the time you don’t want to maintain two separate config files
for login and non-login shells — when you set a PATH, you want it to
apply to both. You can fix this by sourcing .bashrc from your
.bash_profile file, then putting PATH and common settings in .bashrc.
To do this, add the following lines to .bash_profile:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
Now when you login to your
machine from a console .bashrc will be called.
A good place to look at is the man page of bash. Here's an online version. Look for "INVOCATION" section.
I have used Debian-family distros which appear to execute .profile, but not .bash_profile,
whereas RHEL derivatives execute .bash_profile before .profile.
It seems to be a mess when you have to set up environment variables to work in any Linux OS.

Resources