web-dev-qa-db-ja.com

Bash関数からブール値を返す

ファイルに特定のプロパティがあり、trueまたはfalseを返すかどうかを確認するbash関数を作成します。その後、スクリプトの「if」で使用できます。しかし、何を返すべきですか?

function myfun(){ ... return 0; else return 1; fi;}

次に、このように使用します:

if myfun filename.txt; then ...

もちろんこれは機能しません。どうすればこれを達成できますか?

172
luca

Trueの場合は0、falseの場合は1を使用します。

サンプル:

#!/bin/bash

isdirectory() {
  if [ -d "$1" ]
  then
    # 0 = true
    return 0 
  else
    # 1 = false
    return 1
  fi
}


if isdirectory $1; then echo "is directory"; else echo "nopes"; fi

編集

@amichairのコメントから、これらも可能です

isdirectory() {
  if [ -d "$1" ]
  then
    true
  else
    false
  fi
}


isdirectory() {
  [ -d "$1" ]
}
283
Erik

250以上の賛成票があるにもかかわらず、私が言うことを気にしなければならない理由

0 = true1 = falseではありません。 ゼロは障害なしを意味します(success)およびゼロ以外は障害を意味します(タイプN)

選択された回答 は技術的に「true」ですがpleasefalseのコードにreturn 1 **を入れないでください。不幸な副作用がいくつかあります。

  1. 経験豊富な開発者があなたをアマチュアとして見つけます(以下の理由により)。
  2. 経験豊富な開発者はこれを行いません(以下のすべての理由により)。
  3. エラーが発生しやすい。
    • 経験豊富な開発者でさえも、0と1をそれぞれfalseとtrueと間違えます(上記の理由により)。
  4. 無関係でばかげたコメントが必要です(または奨励されます)。
  5. 実際には、暗黙の戻りステータスよりも役に立たない。

Bashを学ぶ

bash manual と言う(強調する)

return [n]

シェル関数の実行を停止し、値nを呼び出し元に返します。 nが指定されていない場合、戻り値は最後に実行されたコマンドの終了ステータスです関数内。

したがって、TrueとFalseを示すために0と1を使用する必要はありません。彼らがそうするという事実は、コードのデバッグ、質問へのインタビュー、初心者の心を吹き飛ばすためにのみ有用な本質的に些細な知識です。

Bashマニュアル また言う

それ以外の場合、関数の戻りステータスは、最後に実行されたコマンドの終了ステータスです

Bashマニュアル また言う

$?)最後に実行されたフォアグラウンドパイプラインのexitステータスに展開されます

ちょっと待ってパイプライン?それでは bashのマニュアルを参照 もう一度。

パイプラインは、制御演算子「|」または「|&」のいずれかで区切られた一連の1つ以上のコマンドです。

はい。彼らは、1つのコマンドがパイプラインであると言いました。したがって、これら3つの引用符はすべて同じことを言っています。

  • $?は、最後に何が起こったかを示します。
  • 泡立ちます。

私の答え

そのため、 @ Kambusデモンストレーション では、そのような単純な関数ではreturnはまったく必要ありません。これを読むほとんどの人のニーズと比較して、私は非現実的に単純だったと思います。

なぜreturnなのか?

関数が最後のコマンドの終了ステータスを返す場合、なぜreturnを使用するのですか?関数が実行を停止するためです。

複数の条件下で実行を停止する

01  function i_should(){
02      uname="$(uname -a)"
03
04      [[ "$uname" =~ Darwin ]] && return
05
06      if [[ "$uname" =~ Ubuntu ]]; then
07          release="$(lsb_release -a)"
08          [[ "$release" =~ LTS ]]
09          return
10      fi
11
12      false
13  }
14
15  function do_it(){
16      echo "Hello, old friend."
17  }
18
19  if i_should; then
20    do_it
21  fi

ここにあるのは...

04のRHSはLHSがtrueの場合にのみ実行されるため、行&&は明示的な[-ish]がtrueを返す

09は、行08のステータスに一致するtrueまたはfalseを返します

13行は、12行のためにfalseを返します

(はい、これはゴルフダウンできますが、全体の例は不自然です。)

別の一般的なパターン

# Instead of doing this...
some_command
if [[ $? -eq 1 ]]; then
    echo "some_command failed"
fi

# Do this...
some_command
status=$?
if ! $(exit $status); then
    echo "some_command failed"
fi

status変数を設定すると、$?の意味がわかりやすくなります。 (もちろん、$?の意味を知っていますが、いつかGoogleに習熟するよりも知識の低い人がいます。コードが高頻度で取引されている場合を除き、 愛を見せてください 、変数を設定してください。)実際の要点は、「存在しない場合はステータス」、または逆に「終了ステータスがある場合」を読み上げて、その意味を説明できることです。 ただし、最後の1つは少し野心的かもしれません。なぜなら、実際には終了しているときに、exitという単語を見ると、スクリプトを終了していると思うかもしれないからです。 $(...)サブシェル。


** return 1をfalseに使用することを絶対に主張する場合は、少なくともreturn 255を代わりに使用することをお勧めします。これにより、将来の自分自身、またはコードを維持する必要がある他の開発者が「なぜ255なのか?」そうすれば、彼らは少なくとも注意を払い、間違いを回避する可能性が高くなります。

112
Bruno Bronosky
myfun(){
    [ -d "$1" ]
}
if myfun "path"; then
    echo yes
fi
# or
myfun "path" && echo yes
30
Kambus

オプション-dのみでディレクトリをチェックする場合は注意してください!
変数$ 1が空の場合、チェックは成功します。確実に、変数が空でないことも確認してください。

#! /bin/bash

is_directory(){

    if [[ -d $1 ]] && [[ -n $1 ]] ; then
        return 0
    else
        return 1
    fi

}


#Test
if is_directory $1 ; then
    echo "Directory exist"
else
    echo "Directory does not exist!" 
fi
13
RenRen

このfunction myfun(){ ... return 0; else return 1; fi;}をこのfunction myfun(){ ... return; else false; fi;}に書き換えると動作する場合があります。つまり、falseが関数の最後の命令である場合、関数全体で偽の結果が得られますが、returnはいずれにしても真の結果で関数を中断します。少なくとも私のbashインタープリターには当てはまると思います。

1
Nephew