シェルスクリプトでブール値を表すベストプラクティスは何ですか?

シェルスクリプトでブール値を表すベストプラクティスは何ですか?

にブール値があることはわかっていますが、bashどこにも使用されていることはわかりません。

たとえば、この特定のUSBドライブが接続/マウントされているかどうかなど、自分のコンピュータから頻繁に検索される情報のラッパーを作成したいと思います。

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

  • ロープ?

    drive_xyz_available=true
    
  • 数字(0は真、≠0は偽)ですか?

    drive_xyz_available=0    # evaluates to true
    
  • 機能?

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

私は主にラッパーを使用したい他の人が何を期待できるか知りたいです。ブール、変数に似たコマンド、または関数が呼び出されることを期待していますか?

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

答え1

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

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

単に変数をnull以外のものに設定すると、上記の操作は[ -n "$var" ]短くなりますが(明確ではない場合)実行されます。

通常、スクリプトが環境変数を true または false として解釈すると、すべての値が true として解釈されます。(指定された値は特定のオプションを設定するために使用されることもあります)それ以外の場合、null 値は false として扱われます。

上記の!not関数は、引数にゼロ以外の文字が含まれている場合は最初の引数len - 0のブール値を返し、そうでない場合は文字がまったくない場合は1を返します。[ -n "$var" ]デフォルトでは、これを使用して実行できるのと同じテストですが、という小さな関数で終わりますbool()

普通こんな感じだバナー変数が機能します。たとえば、

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

$dirスクリプトの残りの部分では、使いやすさを測定するために値を見つけることができます。これはパラメータ置換にも便利です。パラメータはデフォルト値に拡張され、空または設定されていないパラメータを埋めることができますが、そうでない場合は事前設定された値に拡張できます。たとえば...

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

...これが印刷されます...

yes
unset or null

もちろん、逆の場合も可能です:+が、これは事前設定されたデフォルト値のみを提供したり、まったく提供しませんが、上記の形式は値またはデフォルト値を提供できます。

したがって、これら3つのオプションに関して、実装方法に応じてどちらを操作することもできます。関数の戻り値は自己テストですが、何らかの理由で戻り値を保存する必要がある場合は、変数に入れる必要があります。ユースケースによって異なります。テストを一度評価してブール型で完了したいですか?その場合はその機能を実行し、そうでない場合は他の2つのいずれかが必要になることがあります。

答え2

bash変数は本質的に文字列(または配列または関数ですが、ここでは一般的な変数について話しています)です。

条件はテストコマンドの戻り値に基づいて解析されます。戻り値は変数ではなく終了状態です。評価するとき、if [ ... ]戻り値0(文字列0ではなく終了ステータス0 if [[ ]]=if grep something成功)はtrueを意味し、残りはfalseを意味します。したがって、コンパイルプログラミングに慣れているものとは正反対です。しかし、成功する方法は1つであり、失敗する方法はいくつかあり、予想される実行結果は通常成功であるため、問題が発生しない場合は、最も一般的なデフォルト結果としてゼロが使用されます。これはすべてのバイナリをテストとして使用できるため便利です。失敗した場合は false、それ以外の場合は true

trueプログラムfalse(通常は組み込み機能で上書きされます)は何もしない便利な小さなプログラムです。true正常に何も実行せずに0で終了しますが、false試みは何もせずに「失敗」して1で終了します。無意味に聞こえますが、スクリプトにはとても便利です。

真実を伝える方法はあなた次第です。真偽と使用法を示すために「y」または「yes」のみを使用するのが一般的です(長さが0の場合、解析できない偽のコマンドが生成されるのを防ぐためにダミーif [ x"$variable" = x"yes" ]文字列が追加されます)。単に空の文字列を使用して偽を表し、長さがゼロか(またはゼロ以外)テストすることも便利です。x$variableif [ = "yes" ][ -z "$variable ]-n

とにかく、実際にブール値を渡す必要がある場合はほとんどありませんbash。単に失敗したり、有用な結果(または問題が発生した場合は0を返し、空の文字列をテスト)を返す方が一般的exitで、ほとんどの場合直接実行できます。終了時のテスト失敗状態。


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

さらに、return声明は必要ないかもしれません。関数が十分に単純な場合は、関数で実行された最後のコマンドの状態のみを返すという事実を利用できます。したがって、あなたの機能は簡単です

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

デバイスノードが存在するかどうかをテストする場合(または/proc/mountsマウントされていることを確認するためにgrepを使用しますか?)

答え3

デフォルトでは、ゼロ以外のすべての数字は真で、ゼロは偽です。戻り値 0 は、スクリプトが正常に終了した理由を示し、他の種類のエラーの理由を識別する別の数値を表します。

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

だから私はその方法を使って真/偽を判断します。if (( ! $? ));then OK;else NOOK;fi

関連情報