The author's last post was about terminal frustrations[0]<p>This is easily one of the most annoying ones, especially when shells will have several different locations to read config from depending on how you start the shell, or what a desktop app will do to try and pull the config in (`exec-path-from-shell` in emacs, for example).<p>And you can't really, say, put it in both your `.zprofile` and `.zshrc` or `.bash_profile`, `.profile`, and `.bashrc`, because then it'll get executed more than once and you'd need to maintain some kind of state to prevent that.<p>[0]<a href="https://jvns.ca/blog/2025/02/05/some-terminal-frustrations/" rel="nofollow">https://jvns.ca/blog/2025/02/05/some-terminal-frustrations/</a>
I've worked on maintaining internal dev tooling for some small companies for a while now, and it's a real PITA to write a robust installation script for bootstrapping a new laptop running an arbitrary shell on linux or macOS into a working environment. Way more work than it feels like it should be.<p>At this point I've pretty much given in and decided that a containerized dev environment is probably the better solution, but on principle it feels so unsatisfying to have to resort to this :(<p>(I know someone is going to mention Nix/Guix ;) but that feels like a giant rabbit hole)
FWIW in bash I have 2 functions:<p><pre><code> path_add() {
export PATH=$PATH:$(string_join ':' $@)
}
path_prepend() {
PATH=$(string_join ':' "$@"):$PATH
export PATH
}
</code></pre>
These can join an arbitrary list of paths to PATH. e.g.<p><pre><code> path_add /usr/bin /usr/local/bin ~/bin
</code></pre>
They depend on another one:<p><pre><code> string_join() {
local join=$1; shift
local result=$1; shift
for p in "$@"; do
result="${result}${join}${p}"
done
echo -n "$result"
set +x
}
</code></pre>
I also have ones for adding and prepending to LD_LIBRARY_PATH
As for path duplication, I personally have<p><pre><code> printf '%s\n' "$PATH" | grep --color=auto -E -e '(^|:)'"$( printf '%s\n' "$1" | sed 's/[][\.|$(){}?+*^]/\\&/g' )"'($|:)' > /dev/null 2>&1
if [ "$?" = 1 ]; then PATH="$1:$PATH" ; export PATH ; fi
</code></pre>
in my version of pathadd().
> Configure your shell to continuously save your history instead of only saving the history when the shell exits. (How to do this depends on whether you’re using bash or zsh, the history options in zsh are a bit complicated and I’m not exactly sure what the best way is)<p>I attempted this in bash like so:<p>```
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
```<p>But, that meant every shell was sharing the same history. Pressing up would go to the last command run anywhere, not just my current shell.<p>Sadly, I wasn't even trying to solve the problem Julia is talking about here. I just wanted to make sure my history was saved when I shutdown. Still haven't found a great solution to that. My attempts as using traps and signals caused weird issues.
In my (fever) dreams, there's a directory at `/var/share/env` with the rule that regular files are <file name>=<file contents> and all other file types are ignored. The `env` program can slurp all the files to create the default environment before applying whatever customization are in dotfiles for a shell.<p>Want to add to path? `echo ':<directory>' >> /var/share/env/PATH` (or `env --add PATH :<directory>`, or something like that).
All this path stuff would go away if you have a proper vfs where you bind you other bins over /bin allowing $path to simply read "/bin ." and be done with it.
.bashrc gets run every time a shell starts<p>I'm not sure I'd stick a path setting in .bashrc - just because it would make it very difficult to ever override that PATH setting elsewhere.<p>You might want that but it might also mess up some other program's attempt to set the PATH and then e.g. run a shell command.<p>I usually use .bash_profile or .profile more for this sort of thing and then I have to tell my terminal program to run bash as a login shell and that gives me what I mostly expect.
> fish instructions:<p>> set PATH $PATH ~/.npm-global/bin<p>Fish has some nice utilities for these type of set calls<p>set --append PATH ~/.npm-global/bin