3

At the moment, when I open a terminal on my Mac, it automatically calls:

source ~/.bash_profile.

What bemuses me, however, is that my shell does not seem to inherit any of the content from ~/.bashrc or ~/.profile. But that might be typical.

I have a number of scripts to inherit using source or .; if I put those calls in ~/.bash_profile, it can take some time to load a new shell window, sometimes 3 or 4 seconds, and that gets old. I imagine that there is some way to source those scripts just once and have my ~/.bash_profile file inherit it somehow.

Note that calling source ~/.bashrc or source ~/.profile from my ~/.bash_profile is not what I want to do, and is also probably a bad idea. It's not what I want to do because it doesn't solve the problem of a slow load for each new shell.

I added some echo statements; every time I open a new bash terminal window, this is logged:

starting to load /etc/profile
finished loading /etc/profile
starting to load bash_profile
finished loading bash_profile

that makes sense, but what is disheartening - do I really need to load these every time a new shell is opened? Why can't it do some fancy inheritance so that we don't have to reload everything every time?

I created a video demo'ing the problem. I have 4 terminal applications I use regularly:

terminal.app                  # misbehaves
iterm2                        # misbehaves
webstorm terminal emulator    # misbehaves
vscode terminal emulator      # behaves!

VSCode actually behaves in the way I would desire. I am guessing that it does this by loading ~/.bash_profile in a parent shell, and only doing that once, when vscode boots up. All of the terminal windows in the app, are then subshells of that one parent shell.

Hopefully this video makes the issue clear: https://www.useloom.com/share/4e62f0cb24434c4a83b8bd32844b596a

This is a legit issue - most terminal applications do this whole thing wrong, however, quite miraculously, it appears that VSCode from Microsoft actually does this whole thing the right way, see this issue:

https://youtrack.jetbrains.com/issue/WEB-31390

  • I don't understand why a terminal session is not just a subshell of a parent shell which has already inherited from /etc/profile or ~/.profile or whatever – Alexander Mills Feb 21 '18 at 21:10
  • There is no problem sourcing .bashrc from .bash_profile and it is quite common in fact. Also related: joshstaiger.org/archives/2005/07/bash_profile_vs.html | Additionally please edit your question with additional thoughts/details instead of commenting. – Jesse_b Feb 21 '18 at 21:11
  • Yeah sourcing one file from another is not the answer here - that doesn't speed anything up - and one time I did that, I got an infinite loop when logging in, and I will never try that again :( – Alexander Mills Feb 21 '18 at 21:13
  • What I could do to avoid an infinite loop is have .bashrc/.bash_profile/.profile source a 4th file, but again that doesn't speed up loading a new terminal session – Alexander Mills Feb 21 '18 at 21:14
1

This morning I moved a bunch of personal information out of my bash_profile and bashrc and added them to a new file I call privaterc.

In my privaterc file I set this variable:

PRIVATERC_RUN=yes 

Now in my bash_profile I have added this line:

[[ $PRIVATERC_RUN != yes && -f ~/.privaterc ]] && source ~/.privaterc

This will cause privaterc to only be sourced if it hasn't previously been sourced in this shell.


Also as for the profile weirdness you are seeing, the article I linked in the comment states the following about mac:

Mac OS X — an exception

An exception to the terminal window guidelines is Mac OS X’s Terminal.app, which runs a login shell by default for each new terminal window, calling .bash_profile instead of .bashrc. Other GUI terminal emulators may do the same, but most tend not to.

  • that might work, I will try it – Alexander Mills Feb 21 '18 at 21:16
  • you think like me :) I also use "yes" instead of true/false – Alexander Mills Feb 21 '18 at 21:17
  • yeah this doesn't work as I was hoping. Every time I open a new terminal window, it will resource the .privaterc file. That makes sense because when you call export it won't change the parent shell. So what we need is a way so that an original parent shell is what's called when we first login, and then any terminal will already be a subshell of that parent shell.. – Alexander Mills Feb 21 '18 at 21:26
  • do you follow what I am saying? any other ideas? I have always found info on this stuff to be a little wishy washy, but there must be some way to inherit stuff in a bash shell, instead of having to re-source stuff every time. – Alexander Mills Feb 21 '18 at 21:37
1

Put a unique variable in the rc file - with a length of 1 or more bytes - then check if it has a length greater than 0 before sourcing bash_profile.

if [ ! X”” = X”$uniq_var” ] ; then . ~/.bash_profile ; fi

I just set bash as the login shell on MacOS, and didn’t have this problem. Perhaps they changed something again.

  • How do you set bash as the login shell on MacOS? – Alexander Mills Feb 21 '18 at 21:27
  • @AlexanderMills In settings. There are numerous tabs, you’ll find it. – user2497 Feb 21 '18 at 21:27
  • yeah see: superuser.com/questions/362372/… – Alexander Mills Feb 21 '18 at 21:29
  • @AlexanderMills I really liked Terminal.app, but I remember switching to iTerm2 after it got an overhaul - it was much more useful (tabswitching with CMD-{1,2,3,4,..} etc. 99% customizable. Try it if you can’t make Terminal.app behave. – user2497 Feb 21 '18 at 21:41
  • Yeah I use iterm2 most of the time. I also use the built-in terminal for Webstorm and VSCode even more. I need to get them all to behave. – Alexander Mills Feb 21 '18 at 21:45

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.