set-uの使用法が期待どおりに機能しない

スクリプトでさまざまなsetオプションを効率的に使用する方法を学習しています変数が適切に設定されていない場合(ユーザーの削除など)にスクリプトを終了するのに最適なset -uに出くわしました。 man ページによると、set -uset -eは次のことを行います…

-e Exit immediately if a command exits with a non-zero status. -u Treat unset variables as an error when substituting. 

この機能をテストするためのテストスクリプトを作成しましたが、期待どおりに機能していないようです。おそらく誰かが私の問題を私にもっとよく説明し、私がどこで誤解しているのでしょうか?テストスクリプトは以下のとおりです。ありがとうございます。

set -e set -u testing="This works" echo $? echo ${testing} testing2= echo $? echo ${testing2} testing3="This should not appear" echo $? echo ${testing3} 

スクリプトに 0 および「これは機能します」、その後${testing2}のように失敗します設定されていません。

代わりに、 0 「これは機能します」、続いて 0 、次に 0 これは表示されません

誰かが知識を提供できますか?ありがとうございます。

コメント

  • フォローアップ…変数をnull文字列に設定することを違法にする/エラーを発生させる方法はありますか? '推測していません。

回答

From ” man Bash “:

パラメータに値が割り当てられている場合は、パラメータが設定されます。 null文字列は有効な値です。変数が設定されると、unset組み込みコマンドを使用することによってのみ設定を解除できます。

testing2=変数をnull文字列に設定しています。

これをunset testing2に変更して、再試行してください。


set -eは、この場合、割り当ての終了コードが1になることはないため、役に立ちません。これを試して、最後に実行されたコマンド(割り当て)の終了コードが0、またはこの質問を読む

$ false; a=""; echo $? 0 

また、set-eの使用は解決策というより多くの問題。

未設定の変数を使用するとエラーが発生する可能性があるのは、set -u

出力されます:

$ ./script.sh This works ./script.sh: line 9: testing2: unbound variable 

回答

testing2=は、testing2変数を空の文字列に設定します。変数は実際には設定されています

ただし、インタラクティブなBashシェルでecho $testing99を実行する場合(errexit、つまりset -e)の場合、エラーが発生します:

bash: testing99: unbound variable 

余談ですが

スクリプトをテストしているときに、インタラクティブシェルが常に終了するとは限らないことを発見しました 非対話型シェル(シェルスクリプトの実行)中に設定されていない変数を展開しようとした場合常にを終了します。 setのPOSIXマニュアルページによると:

-uシェルは標準エラーにメッセージを書き込む必要があります設定されていない変数を展開してすぐに終了しようとしたとき。インタラクティブシェルは終了しません。

errexitまたが設定されました。一方、インタラクティブなダッシュシェルは、set -eが以前に実行されていても終了しません。

コメント

  • ダッシュがset-eで終了しない場合;セット-u;未設定のaa; echo $ aaの場合、ダッシュは間違っています。
  • @schilyこれに最初に気付いたとき、ダッシュの作成者は私よりもよく知っていて、POSIX仕様にはあいまいさがあったかもしれませんが、 pubs.opengroup.org/onlinepubs/9699919799/utilities/ … を確認しましたが、バグのように見えることに同意します。
  • 単純なルールがあります。KornShellとBourneShellの両方が一致し、別のシェル実装に逸脱がある場合、他のシェルは正しく動作しません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です