sh 1つのコマンドでANDとOR

sh 1つのコマンドでANDとOR

1行のコードで3つの条件を確認しようとしました。

デフォルトでは、次のコードを記述する必要があります。

もし

文字列 1 は文字列 2 と同じではありません。

そして

文字列 3 は文字列 4 と同じではありません。

または

ブール1 = true

それから

「条件を満たす - コード実行中...」と表示されます。

コメントで尋ねたように、質問をより明確にするために例を更新しました。

#!/bin/sh

string1="a"
string2="b"
string3="c"
string4="d"
bool1=true

# the easy-to-read way ....
if [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] ; then
    echo "conditions met - running code ..."
fi

if $bool1 ; then
    echo "conditions met - running code ..."
fi

# or the shorter way ...
[ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] && echo "conditions met - running code ..."

$bool1 && echo "conditions met - running code ..."

上記のコードは2回実行できます。最初の2つの条件が満たされた場合は再実行され、3番目の条件が満たされると再実行されます。これは私にとって必要なものではありません。

この例の問題は、2つの異なる「エコー」呼び出しが含まれていることです。 (注:実際のコードではエコーではありませんが、アイデアを得ることができます。)3つの条件付きチェックを1つのコマンドにまとめてコードの重複を減らそうとします。

今すぐ首を振りながら画面に向かって「それはまさに」と叫ぶ人々がいると確信しています。いいえあなたはそうしなかった方法! 」

これを重複としてマークするのを待っている人がいるかもしれません...まあ、私が見たしかし、私が読んだ答えを使ってこれを行う方法を見つけることができれば、呪われます。

誰かが私を実現できますか? :)

答え1

これは働きます:

if    [ "$string1" != "$string2" ] \
   && [ "$string3" != "$string4" ] \
   || [ "$bool1" = true ]; then
    echo "conditions met - running code ...";
fi;

または、{ ;}読みやすさを高め、将来のメンテナンスを容易にするために囲まれています。

if { [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] ;} \
   || [ "$bool1" = true ] ; then
    echo "conditions met - running code ...";
fi;

指示:

  1. ブール変数のようなものはありません。
  2. 中括弧の末尾にはセミコロン({ somecmd;})が必要です。
  3. &&||評価して左から右へ上 -&&より優先します|| 内だけで(( ))そして[[..]]

&&[[ ]]より高い優先順位は、次の証明でのみ発生します。考えるbool1=true

そして[[ ]]

bool1=true
if [[ "$bool1" == true || "$bool1" == true && "$bool1" != true ]]; then echo 7; fi #1 # Print 7, due to && higher precedence than ||
if [[ "$bool1" == true ]] || { [[ "$bool1" == true && "$bool1" != true ]] ;}; then echo 7; fi # Same as #1
if { [[ "$bool1" == true || "$bool1" == true ]] ;} && [[ "$bool1" != true ]] ; then echo 7; fi # NOT same as #1
if [[ "$bool1" != true && "$bool1" == true || "$bool1" == true ]]; then echo 7; fi # Same result as #1, proved that #1 not caused by right-to-left factor, or else will not print 7 here

そして[ ]

bool1=true
if [ "$bool1" == true ] || [ "$bool1" == true ] && [ "$bool1" != true ]; then echo 7; fi #1, no output, due to && IS NOT higher precedence than ||
if [ "$bool1" == true ] || { [ "$bool1" == true ] && [ "$bool1" != true ] ;}; then echo 7; fi # NOT same as #1
if { [ "$bool1" == true ] || [ "$bool1" == true ] ;} && [ "$bool1" != true ]; then echo 7; fi # Same as #1
if [ "$bool1" != true ] && [ "$bool1" == true ] || [ "$bool1" == true ]; then echo 7; fi # Proved that #1 not caused by || higher precedence than &&, or else will not print 7 here, instead #1 is only left-to-right evaluation

答え2

&&条件式の最後に使用することは、前のコマンド(最初の引数)がステータス0(伝統的にプログラムの成功コードと見なされていた)を返す場合、後続のコマンド(2番目の引数)を実行することを意味します。また、$bool1そこに入力する内容は独立しているため、Bashはその値を実行するコマンドまたはプログラムの名前として解釈します。達成しようとしているのは、以下を[使用して実行される条件式評価のようです。

if [ "$string1" != "$string2" ]  && [ "$string3" != "$string4" ] || [ $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi

組み込みの「and」、-aおよび「or」、、、-o演算子を使用する古いコードを見ることができますが、POSIX仕様そして明確に定義されていません。

if [ "$string1" != "$string2" -a "$string3" != "$string4" -o $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi

kshたとえば、から派生したシェルを使用している場合は、組み込みbashテスト演算子を使用できます[[

[[ "$string1" != "$string2" && "$string3" != "$string4" || $bool1 -ne 0 ]] && echo "conditions met - running code ..."

ブール値は整数で表されるため、ここでは-ne「等しくない」整数式テストを使用できます。どのように動作するかを示すスクリプトは次のとおりです。

#!/bin/bash

string1="Hello"
string2="Hello"
string3="Hello"
string4="Hello"
bool1=1

if [ "$string1" != "$string2" ]  && [ "$string3" != "$string4" ] || [ $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi

exit 0

関連情報