web-dev-qa-db-ja.com

コマンド置換は時々err_exitを尊重しません

上記の行で成功したコマンドを挿入すると、コマンド置換($(I mean this))が期待どおりに機能しないという奇妙な状況があります。コマンドが失敗し、err_exitが設定されていても、コマンドは終了しません。

サブシェルの振る舞いが思ったのとは違うのではないかと思い続けていますが、なかなか指が届きません。

このプリントは「上に出るべきだった」:

#!/usr/bin/env zsh
setopt local_options err_exit warn_create_global nounset

local x
if false; then
else
    x=$(false)
    echo 'should have exited above'
fi

これは何も出力しません:

#!/usr/bin/env zsh
setopt local_options err_exit warn_create_global nounset

local x
if false; then
else
    true
    x=$(false)
    echo 'should have exited above'
fi

明らかに、そのtrueを残しておくことでスクリプトを正しく機能させることができますが、正しくないようで、説明することすらできません。では、何が起こっているのでしょうか。また、推奨される解決策は何ですか。

3
Simon

バグです。これが小さなテストケースです。

_set -e; if false; then :; else x=$(false); echo "$? $-"; fi
_

割り当てx=$(false)には、最後のコマンド置換のステータス(1)が含まれている必要があります。_set -e_がない場合、このスニペットは_1_の後にアクティブなシェルオプションを出力する必要があります。 _set -e_を使用すると、このスニペットは何かを出力する前に終了する必要があります。

Zsh 5.1.1は正しく機能します(ステータス1で終了します)。 Dash、bash、mksh、ksh93はすべて同じ動作をします。

今日GitからチェックアウトされたZshは、_1 569Xe_を出力し、ステータス0で終了します。falseの前にechoへの呼び出しを追加すると、スクリプトは期待どおりに終了します。 errexitx=$(false)に影響を与えないようです。 _git bisect_は言う b581c3fece76c87ed86ae9fc704d0fcf208a79d は最初の悪いコミットです。

現在は zshワーカーのメーリングリストで報告されています および 数時間後に修正されましたそのコミット で、次のリリースに含まれる予定です。