bashシェルの複数行のif条件


19

引数を取り、必要に応じて何かを実行するbashシェル関数があります。

do_somthing() {
  if [need to do something on $1]
  then
    do it
    return 0
  else
    return 1
  fi
}

いくつかの引数を指定してこのメ​​ソッドを呼び出し、少なくとも1つが成功したかどうかを確認します。

私は次のようなものを試しました:

if [ do_something "arg1" ||
     do_something "arg2" ||
     do_something "arg3" ]
then
  echo "OK"
else
  echo "NOT OK"
fi

そのための正しい構文は何ですか?
編集
-また、最初の条件が真であっても、他のすべての条件が評価されるようにします。

おかげで、


回答を更新しました。
tectux

ありがとう、例を挙げていただけますか?
イタイ

1
回答にコード例を追加しました。
tectux

回答:


7

最初にコマンドを実行してから、少なくとも1つが成功したかどうかを確認してください。

#!/bin/bash

success=0
do_something arg1 && success=1
do_something arg2 && success=1
do_something arg3 && success=1

if ((success)); then
    printf 'Success! At least one of the three commands succeeded\n'
fi

3
これは、...、...あなたはbashでどのように条件文の仕事にいくつかの説明を与えることができれば、私は喜んでいるよ、混乱成功時に0を返しdo_somethingが、その後、私たちは1に成功を更新しているif ((success))よりも別の何かに評価しますif success。私は混乱しています:)
Itay

2
@Itay ((...))は算術コマンドです。内部の結果がゼロ以外の場合、true(0)を返します。内部の結果が0の場合、false(1)を返します。「成功」は、数値を含むと予想される変数として扱われます。参照mywiki.wooledge.org/ArithmeticExpression
geirha

おかげで、私を混乱させた部分は、0が真で1が偽であるということだと思います。通常は逆です:)
Itay

2
@Itayはい、最初は混乱するかもしれません。Bashは「コマンドベース」であるという点で汎用言語とは異なります。関数を呼び出さず、クラスとメソッドを持たず、コマンドを実行し、コマンドの終了ステータスをテストします。また、C、python、java、perlなどの言語よりもbashでコマンドを実行する方がはるかに簡単です。コマンドは0で終了して成功を通知し、1-255はさまざまなタイプの失敗を通知します。(コマンドは、一般的に、一方向にのみ成功しますが、様々な異なる理由で失敗することができます)
geirha

2
このソリューションは、あなたが一時的に無効にしたくない行をコメントアウトすることができますという利点がある
ジョサイアYoderの

31

バックスラッシュを使用します。

if [ $(do_something "arg1") ] || \
   [ $(do_something "arg2") ] || \
   [ $(do_something "arg3") ]
then
  echo "OK"
else
  echo "NOT OK"
fi

編集

また、最初の条件が真であっても、他のすべての条件が評価されることを確認したいと思います。

1つのifステートメントでは不可能です。代わりに、引数を反復処理して個別に評価するforループを使用できます。何かのようなもの:

do_something() {
  for x in "$@"
  do
    if [need to do something on $x]
    then
      do it
    else
      echo "no action required on $x"
    fi
  done
}

おかげで、試してみました-エラーが表示されます[: do_something: unary operator expected
-Itay

各評価をそれぞれの括弧で囲みましたか?の[ expr1 ] || [ expr2 ]代わりに[ expr1 || expr2 ]
テクテックス

はい、私はやった:(...
Itay

私の推測では、do_something "arg1"2つの引数として解釈されるのに対し、式は単項でなければなりません。作る方法はdo_something "arg1"1つの引数として評価されますか?
イタイ

1
あなたが正しい。これも機能しますif [ $(do_something "arg1") ]
tectux

5

正しい構文は次のとおりです。

if  do_something "arg1" || \
    do_something "arg2" || \
    do_something "arg3"
then
  echo "OK"
else
  echo "NOT OK"
fi

\ 次の行にコマンドが続くことをシェルに伝えるために使用されます。

編集:私はこれがあなたが望むことをすべきだと思う:

#!/bin/bash

do_something() {
  if [need to do something on $1]
  then
    do it
    echo "OK"
  else
    echo "NOT OK"
  fi
}

do_something "arg1"
do_something "arg2"
do_something "arg3"

ありがとう、エラーの結果:[: too many arguments
Itay

@Itay Answerが更新されました。
エリック

質問の更新-これはまだ最終回答ではありません:(
Itay

-1

私が好む:

if {
    do_something "arg1" ||
    do_something "arg2" ||
    do_something "arg3"
}; then
    echo "OK"
else
    echo "NOT OK"
fi

スクリプトはまったく機能しません。最初のテストパラメーターの後に\n文字が生成されるため、ifステートメントはエラーを生成し、do_somethingコマンド名ではないため、さらにエラーが発生します
damadam

私にとっては、zshとbashで動作しdo_somethingます。IF はもちろん機能です。do_something関数またはコマンドである必要がありますが、他に何がありますか?さらに\n、結果をエコーし​​た後を除いて、文字が生成される場所がわかりません。これは予想されることです...
Toxiro
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.