シェルスクリプトのboolean値を表すためのベストプラクティスは何ですか?


15

私は中にブール値があることを、知っているbashが、私は今まで彼らがどこにも使用され表示されません。

マシンで頻繁に検索される情報のラッパーを作成したいと思います。たとえば、この特定のUSBドライブが挿入/マウントされています。

それを達成するためのベストプラクティスは何でしょうか?

  • 文字列?

    drive_xyz_available=true
  • 数値(0はtrue、0はfalse)?

    drive_xyz_available=0    # evaluates to true
  • 機能?

    drive_xyz_available() { 
        if available_magic; then 
                return 0 
        else 
                return 1 
        fi
    }

私は主に、ラッパーを使用したい他の人に何が期待されるのだろうかと思います。ブール値、変数のようなコマンド、または呼び出す関数を期待しますか?

セキュリティの観点からは、2番目のオプションが最も安全だと思いますが、あなたの経験を聞きたいと思います。


3
help true ; help false ; help exit
コスタ

3
@Costas精緻化してもらえますか?
ミニックス

回答:


2
bool(){ return "$((!${#1}))"; }

if bool "$var"
then : do true
else : do false

上記を機能させるためには、変数をnull以外の値に設定するだけ[ -n "$var" ]です。

一般に、スクリプトが環境変数をtrueまたはfalseとして解釈する場合、すべての値をtrue (および場合によってはこの値を使用してオプションを構成する)またはnull値をfalseとして解釈します。

上記リターンboolean型!notの引数が、それは他に、0を返す0以外の任意の数の文字が含まれている場合、すべての文字なしならば、それはこれはあなたが行うことができ、同じテストである1を返します。 -最初の引数ののlenの値は[ -n "$var" ]基本的には、 、しかし、それは名前の小さな関数でそれをラップしていますbool()

これは通常、フラグ変数の機能です。例えば:

[ -d "$dir" ] || dir=

スクリプトの必要性の他の部分は、すべての中で任意の値を探してどこ$dirにその有用性を評価します。これは、パラメーター置換が関係する場合にも便利です-パラメーターをデフォルト値に拡張して空または未設定のものを埋めることができますが、それ以外の場合はプリセット値に拡張します...

for set in yes ''
do echo "${set:-unset or null}"
done

...印刷されます...

yes
unset or null

もちろん、反対のことを行うこともでき:+ますが、上記のフォームでは値またはデフォルト値を指定できますが、プリセットのデフォルト値を指定するか、まったく指定しないだけです。

そして、3つの選択肢に関するので - いずれかは、あなたがそれを実装することを選択した方法に応じて仕事ができます。関数の戻り値は、自己テストですが、そのリターンニーズが何らかの理由で保存した場合、変数に入れてする必要があります。一度テストおよびDONEタイプを評価したいブール値がある - それは、ユースケースに依存しますか?その場合は、他のいずれかの他の二つの、おそらく必要があり、機能を実行します。


1
あなたが私の質問に答えているとは思わない。シェルスクリプトでブール値をどのように使用できるかを尋ねているわけではありませんが、どの方法が最も一般的であり、別のユーザーが期待する方法です。私の質問が不明な場合は、喜んで編集します。また、あなたの答えが何をするのかについての短い説明がいいでしょう。ありがとうございました。
ミニックス

@ミニックス
mikeserv

私は通常、変数に割り当てるtruefalse、変数を割り当てることができますif $variable; then ...
ウルテル

@wurtel-デフォルトに依存します$IFS-そして、varの値にあらゆる種類のユーザー入力が含まれる場合は、幸運にもなります。値が最初から不明でない場合は、テストする必要はほとんどありません。if ${var:+":"} false; thenブール値のnull / not null値で作業する場合、より安全に行うことができます。しかし、それはめったに[ -n "$var" ] &&
-Mikeserv

スクリプトを開始し、variable=false条件に応じてtrueに設定すると(Cで変数を使用するときと同じように)、何の問題もありません。IFS値やランダム変数値の変化に対する強迫観念はとにかくです。 。
wurtel

4

ではbash、すべての変数、基本的に文字列(または配列または機能が、ここでは通常の変数についてのletの話)です。

