
これ受け入れられた回答同様の問題には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
現在の対話型シェルがある場合、スクリプトzsh
は毎回完全に間違った結果を得ます。パフォーマンスが少し優れていますbash
(ただし、1日に2回正確に時間を維持するストップウォッチを思い出させますが)。
これらは実際にひどい結果を見ると、このアプローチに対する確信はほとんどありません。
もっと良いものがありますか?
答え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
サブシェルに存在することを確認するには、次の値を確認してください$ZSH_SUBSHELL
。
if (( ZSH_SUBSHELL )); then
echo "subshell, $ZSH_SUBSHELL fork(s) deep"
else
echo "not a subshell"
fi
$ZSH_SUBSHELL
0
サブシェルにない場合にのみ評価されます。バラより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
シェルレベルを得ることができます:
[ $SHLVL -gt 1 ] && echo "subshell"
また利用可能です(ZSHのみ)$ZSH_SUBSHELL
。
もちろん、巣を作ると壊れるでしょう。
答え4
あなたが探している答えは、ログインとインタラクティブシェルの違いではありませんか?
localhost% cat foo
#!/usr/bin/env zsh
[[ $- == *i* ]] && print ' interactive=sourced' || print ' login=called'
localhost% source foo
interactive=sourced
localhost% zsh foo
login=called