
私は次の行を持っています:
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つの目標を持っています。
これは予想されるエラーメッセージであるため、ライブラリユーザーが表示する必要はありません。
予想されるエラーは無視して、可能であれば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
。