I am not sure this is clear to me and if is neat for my system. I'm aware of the ~/.zhrc file where I can store alias and paths, but today after installing node via brew I was asked to put this: export PATH="$HOME/.npm-packages/bin:$PATH" in my ~/.bash_profile file, which it doesn't exist, thus in my effort to keep my system clean I putted it in the former file but emacs complaint. Now, I removed it and putted it, after creating, in the ~/.bash_profile. Is that OK to keep both in the home directory?
11 Answer
You need to provide the exact wording of whatever error or warning message you get from emacs to ensure accurate or better answers. However, I will make a guess and assume the warning you are getting is from the exec-path package.
This package has a check, which you can disable, that looks to make sure you have variables defined in the correct init file.
In general, most shells support two types of configuration files
- Startup or Login init files
- Interactive shell init files
The difference is how often or when the files are sourced (loaded). To understand the difference, you really need to understand when a shell is run and the relationship between each shell. I'll try to give a vary high level explanation, but you really should read the manual page for the particular shell you are using.
Think of your environment as a tree of shell processes. When you login to the system, a login shell is created. This shell will be the parent of all the other shells you create. Each time you run a command, it is executed in a new shell (this isn't 100% accurate, but is accurate enough to explain the main points). So when you open a terminal, it runs another shell which is a child of your login shell. When you execute various commands, the system creates a new shell and runs that command inside the shell. These are all children of your parent login shell. Some shells only exist for a short period of time (as long as it takes to execute the command), others may last for hours, days or possibly weeks (such as the shell that emacs is running in).
The important point to keep in mind is that child shells inherit various settings from the parent shell. The idea of the 'export' command you will see in front of some variables is actually a command to the shell telling it to export the variable to child shells. For example, if we have a line like
export PATH=/usr/local/bin:/usr/bin:/bin what we are really doing is
PATH=/usr/local/bin:/usr/bin:/bin # set the variable export PATH # make it available in child shells We don't always want variables to be exported as some variables need to be reset in the child shell itself. For example, the variable holding the prompt string. It would not work to have this variable only defined in the login parent shell if you want the prompt to have dynamic components, such as the current directory, date or time. We want these types of variables to be defined in each shell when it is created.
To handle this, shells have the two different init files. The login init files are only sourced for the parent shell and are particularly useful for setting variables that will be common to all child shells. the per-shell init files are sourced for every new shell and are best used for setting things which need to be updated or changed each time a shell is started. There are also other shell configuration files which can be used for other special purposes, such as when you log out or log off a system, or to just put alias definitions in etc.
Once upon a time, it made a big difference where you put your variables as there was a performance hit when sourcing these init files. If the per-shell init file was too large and consumed too many resources, the whole performance of your environment could be affected. This is largely less of an issue these days due to increased processing speeds. Unfortunately, because many people didn't understand the role and relationships between the different shell configuration files, there is lots of incorrect or misleading information out there regarding where values should be set. People often advise setting variables in (for example) bashrc when they should be set in the bash__profile=. The confusion is partly caused by the fact you can add a variable to bashrc and it will work when you test it (usually because your test involves forking a new child shell) and putting it in your bash_profile will only work after the next login.
There are also some platform differences which make things a little less clear. For example, under OSX, there is actually a special file in the /etc directory where you should add additional path components (I'm not on a mac just now, but it is something like /etc/paths or a per path component file in /etc/path.d). This is done so that you have a global place to set paths which will ensure desktop processes, such as the dock, which do not run as a child process of your login shell, are able to be set.
As a general rule, most variables can go in the login profile, with the exception of variables relating to the prompt or other variables which have a dynamic content i.e. content which changes depending on time, directory location or other tracking of interactive actions which are specific to a shell instance.
Setting of the path (noting OS differences as described above) should go into the profile or login configuration file. Under bash, this is .bash_profile and under zsh, it is typically .zprofile. As bash has become the most common shell, documentation etc often advises adding things to .bash_profile. If your running zsh, then add the same information using .zprofile.
As you have said you don't have a.bash_profile, but you do have a zshrc file, I am assuming you are running zsh rather than bash as your login shell. This being the case, you need to add that path setting to .zprofile in your home directory. The exec-path package is complaining because you added it to zshrc/bashrc, which are not the correct place to set path variables. If your running under OSX, you really need to add the path to the correct file in /etc (you will need to check the OSX documentation as I cannot remember the precise filename).
1