||後の Union コマンド(または)演算子

||後の Union コマンド(または)演算子

以下のコードを書くときは、ステートメントの後に複数のコマンドを実行できますelse

if [ "$?" -eq 0 ]
    then              
        echo "OK"
    else 
        echo "NOK"
        exit 1
fi

ただし、他の構文を使用する場合は、次のことはできません。または:

[ "$?" -eq 0 ] && echo "OK" || (echo "NOK" >&2 ; exit 1)

私のユースケースには、に基づく複雑なスクリプトがあるので、"$?" == 0メッセージが間違っている場合(メッセージをエコーすることに加えて)、中断する方法を探しています。

答え1

このペアは( )サブシェルを生成し、内部シャットダウンコマンドを使用してスクリプト全体をシャットダウンする目標を破棄します。

自動区切り記号の代わりにコマンドに似ているので、次のよう( )に置き換えます。末尾のスペースと内部の最後のコマンドは、いくつかの終端文字で終わらなければなりません。これにより、同じシェルチェーンでコマンドが実行されるため、シャットダウンされ、このシェルに影響します。{ }{ }{;

[ "$?" -eq 0 ] && echo "OK" || { echo "NOK" >&2; exit 1;}

アップデート:@D.BenKnobleはecho失敗し、前のif ...; then ... else ... fi設定のように動作しないことを述べました。したがって、最初のecho終了コードはnoopコマンドを使用して「エスケープ」する必要があります:(組み込みコマンドは失敗しません)。

[ "$?" -eq 0 ] && { echo "OK"; :;} || { echo "NOK" >&2; exit 1;}

引用:

POSIX:

グループ化コマンド

グループ化コマンドの形式は次のとおりです。

(compound-list)
     Execute compound-list in a subshell environment; see Shell
     Execution Environment. Variable assignments and built-in commands 
     that affect the environment shall not remain in effect
     after the list finishes.

[...]

{ compound-list;}
     Execute compound-list in the current process environment. The
     semicolon shown here is an example of a control operator delimiting
     the } reserved word. Other delimiters are possible, as shown
     in Shell Grammar; a <newline> is frequently used.

ダッシュマンページバッシュマンページ、...

答え2

1つの方法は、次のスクリプト行を使用することです。

[ "$?" -eq 0 ] && echo "OK" || exit $(echo "NOK" >&2 ; echo 1)

その目的は、エラーを報告し、エラーコードを返すと同時に「確認」パスを選択した場合はサイレントを維持することです。

答え3

問題は、サブシェルで別のブランチを実行していることです(角かっこ内の内容です。たとえば、bash(1)マニュアルページで参照してくださいcompound commands)。したがって、exitスクリプトを実行したシェルではなくサブシェルを終了します。よりグラフィカルに表示するには、sleep2つのバージョンのコードを十分に長くして実行するかps fauxcoreutilsバージョンの場合ps)、同様の項目を実行してpstreeプロセスの親関係を確認してください。

今、「修正」する方法は次のとおりです。

  1. 大丈夫ですif ... then / else / fi。特に長いブロックでは、コードを読みやすくします。

  2. パッドが必要な場合は、

    [ "$?" -eq 0 ] && echo "OK" || echo "NOK" >&2 && exit 1
    

    これは正常に終了するか、グループコマンドを使用することに依存します。

    [ "$?" -eq 0 ] && echo "OK" || { echo "NOK" >&2 ; exit 1; }
    

    シェルの一般的な使いやすさと特殊性を確認してください。たとえば、改行やセミコロンで終わらなければなりません。

  3. 最も包括的な - シグナル/イベントハンドラの使用(bashたとえば、他のシェルは異なる構文を持つことができます):

    #!/bin/bash
    
    exit_handler () {
        echo "error happened, exiting"
        ... fix things, that may be half baked ...
    }
    
    trap exit_handler EXIT
    
    ... do stuff ...
    

    これにより、次の機会を得ることができます。

    • 使用set -eset -o errexit)これは通常危険と見なされます。EXITハンドラは、残したくない一時ファイルを削除するなどの操作を実行できます。
    • クリーンアップコードを1つの場所にのみ配置してください。
    • killまた、他の信号(例:

関連情報