Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Detect if a script is being sourced vs executed



Here's an example of what I use in my scripts (zsh 5.0.2):

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


On Fri, Sep 12, 2014 at 10:57 AM, Daniel Hahler <dhahler@xxxxxxxxx> wrote:

> I want to detect if a script is being sourced instead of being called.
>
> This is meant for pyenv, which uses shims to delegate execution to the
> selected Python version.
>
> Currently it always uses "exec" to do so, but there is a pull request to
> add support for scripts that are meant to be sourced (like
> virtualenvwrapper.sh), and then would use "source" instead of "exec" in the
> shim.
>
> The PR provides this functionality for Bash, which provides a way to
> detect this via $BASH_SOURCE/$BASH_LINENO:
> https://github.com/yyuu/pyenv/pull/100/files
>
>
> My current approach so far is the following, which requires Zsh 5.0.5 (for
> POSIX_ARGZERO) and does not work for "zsh test_source.sh" yet (a patch has
> been posted to zsh-workers to fix this).
>
> I would like to do this for older Zsh versions, and in a simpler / more
> elegant way.
>
>
> Script to be sourced (test_source.sh):
>
>     #!/usr/bin/zsh
>
>     echo "\$0: $0"
>
>     sourced=0
>     if [ -n "$ZSH_VERSION" ]; then
>       # Use prompt expansion to get the current file.
>       cur_file=${(%):-%x}
>
>       # Fix $0:
>       if (( ${+options[posixargzero]} )); then  # added in zsh 5.0.5
> (2014-06-01)
>         if [[ $options[posixargzero] != "on" ]]; then
>           setopt posixargzero
>           [ "$0" = "$cur_file" ] || sourced=1
>           setopt noposixargzero
>         else
>           [ "$0" = "$cur_file" ] || sourced=1
>         fi
>       else
>         echo "TODO"
>       fi
>
>     elif [ -n "$BASH_VERSION" ]; then
>       [ "$0" = "$BASH_SOURCE" ] || sourced=1
>     fi
>
>     echo "sourced: $sourced"
>
>
> Test script (test.sh):
>
>     #!/usr/bin/zsh
>
>     echo "== CALL"
>     ./test_source.sh
>
>     echo "== SOURCE"
>     . ./test_source.sh
>
>     echo "== CALL: bash"
>     bash ./test_source.sh
>
>     echo "== CALL: zsh"
>     zsh ./test_source.sh
>
>     echo "== EXEC"
>     exec ./test_source.sh
>
>
> There must be an easier way!?
>
> It would be really useful, if Zsh would provide a mechanism like Bash to
> simplify this.
>
>
> Regards,
> Daniel.
>



-- 
Kurtis Rader
Caretaker of the exceptional canines Junior and Hank


Messages sorted by: Reverse Date, Date, Thread, Author