bashでトラップEXITを使用して実行を続行するには?

bashでトラップEXITを使用して実行を続行するには?

環境:GNU bash、バージョン 3.2.57(1)-リリース(x86_64-apple-darwin20)

他の関数の終了をキャッチしようとしていますが、プログラムの実行を続けます。オブジェクト指向言語では、例外をキャッチして再度発生させることなく実行を続行できます。これが私が望むものです。関数を期待していますが、foo()このexit場合は関数をキャプチャしてプログラムの実行を続けたいと思います。

#!/bin/bash

function doNotExitProgram()
{
   echo "Ignoring EXIT"
    # Magic happens here
}

trap doNotExitProgram EXIT

function foo()
{
    echo "Inside foo()"
    exit 170
}

foo
echo "Continue execution here"

期待される:

foo() 内部は
EXIT を無視し
、ここで実行を続けます。

実際:

foo() 内部では
EXIT を無視します。

これまでに試した手順:

  1. EXITを試してみましたが、うまくshopt -s extdebugいかないようです。

  2. trap - EXIT内部で試すdoNotExitProgram()

  3. 中にtrap - EXIT戻ろうとするreturn 0doNotExitProgram()

  4. 中にtrap - EXIT戻ろうとするreturn 1doNotExitProgram()

  5. return 0内部で試すdoNotExitProgram()

  6. return 1内部で試すdoNotExitProgram()

  7. trap "" EXIT内部で試すdoNotExitProgram()

このシーンはありませんtldp.orgの罠またはトラップのマニュアルページ

編集する:可能であれば変更しないでください。foo()

答え1

または、ヘルパー機能を使用してください。

#!/bin/bash

function doNotExitProgram()
{
   echo "Ignoring EXIT"
    # Magic happens here
}

function catchExitCode()
{
    case $1 in
        170 )
            doNotExitProgram
            ;;
    esac
}

trap 'catchExitCode $?' DEBUG

function foo()
{
    echo "Inside foo()"
    return 170
}

foo
echo "Continue execution here"

という分岐関数を追加できますcatchExitCode。欠点は、他の実行可能ファイルが返されるとハイジャックされる可能性があることです170。独自の終了コードを使用すると、ロジックを分岐できます。

答え2

使用xオプション( bash -x file):

+ trap doNotExitProgram EXIT
+ foo
+ echo 'Inside foo()'
Inside foo()
+ exit 170
+ doNotExitProgram
+ echo 'Ignoring EXIT'
Ignoring EXIT

trap doNotExitProgram EXITdoNotExitProgram呼び出しは呼び出されると発生しますexit。呼び出されたらfoo実行しますdoNotExitProgramexitスクリプトの実行が完了して実行されませんecho "Continue execution here"

解決する:

#!/bin/bash

(
  function doNotExitProgram()
  {
    echo "Ignoring EXIT"
      # Magic happens here
  }

  trap doNotExitProgram EXIT

  function foo()
  {
      echo "Inside foo()"
      exit 170
  }

  foo
)
echo "Continue execution here"

結果:

Inside foo()
Ignoring EXIT
Continue execution here

オプションを含むx

+ trap doNotExitProgram EXIT
+ foo
+ echo 'Inside foo()'
Inside foo()
+ exit 170
++ doNotExitProgram
++ echo 'Ignoring EXIT'
Ignoring EXIT
+ echo 'Continue execution here'
Continue execution here

サブシェルにトラップを設定できます。期待値を出力します。

答え3

exit関数を使用したコマンドの非exit表示

「ヘルパー機能」ソリューションと同様に、
これは基本スクリプトを「続行」しません。

基本スクリプトの「継続実行」はbashで実行する必要があります
Bashに「goto」ドアがありますか?

function evil_function() {
    echo "code before exit"
    exit 1
    echo "code after exit"
}

# shadow the exit command
function exit() {
    local rc=$?
    if [ -n "$1" ]; then rc=$1; fi
    echo "captured exit $rc"

    # no, this would continue "code after exit"
    #return $rc

    # restore the exit command
    unset -f exit

    # continue script here, then exit
    echo "exiting in 5 sec"
    sleep 5

    exit $rc
}

evil_function

# will not continue here

関連情報