KSH - バイアンプ(&&)とツインチューブ(||)を使用するif/then/else

KSH - バイアンプ(&&)とツインチューブ(||)を使用するif/then/else

if/then/elseのベストプラクティスは何ですか? (読みやすくなるため)次の形式を使用する傾向があります。

#!/usr/bin/ksh
#

[[ -f /path/to/target/file ]] && {
    echo "File exists"
} || {
    echo "No such file"
}

この形式ではなく

#!/usr/bin/ksh
#

if [ -f /path/to/target/file ] ; then
    echo "File exists"
else
    echo "No such file"
fi

また、「else」部分が実行されないように、複雑なブロックのtrue前にステートメントを追加しました。} || {

どんな提案がありますか?

答え1

このスタイルの問題は、2つの形式が同じではないことです。あなたが使用するとき:

if command; then
    foo
else
    bar
fi

これは呼び出されたり同時に呼び出されたりしませんfoo。と両方barを使用している場合は、2つのパスを使用できます。&&||

$ [[ -d / ]] && {
> echo "Path 1 taken"
> false
> } || {
> echo "Path 2 taken"
> }
Path 1 taken
Path 2 taken
$

フォームを使用する場合、if cmd; then foo; else bar; fi呼び出し条件はfalseを返すことです。フォームを使用する場合、呼び出し条件はfalseを返すことです。barcmdcmd && foo || barbarcmd && foo

true編集:あなたの質問であなたのバージョンが機能するためにブロックの最後に置く必要があることを認めたことがわかりました。これを行うことに興味がある場合は、他の主な問題はわかりません。しかし、可能であれば、スタイルの前にブロックの最後のコマンドとして無条件に「true」を追加する必要があるようです。コマンドが失敗する可能性があります。これは保証するためだけです。最終的には忘れてしまい、そうでないまですべてが正常に動作しているように見えます。

答え2

私の考えでは、if-then-elseが他の言語で書く人にとっては読みやすくなります。しかし、私の提案は、
1つだけを含む単一のコード行に短い表記法(&&または||を使用)を使用することです。次のようないくつかのコード &&||

[[ -d mustExist ]] || errorFunction "Dir mustExist is missing"
[[ -f toBeSend ]] && sendFile toBeSend
if [[ -d sometimes ]]; then
   writeTrueBlock
else
   writeFalseBlock
fi

編集:新しいアイデア:これを書く方が良いかもしれません。

test -d mustExist || errorFunction "Dir mustExist is missing"
test -f toBeSend && sendFile toBeSend
if [[ -d sometimes ]]; then
   writeTrueBlock
else
   writeFalseBlock
fi

答え3

読みやすさとスタイル

私はスクリプトで&&and演算子をたくさん使う傾向があります。||

一文に複数個を使ったこともありますが、続ける現在のブロックから。

例1:

for word in $list; do
    condition1 $word || continue
    condition2 $word || continue

    : do stuff with $word
    : do more stuff with $word
done

条件1そして条件2主張として。我々は例外を得た 空いているをクリックして、このコードが実行する必要がある操作を続行します。

if使い方がちょっとぎこちないですね…こんな状況ではねthenfi

代替記号:

例2:

for word in $list; do
    if condition1 $word && condition2 $word; then
        : do stuff with $word
        : do more stuff with $word
    fi
done

存在する実施例2追加の作業なしで他のレベルのインデントが可能です。

例3:

for word in $list; do
    condition1 $word && condition2 $word || continue
    : do stuff with $word
    : do more stuff with $word
done

両方の条件を簡単に表現すると、例3のように組み合わせることもできます。


PS:もともとシェルプログラマーのための練習を追加しました。3つの例のうち2つがまったく同じです。どちらが変ですか? 偶然にも私が存在すると思っていた違いはありませんでした。実は一つ書きました。shpecテスト:

describe "continue"
  it "discards last exit status"
    (for i in 1; do
     false || continue
     done
    )
    assert equal 0 $?
  end
end

shpec/continue_shpec.sh
continue
  discards last exit status
  1 examples, 0 failures

関連情報