関数ローカル `set -e`

関数ローカル `set -e`

そのような機能はありますか?それとも簡単にエミュレートできますか?呼び出しが発生するreturn場所を除いて、同じ動作が必要です。set -eexit

答え1

サブシェルが役に立ちます。

func() {(set -e
        echo a
        ehco b
        echo c
)}

func
func
func

このスクリプトは以下を生成します。

a
script.sh: line 3: ehco: command not found
a
script.sh: line 3: ehco: command not found
a
script.sh: line 3: ehco: command not found

それとも興味があるかもしれません。Bashでtry/catchを実装する

答え2

ERRコマンドがゼロ以外の状態を返すたびに実行されるトラップを設定できます。

Bashでは、トラップは関数にローカルではないため、これはもう少し複雑です。デフォルトでは、トラップはそれを変更するためのサブシェルまたはサブ関数呼び出しによって継承されませんset -E。以下はいくつかのデモコードです。

#!/bin/bash

subroutine () {
  false
  echo "Subroutine continued after status $?"
}

trapper () {
  local i ret
  trap 'ret=$?
        echo "Command $BASH_COMMAND returned status $ret"
        for ((i=0; i<$((${#FUNCNAME[@]}-1)); i++)) do
          echo "  from ${FUNCNAME[$i]} at ${BASH_SOURCE[$((i+1))]} line ${BASH_LINENO[$((i+1))]}"
        done
        return $ret' ERR
  trap 'ret=$?; trap - ERR RETURN; return $ret' RETURN
  echo ok
  subroutine
  echo "By default, the ERR trap is not inherited"
  false
  echo "You won't see this"
}

main () {
  trapper
  echo "trapper returned status $?"
  false
  echo "still there"
}

main

TRAPZERRzshでは、(互換性のために)または(という名前のシグナルを持つシステムでは何も知りません)のトラップを設定する代わりに、機能を定義できます。しかし、(エラーメッセージを印刷するのではなく)すぐに返したい場合は簡単です。オプションを設定するだけです。オプションはデフォルトでグローバルです。呼び出し関数に対してローカルになるようにオプションを設定します(関数が返されたときに設定されている場合は、関数呼び出し時にオプションを復元します)。デフォルトではトラップもグローバルです。オプションとトラップは関数呼び出し全体から継承されます。ERRZERRSIGERRerr_returnlocal_optionslocal_options

myfunction () {
  setopt local_options err_return
  false
  echo not executed
}

答え3

の場合、独自の構文をksh93使用して関数()を定義すると、オプションとトラップにローカルスコープがあります。したがって、次のようにすることができます。kshfunction f {...;}

function f {
  trap 'return 99' ERR
  set -e
  echo foo
  false
  echo never output
}
f
echo "f exited with status $?"

これは作る:

foo
f exited with status 99

関連情報