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

現在の対話型シェルがある場合、スクリプト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

sourceあなたがDであることを確認するには、そのzsh_eval_context単語が含まれていることを確認してくださいfile

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

答え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

関連情報