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:

  1. /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
    
  2. /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