Bashスクリプトから「接続拒否」エラーを削除する

Bashスクリプトから「接続拒否」エラーを削除する

私は次の行を持っています:

exec 3<>/dev/tcp/127.0.0.1/9091 > /dev/null 2>&1 ||  { PORT_IS_FREE="yes"; };

ポート9091が利用可能であることを確認しています。接続を確立できない場合は、次のエラーが表示されます。

my-script: connect: Connection refused
my-script: line 6: /dev/tcp/127.0.0.1/9091: Connection refused

もちろん、このエラーは悪いニュースではなく、ポートが無料であることを意味します。エラー追跡が記録されるのを防ぐ方法は?私はstdout / stderrを/ dev / nullに送ろうとしましたが、うまくいかないようです。

ボーナス:

私はset -eスクリプトの一番上にあります。接続が拒否されると、すべてが停止します。上記のような特定の行でエラーが発生した場合、どのように停止を防ぐことができますか?

だから私は2つの目標を持っています。

  1. これは予想されるエラーメッセージであるため、ライブラリユーザーが表示する必要はありません。

  2. 予想されるエラーは無視して、可能であればset -eを使用したいと思います。

答え1

続行しますset -eが、既知のエラーを許可するには、次の注文を使用してください。

/bin/false || :

これは||演算子を使用して、エラーがset -eアクティブ環境に致命的ではないと見なされるようにエラーを「消費」します。

すでに標準エラーを抑制するために使用しています2>/dev/null。ここで引用した行でエラーが発生することは確実ですか?また、exec以下を使用しないで、より読みやすい代替手段を使用することをお勧めします。

if ! nc -z localhost 9091 1> /dev/null 2>&1; then
    port_free="yes"
fi

リターンコードはドアで確認するncので、ifその後も安全ですset -e

答え2

エラーと出力ストリームを/ dev / nullに正しくリダイレ​​クトしてエラーメッセージを抑制するには、execコマンド全体をグループ化する必要があります。

{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 || PORT_IS_FREE="yes"

execシェルが組み込まれているため、どのように動作するかを予測することは困難ですが、特に処理できるとしても、全体の操作はまだいくつかの段階で発生し、ストリームの最後の1つだけが発生すると仮定し<ます>。リダイレクトされます。方法について詳しく知っている人ですexec

編集:別のコマンドなので、変数を割り当てるために角かっこをグループ化する必要がある理由はわかりませんが、私が使用したデフォルトの割り当ての代わりに必要な場合は、私の例では角かっこを使用できます。

;エラーを無視する場合は、次のように終了ステータスを使用するのではなく、リダイレクトしてコマンドを終了できます||

{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 ; PORT_IS_FREE="yes"

もちろん、この場合の問題は、他のエラーも捕まえられないという点だ。試してみましたが、そのエラーが発生した後、終了ステータスは1でした。別のエラーから別のコードが返された場合は、1をテストできます(1は非常に一般的なエラーコードであるため、実際には疑わしいです)。編集:この解決策は、次の使用exec時にコード1を返した後に終了しないという利点もありますset -e

{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 || [ "$?" = 1 ] && PORT_IS_FREE="yes"

それ以外の場合は、grepエラーメッセージを一致させることができますが、これはより安定していると思います。

socketOpenOutput="$({ exec 3<>/dev/tcp/127.0.0.1/9091; } 2>&1`)"
socketOpenErrorCode="$?"
if [ "$socketOpenErrorCode" != 0 ]; then
    if ! echo "$socketOpenOutput" | grep 'connect\s*:\s*Connection refused' >/dev/null; then
        echo "An unexpected error happened when opening the socket!"
        exit 1
    fi
fi

PORT_IS_FREE="yes"

しかし、これはset -e

関連情報