这接受的答案对于类似的问题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
$ZSH_SUBSHELL
计算结果为0
if ,且仅当您不在子 shell 中时。看http://zsh.sourceforge.net/Doc/Release/Parameters.html#Parameters-Set-By-The-Shell
要查看您是否被source
d,请检查是否zsh_eval_context
包含单词file
:
if (( zsh_eval_context[(I)file] )); then
echo "sourced"
else
echo "not sourced"
fi
$zsh_eval_context
file
当直接从文件读取代码时,例如使用.
或 内置函数时,将包含该单词source
。看http://zsh.sourceforge.net/Doc/Release/Parameters.html#Parameters-Set-By-The-Shell$zsh_eval_context[(I)file]
0
如果$zsh_eval_context
不包含单词,则计算结果为file
。看https://zsh.sourceforge.io/Doc/Release/Parameters.html#Array-Subscripts
答案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