Invoke zsh, then *source* another file (while entering interactive mode)
This question is of course related, but different to the one about executing a command.
That questions’ solutions involve either starting a subshell – which isn’t possible due to the requirement of sourcing instead of executing – or modifying your ~/.zshrc
, which isn’t possible if you want to distribute a script that does it. (Or rather modifying the user’s config files is a thing you just don’t do)
The problem is that with zsh there is no --init-file
parameter like bash has (the first time ever i saw bash having a feature that zsh hasn’t)
I’ll provide an answer with my question, but it’s reeeaaallly ugly, and I hope someone knows a trick to circumvent it!
This site tells us that there is a $ZDOTDIR
, which makes a very ugly solution possible:
-
/distdir/my-cmd
:Use shell-specific ways to replace init files or fail hopelessly.
case $(basename $SHELL) in zsh) OLD_ZDOTDIR="$ZDOTDIR" ZDOTDIR="/distdir" zsh -i ;; bash) bash --init-file "/distdir/.zshrc" -i ;; *) echo "Unrecognized shell $SHELL"; exit 1 ;; esac
-
/distdir/.zshrc
:Named
.zshrc
, as the names are hardcoded in zsh, but bash can be passed a arbitrarily named file via--init-file
. It would also be possible to name this e.g.our_stuff.sh
, and create a.zshrc
which contains just. ./our_stuff.sh
.As we don’t actually want to replace the init files, but to append another, we have to painstakingly recreate the builtin sequence of sourcing them.
# ignore profile, login & logout rc files, as we want no login shells case $(basename $SHELL) in zsh) test -f "$OLD_ZDOTDIR/.zshenv" && . "$OLD_ZDOTDIR/.zshenv" test -f "$OLD_ZDOTDIR/.zshrc" && . "$OLD_ZDOTDIR/.zshrc" ;; bash) test -f ~/.bashrc && source ~/.bashrc test -f /etc/bash.bashrc && source /etc/bash.bashrc ;; esac do_our_stuff! PS1="myenv! $PS1" #tell the user he’s in a modified shell