How to a zsh script test whether it is being sourced

zsh

The accepted answer for a similar question for bash does not seem to work for zsh. In fact, if I copy basically the same code given in that answer, to produce the script

#!/usr/bin/zsh -
# test.sh

[[ $_ != $0 ]] && echo "sourced\n" || echo "subshell\n"

the output hardly ever corresponds to the actual situation:

zsh% chmod +x ./test.sh
zsh% env -i /usr/bin/zsh -f
zsh% ./test.sh
sourced

zsh% /usr/bin/zsh ./test.sh
sourced

zsh% /bin/bash ./test.sh
sourced

zsh% source ./test.sh
subshell

zsh% . ./test.sh
subshell

zsh% env -i /bin/bash --norc --noprofile
bash-3.2$ ./test.sh
sourced

bash-3.2$ /usr/bin/zsh ./test.sh
sourced

bash-3.2$ /bin/bash ./test.sh
sourced

bash-3.2$ source ./test.sh
sourced

bash-3.2$ . ./test.sh
sourced

When the current interactive shell is zsh, the script gets it exactly wrong every time. It fares a bit better under bash (though in a way reminiscent of the stopped watch that gets the time exactly right twice a day).

These truly abysmal results give me little confidence in this approach.

Is there something better?

Best Answer

if [[ $ZSH_EVAL_CONTEXT == 'toplevel' ]]; then
    # We're not being sourced so run the colors command which in turn sources
    # this script and uses its content to produce representative output.
    colors
fi

Via Kurtis Rader on the zsh-users mailing list.

Related Question