zsh 脚本如何测试它是否被获取?

zsh 脚本如何测试它是否被获取?

接受的答案对于类似的问题bash似乎不适用于zsh。事实上,如果我复制该答案中给出的基本相同的代码来生成脚本

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

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

输出几乎不符合实际情况:

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

当当前的交互式 shell 为 时zsh,脚本每次都会得到完全错误的结果。它的表现要好一些bash(尽管在某种程度上让人想起每天两次准确计时的停表)。

这些确实糟糕透顶结果让我对这种方法信心不足。

还有更好的吗?

答案1

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

通过科蒂斯·雷德在 zsh-users 邮件列表上

答案2

要查看您是否位于子 shell 中,请检查 的值$ZSH_SUBSHELL

if (( ZSH_SUBSHELL )); then
  echo "subshell, $ZSH_SUBSHELL fork(s) deep"
else
  echo "not a subshell"
fi

要查看您是否被sourced,请检查是否zsh_eval_context包含单词file

if (( zsh_eval_context[(I)file] )); then
  echo "sourced"
else
  echo "not sourced"
fi

答案3

您可以获得 Shell 级别:

[ $SHLVL -gt 1 ] && echo "subshell"

还有(仅限 ZSH)$ZSH_SUBSHELL

显然,如果你筑巢,这些就会破裂。

答案4

您正在寻找的答案不是登录和交互式 shell 之间的区别吗?

localhost% cat foo
#!/usr/bin/env zsh

[[ $- == *i* ]] && print ' interactive=sourced' || print ' login=called'

localhost% source foo
 interactive=sourced
localhost% zsh foo   
 login=called

相关内容