Skip to main content
The 2024 Developer Survey results are live! See the results
typo
Source Link
MarcH
  • 441
  • 4
  • 10

As the never-ending stream of discussions on this topic demonstrates, it's a lost cause. As long as you just want to add new values, some "trial and error" tends to be enough. The real fun begins when you want to modify in one (user) file something already defined in another (in /etc). Then be prepared to be spend some time engineering a solution that will never be portable.

As the never-ending stream of discussions on this topic demonstrates, it's a lost cause. As long as you just want to add new values, some "trial and error" tends to be enough. The real fun begins when you want to modify in one (user) file something already defined in another (in /etc). Then be prepared to be spend some time engineering a solution that will never be portable.

As the never-ending stream of discussions on this topic demonstrates, it's a lost cause. As long as you just want to add new values, some "trial and error" tends to be enough. The real fun begins when you want to modify in one (user) file something already defined in another (in /etc). Then be prepared to spend some time engineering a solution that will never be portable.

Source Link
MarcH
  • 441
  • 4
  • 10

The configuration logic of bash's itself is not crazy complicated and explained in other answers in this page, on serverfault and in many blogs. The problem however is what the Linux distributions make of bash, I mean the complex and various ways they configure bash by default. http://mywiki.wooledge.org/DotFiles mentions some of these quirks briefly. Here's one sample trace on Fedora 29, it shows which files source which other file(s) and in which order for a very simple scenario: remotely connecting with ssh and then starting another subshell:

ssh fedora29
 └─ -bash # login shell
      ├── /etc/profile
      |    ├─ /etc/profile.d/*.sh
      |    ├─ /etc/profile.d/sh.local
      |    └─ /etc/bashrc
      ├── ~/.bash_profile
      |    └─ ~/.bashrc
      |          └─ /etc/bashrc
      |
      |
      └─ $ bash  # non-login shell
            └─ ~/.bashrc
                 └─ /etc/bashrc
                       └─ /etc/profile.d/*.sh

Fedora's most complex logic is in /etc/bashrc. As seen above /etc/bashrc is a file bash itself doesn't know about, I mean not directly. Fedora's /etc/bashrc tests whether:

  • it's being sourced by a login shell,
  • it's being sourced by an interactive shell,
  • it has already been sourced

... and then does completely different things depending on those.

If you think can remember the graph above then too bad because it's not nearly enough: this graph merely describes just one scenario, slightly different things happen when running non-interactive scripts or starting a graphical session. I've omitted ~/.profile. I've omitted bash_completion scripts. For backward compatibility reasons, invoking bash as /bin/sh instead of /bin/bash changes its behaviour. What about zsh and other shells? And of course different Linux distributions do things differently, for instance Debian and Ubuntu come with a non-standard version of bash, it has Debian-specific customization(s). It notably looks for an unusual file: /etc/bash.bashrc. Even if you stick to a single Linux distribution it probably evolves over time. Wait: we haven't even touched macOS, FreeBSD,... Finally, let's have a thought for users stuck with the even more creative ways their admins have configured the system they have to use.

As the never-ending stream of discussions on this topic demonstrates, it's a lost cause. As long as you just want to add new values, some "trial and error" tends to be enough. The real fun begins when you want to modify in one (user) file something already defined in another (in /etc). Then be prepared to be spend some time engineering a solution that will never be portable.

For a last bit of fun here's the "source graph" for the same, simple scenario on Clear Linux as of June 2019:

ssh clearlinux
 └─ -bash # login shell
      ├── /usr/share/defaults/etc/profile
      |    ├─ /usr/share/defaults/etc/profile.d/*
      |    ├─ /etc/profile.d/*
      |    └─ /etc/profile
      ├── ~/.bash_profile
      |
      |
      └─  $ bash   # non-login shell
           ├─ /usr/share/defaults/etc/bash.bashrc
           |      ├─ /usr/share/defaults/etc/profile
           |      |    ├─ /usr/share/defaults/etc/profile.d/*
           |      |    ├─ /etc/profile.d/*
           |      |    └─ /etc/profile
           |      └─ /etc/profile
           └─ ~/.bashrc