
これはおそらく具体的な答えがない、やや難解なZshの質問です。
Zshが特定の方法でインスタンス化されたときに特定のコンテキストを検出しようとしています。この目的のために一般的に使用される環境変数(例えば、、、および)を考慮すると、$SHLVL
これを$ZSH_SUBSHELL
行う方法は、少なくとも私の知識ではすぐには明確ではありません。$ZSH_EVAL_CONTEXT
$-
以下は通常、検出可能な方法でインスタンス化されたZshです。
export HELLO='world'
zsh -c 'echo "$SHLVL $ZSH_SUBSHELL $ZSH_EVAL_CONTEXT $- $HELLO"'
# 2 0 cmdarg 569X world
検出をマスクするようにインスタンス化されたZshとは対照的に:
export HELLO='world'
(zsh -c 'echo "$SHLVL $ZSH_SUBSHELL $ZSH_EVAL_CONTEXT $- $HELLO"')
# 1 0 cmdarg 569X world
world
サブシェルから呼び出されたZshは、その存在として示されているように親環境の変数にアクセスできますが、残念ながら、この場合、その値は役に立たないと欺いて$SHLVL
報告します。1
$ZSH_SUBSHELL
0
標準検出方法を使用して、2番目のケースが親環境にアクセスできることをどのように検出できますか?必要でない場合は、この目的のために親コンテキストで設定した変数を確認して環境を汚染したくありません。
$SHLVL
誰かがZshがそれを解読する方法と、このコードをサブシェルに入れる理由が検出をマスクするかどうかを説明できれば役に立ちます。私が大まかに理解したのは、サブシェルが環境(エクスポートしたすべてのもの)をフォークして$SHLVL
エクスポートしないことです。
答え1
それは抜け穴(返却)は1999年に導入されました。その変化今修正されました。その変化(犯罪))
基本的には次のようになります。
(cmd1; cmd2)
zsh
サブシェルのサブプロセスをフォークし、次にフォークしますcmd1
。ただし、フォークの場合、cmd2
サブシェルの最後のコマンドであることを考慮すると、zsh
フォークは最適化されます。まるで私たちがすでにやったように見えます:
(cmd1; exec cmd2)
または言い換えればzsh
、絶対的な/徐々に進む exec
ここで。
今の場合、エラーが発生します。zsh
忘れる私たちはサブシェルにあり、仮定します。絶対的な exec
実際には終了シェル(に置き換えcmd2
)を使用してから、$SHLVL
親cmd2
が存在しなくなったために減少しますzsh
。
しかし、ここはサブシェルにあるので絶対的なexec
シャットダウンシェルはありません。
この質問をお寄せいただきありがとうございます。これにより問題を解決し、関連するエラーを見つけることができます。存在するbash
そしてtcsh
。