0

私はいくつかの BASH スクリプトを書いていますが、エラー処理メカニズムが必要です。

function f()
{
  command1 || { echo "command1 failed"; return 1; }
  command2 || { echo "command2 failed"; return 1; }
  command3 || { echo "command3 failed"; return 1; }
  command4 || { echo "command4 failed"; return 1; }
}

関数を定義して、この繰り返し構造を読みやすくしたいと思います。

function print_and_return()
{
  echo "$@"
  # some way to exit the caller function
}

f関数を次のように書くことができるように

function f()
{
  command1 || print_and_return "command1 failed"
  command2 || print_and_return "command2 failed"
  command3 || print_and_return "command3 failed"
  command4 || print_and_return "command4 failed"
}

これを達成するための最良の方法は何ですか?ありがとう。

4

3 に答える 3

2

問題

あなたはしたい:

  1. コードを少しきれいにします。
  2. コードを少し乾かします。
  3. コマンドが最初に失敗したときに実行を停止します。

1つの可能な解決策

コードをリファクタリングできます。例えば:

print_and_return() {
  echo "command failed: $@" >&2
  return 1
}

commands=("cmd1" "cmd2" "cmd3" "cmd4")

for cmd in "${commands[@]}"; do
    { $cmd || print_and_return "$cmd"; } || break
done
于 2012-06-16T04:48:31.923 に答える
1

を使用できるかもしれませんがset -e、シェルを終了するので注意する必要があります。

function f()
{
    (
    set -e
    command1
    command2
    command3
    command4
    )
}

コマンドが問題を診断している限り、この関数は最初のコマンドが失敗したときに停止します。

テスト版:

function f()
{
    (
    set -e
    true
    echo true
    true
    echo true
    false
    echo false
    true
    echo true
    )
}

echo calling function
f
echo still here

出力:

calling function
true
true
still here

NB: シーケンスを使用した場合:

echo calling function
if f
then echo still here - f passed
else echo still here - f failed
fi

次に、Mac OS X 10.7.4 上の bash 3.2.48 では、関数の動作が異なります。

calling function
true
true
false
true
still here - f passed

したがって、独創的ですが、完全に信頼できるわけではありません。

于 2012-06-16T07:31:53.983 に答える
0

CodeGnomeのソリューションに似ていますが、配列を使用していません (すべてのシェルに存在するとは限りません)。

function callthem()
{
    for cmd; do # short form for "for cmd in "$@"; do"
        "$cmd" || { echo "$cmd failed." >&2; return 1; }
    done
}

function f()
{
    callthem command1 command2 command3 command4
    # or maybe even
    callthem command{1,2,3,4}
}
于 2012-06-16T07:14:31.057 に答える