シェルスクリプトで条件を使用する方法

シェルスクリプトで条件を使用する方法

ifスクリプトにステートメントがあります。

次のようになります。

if [ "$a" != "0" -a "$b" != "100" ]; then
 #some commands here

私が正しく覚えている場合、両方の条件が真であれば、上記の行が機能します。

今どのようにテストしますか?誰でもどちらも真になる前に1つまたは両方の条件を実行しますかsome commands

答え1

標準(POSIX shおよびユーティリティ)でこれを指定する明確な方法は次のとおりです。

  • ひも比較する:

    if [ "$a" != 0 ] || [ "$b" != 100 ]; then...
    
  • 10進数比較してください(0100は100ですが、先行スペースが無視されるかどうかは実装によって異なります)。

    if [ "$a" -ne 0 ] || [ "$b" -ne 100 ]; then...
    
  • 整数比較してください(0x64、0144は100です(一部のシェルは8進数に対してPOSIXモードを有効にする必要があります)。RANDOMしたがって、シェル100.0、1e2、50 + 50...によると(0.003%の場合)...):

    if [ "$((a != 0 || b != 100))" -ne 0 ]; then...
    

    ただし、変数の内容が構文エラーのため算術拡張に失敗するとシェルがクラッシュするため、この問題を解決するにはサブシェルで実行する必要があります。

    if ([ "$((a != 0 || b != 100))" -ne 0 ]); then
    

    変数の内容を制御できない場合は、この形式を使用しないでください。一つ任意コマンド実行の脆弱性数多くの樹皮の中からbash、、、kshzsh(例えば、$aのような値x[$(reboot)])。

どちらを選択するかは、変数の内容と目的の内容によって異なります。標準形式の10進整数が含まれていることがわかっている場合、3つすべて同じです。

それにもかかわらず-a/-o test演算子を使用しないでください。一般的に廃止され、信頼できない(変数の内容を制御できる場合はここではありません。)

答え2

あいまいさを避けるために、算術評価と括弧を使用してください。

if (( ($a != 0)  || ($b != 100) )); then
# some commands

または文字列も処理するには[[

答え3

[ "$((a||b^100))" -eq 1 ] && some commands

シェルの数学拡張は、式を1(true)または0(false)に評価して、ブール値&&AND ||ORおよびNOT条件を処理します。!また、ビット&AND |OR および^XOR 演算子を処理しますが、ビット式をここで示すようにブール評価のフィールドとして使用できますが、必ずしも結果が 0 または 1 になるわけではありません。興味深いことに、シェルは回転~<<左右の>>SHIFT操作も実行できます。

したがって、aORb^100がtrueの場合、拡張は1と評価され、比較-eq [テストと一致し、]シェルは残りの評価を続行します&& some commands

整数をまとめるよりも、このように整数を評価/比較する方が簡単なことが多いです。

...そしてバイナリ-aプライマリ-oと演算子は廃止されたとマークされてい(ます)(これを使用する多くの式は、評価される特定の式に従って構文によってあいまいに定義されます。)

(^test仕様から直接引用)

これが成功しても正式に加入する前に行くことができる制限は4つです。指定されていない地域。

過去には、次のような抽象化を適用すると便利であることがよくわかりました。

math(){ return "$((!($1)))"; }

...次のように使用できます

math 'a||b^100' && some commands

これは私が考えたものとは異なりますが、実際にPOSIX仕様で得られました。XRAT 基本的な部分:

... [i]は、  test 注文が次のように結論付けます。( [)これはほとんどのリレーショナル算術テストには十分であり、シェル内の複雑な関係式を含むテストはまれですが、  "$(())" 独自の値をテストすることで満足できます。たとえば、

    # a complicated relational expression
    while [ "$(( (($x + $y)/($a * $b)) < ($foo*$bar) ))" -ne 0 ] 

...またはもっと良いことは、複雑な関係式を持つ珍しいスクリプトがそのような関数を定義できることです。

    val() { return "$((!$1))"; }

"(上記の引用を追加しましたが、その人は何が問題になるのでしょうか?)

答え4

上で見たよりも簡単な答えです。

if [ "$a" != "0" -o "$b" != "100" ]; then

関連情報