条件は、テストコマンドの戻り値に基づいて解析されます。戻り値は変数ではなく、終了状態です。あなたが評価した場合if [ ... ]またはif [[ ]]またはif grep somethingまたはそのような何かが、戻り値0(文字列ではありません0しかし、終了ステータス0 =成功)が真と残りの平均偽(意味ので、あなたがコンパイルされたプログラミング言語のに使用されているものとは全く逆の、しかし、成功する1つの方法と失敗する多くの方法があり、実行の期待される結果は通常成功であるため、何も問題がなければ、最も一般的なデフォルト結果として0が使用されます)。これは、任意のバイナリをテストとして使用できるため、非常に便利です。失敗した場合はfalse、それ以外の場合はtrueです。

trueそしてfalseプログラムは、(通常は組み込みコマンドによって上書き)何もしないだけで便利な小さなプログラムです- true何もしないで成功し、0で終了し、一方、false試行は何もしないし、「失敗」、1音でexitting無意味が、それは、スクリプトのために非常に便利です。

真実を完全に伝える方法については、あなた次第です。真実と使用のために「y」または「yes」を使用することは非常に一般的ですif [ x"$variable" = x"yes" ](長さがゼロの場合、解析しない偽のコマンドを作成しないxようにダミー文字列を追加します)。これは、単に空の偽の文字列、および使用を使用することが有用であり得る(またはそれが長さゼロだかどうかをテストするためにそれが非ゼロであるために)。$variableif [ = "yes" ][ -z "$variable ]-n

とにかく、それは実際に周りのブール値を渡す必要があることは非常にまれだbash、それははるかに共通の単純だ- exitことができます失敗した場合、または有用な結果を返す(何かがうまくいかない場合はゼロを、そして空の文字列のための試験)、およびほとんどの場合出口ステータスから直接障害をテストします。


あなたのケースでは、他のコマンドとして機能する関数が必要です(したがって、成功すると0を返します)ので、最後のオプションが正しい選択のようです。

また、return声明さえ必要ないかもしれません。関数が十分に単純な場合、関数内で最後に実行されたコマンドのステータスを単に返すという事実を使用できます。したがって、関数は単純に

drive_xyz_available() {
   [ -e /dev/disk/by-uuid/whatever ]
}

(やgrepは、デバイスノードの存在をテストしている場合/proc/mounts、それはのマウントかどうかを確認するには?)。


これはとてもいい要約です。時間をかけて書いてくれてありがとう。あなたの最後の段落から、あなたdrive_xyz_available()は最も一般的な選択肢を検討すると思いますか?
ミニックス

一般的なy = trueケースの例をいくつか提供できますか?私の経験では、ほとんどのラッパースクリプトは、少なくとも解釈された環境変数が関係している場合、null以外の値をテストしてtrueと見なします。それ以外の場合は、シェルカーを完全に無視します。
mikeserv

3
if変数が引用符で囲まれている場合、テスト用のダミー文字列は不要です。if [ "$variable" = "yes" ]$ variableが設定されていなくても正常に動作します。
ダニエルクルマン

-2

基本的に、0以外の数値はすべて真であり、0は偽です。スクリプトまたは他の番号が正常に終了した場合に値を0として返し、さまざまな種類のエラーを識別する理由。

$? 前のコマンド/実行可能ファイルの終了コードを返します。成功の場合は0、その他の場合はエラーが返されます。

そのため、このメソッドをtrue / falseに使用します。 if (( ! $? ));then OK;else NOOK;fi


それでは、最後のオプションの1つを作成します。ありがとうございました。
ミニックス

5
ゼロ以外の数字は実際には偽であり、ゼロは真です。ただの出力を見てtrue; echo $?false; echo $?
ルスラン

@Ruslan。コマンドの出力を確認しましたか?そうしなかったと思いますが、そうでなければ、あなたが何をしたかを述べなかったでしょう。0はfalse、その他の数値はtrue、!結果を否定する理由はTRUEです。コマンドの結果は、正常に終了すると0になります。これは、0が真であることを意味するものではありません。単語trueは0でもかまいませんが、if条件が示すように0は決して真ではありません。
ヨミスモ

それは、C / C ++に、と言って同じです0ですtrueのでif(!x){True();}else{False();}呼ぶTrue()ときx==0。しかし、正しいチェックはそうではなく!x、むしろでしょう!!x
ルスラン

あなたは間違っています。ifC / C ++ a 0がFALSEの場合のように(bash、またはksh、またはtsh、または...)であるという事実を述べた後、あなたが書いたものが何でどの順序であるかについては話していません他の数値はTRUEです。次のリンクを読むとわかるように、Cの初期実装はブール型を提供せず、0がFALSEで1がTRUEであるintとして定義されていますen.wikipedia.org/wiki/Boolean_data_type
ヨミスモ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.