4 ms·
Before we begin, first note that bashrc refers to something that runs in each and every new shell, and profile refers to something that runs only in interactive
by roryrjb 7y ago
Before we begin, first note that bashrc refers to something that runs in each and every new shell, and profile refers to something that runs only in interactive shells (used by a user at a keyboard, not just a shell script, for example). They aren’t the same and you don’t want them to be the same.
I'm not an expert on bash exactly though I am a heavy shell user (POSIX shell for scripting) but this part doesn't sound right. When is .bashrc ever executed when bash isn't interactive? And as far as I can tell when I open new shells .profile isn't read. I am using Linux and tmux and the reason I mention tmux is that it opens bash as a login shell and therefore .bash_profile is also loaded. Is this a mac OS thing or the version of bash mac OS comes with, which I believe is really old due to some license issues.
- robohoe 7y ago.bashrc would get executed when you run something in cron. Cron runs non-interactive shell sessions.
- deleted 7y ago[deleted]
- roryrjb 7y agoI tested this and this is not the case. My .bashrc does a lot of things such as custom completions that are expensive that I would not want run by anything else other than an interactive shell. It also has return at the end so if anything I don't know about adds stuff to it, it won't get executed. This would break other scripts loading .bashrc as well. So as far as I can see this is false.
- tremon 7y agoFrom the manual: 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. So interactive, non-login shells only. But also: When invoked as an interactive shell with the name sh , bash looks for the variable ENV, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. [A] shell invoked as sh does not attempt to read and execute commands from any other startup files So only when invoked as bash, not as sh.
- roryrjb 7y agoThank you, very helpful. That explains why I have to have my .bash_profile source .bashrc for use with tmux, as it executes bash as a login shell. I knew I had to have this but wasn't 100% on why until now. Note to self, RTFM!
- rovr138 7y agoI thought macOS always loaded the shell as a login shell by default while most Linux and UNIX load a non-login shell by default. On a Mac you usually end up adding if [ -f ~/.bashrc ]; then . ~/.bashrc; fi To your .profile or .bash_profile. Just read that part and now I can’t help but question the rest of it before even reading it
- _mdpn 7y agoI just moved to Catalina, and the fact that zsh has a clear and reasonable standard for startup files made up for the fact that I had to move my shell init to its files.
- rovr138 7y agoThe way the files are loaded on Bash has a standard. Apple breaks it, but there is. Here’s info, https://unix.stackexchange.com/questions/170493/login-non-login-and-interactive-non-interactive-shells#170499 https://unix.stackexchange.com/questions/170493/login-non-lo... ZSH follows the same for login/non-login but I don’t see it for interactive.
- Fnoord 7y agoIf you do, it will even load it for non-interactive shells. if [ -n "$PS1" ] ; then [ -r ~/.bashrc ] && . ~/.bashrc [ -r ~/.bash_login ] && . ~/.bash_login fi
- rovr138 7y agoYep. It’s a mess frankly.
- tremon 7y agoas far as I can tell when I open new shells .profile isn't read True, iff you have a .bash_profile. Bash only reads the first of ~/.bash_profile, ~/.bash_login, ~/.profile. It will ignore the rest of the list once it's found an existing file.
- ashtonbaker 7y agoThis explains so many of my problems. Thank you.
- deleted 7y ago[deleted]
- em500 7y agohttps://hackernoon.com/bash-profile-vs-bashrc-vs-bin-bash-vs-etc-bash-tutorial-help-example-not-found-command-linux-mac-1c7f98c11186 https://hackernoon.com/bash-profile-vs-bashrc-vs-bin-bash-vs... Note that in macOS every new Terminal (tab) opens a login shell, while most GUI Linux environments don't. (In Tmux/screen it depends on the configuration).
- jolmg 7y agoStill, they're not read with every new interactive shell. They're read only with login shells. From the manual: > 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, > When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc So, this is wrong: > bashrc refers to something that runs in each and every new shell Because .bashrc doesn't run when you execute a shell script, and doesn't run when you use `bash -c`. And this is wrong: > profile refers to something that runs only in interactive shells Because it does run in non-interactive shells when they're login shells, and because it implies that it runs in every interactive shell, which it doesn't. It only runs in login shells.
- 7y ago
- Aloha 7y agoIt sounds right to me, when running thru cron for example, I need to load env vars as part of my script startup otherwise even path is missing.
- techslave 7y ago> I'm not an expert on bash exactly though I am a heavy shell user (POSIX shell for scripting) but this part doesn't sound right. When is .bashrc ever executed when bash isn't interactive? Never. TFA has got it wrong.
- skywhopper 7y agoWhich startup files are read by bash and other shells in which state is very inconsistent, even across distributions of Linux. I've collapsed all of mine into .bashrc and simply source that file from the other possibilities. And on the rare occasion that I care about interactive vs not, I can make that distinction explicitly in the code.
- russjones 7y agoI ran an eBPF program called opensnoop [1] to capture what files were opened during login to a system and then re-launching bash. Looks like both are read during initial login but only .bashrc for non-login shells. Output is below. 24435 bash 3 0 /etc/profile 24435 bash 3 0 /etc/profile.d/ 24435 bash 3 0 /etc/profile.d/256term.sh 24435 bash 3 0 /etc/profile.d/colorgrep.sh 24435 bash 3 0 /etc/profile.d/colorls.sh 24435 bash 3 0 /etc/profile.d/lang.sh 24435 bash 3 0 /etc/profile.d/less.sh 24435 bash 3 0 /etc/profile.d/which2.sh 24435 bash 3 0 /etc/profile.d/sh.local 24435 bash 3 0 /home/centos/.bash_profile 24435 bash 3 0 /home/centos/.bashrc 24435 bash 3 0 /etc/bashrc 24736 bash 3 0 /home/centos/.bashrc 24736 bash 3 0 /etc/bashrc 24736 bash 3 0 /etc/profile.d/ 24736 bash 3 0 /etc/profile.d/256term.sh 24736 bash 3 0 /etc/profile.d/colorgrep.sh 24736 bash 3 0 /etc/profile.d/colorls.sh 24736 bash 3 0 /etc/profile.d/lang.sh 24736 bash 3 0 /etc/profile.d/less.sh 24736 bash 3 0 /etc/profile.d/which2.sh [1] http://www.brendangregg.com/blog/2014-07-25/opensnoop-for-linux.html http://www.brendangregg.com/blog/2014-07-25/opensnoop-for-li...
- remram 7y agoBe careful that some of those files explicitly include others. For example my (default) ~/.profile includes ~/.bashrc, my ~/.bash_profile includes ~/.profile, /etc/profile includes /etc/bash.bashrc... So your capture here doesn't show only the files that bash itself decided to load. You also won't see the fallback files (e.g. bash will open .profile if .bash_profile doesn't exist).
- s_gourichon 7y agoThere's a graph (generated by graphviz from text description) that shows the flow and files involved for bash, sh and zsh. Yes, it's insane. https://blog.flowblok.id.au/2013-02/shell-startup-scripts.html https://blog.flowblok.id.au/2013-02/shell-startup-scripts.ht...
- hn_new 7y agoscp executes .bashrc if I recall correctly. Any echo in .bashrc broke scp for me in the past.