私はこの行を持っています:
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を使用します。
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
の後でも安全です。
エラーストリームと出力ストリームの両方を/ dev/nullに適切にリダイレクトし、それによってエラーメッセージを抑制するには、execコマンド全体をグループ化する必要があります。
{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 || PORT_IS_FREE="yes"
exec
はShellに組み込まれているため、どのように動作するかを予測するのは難しいですが、<
と>
を特別に処理できたとしても、操作全体が実行されると思います。いくつかのステップで、最後のストリームのみがリダイレクトされます。 exec
の働きについてもっと知っている人は、これにいくらかの光を当てることができるかもしれません。
編集:変数の割り当てに中括弧のグループ化が必要な理由は1つのコマンドなのでわかりませんが、必要に応じて、使用した裸の割り当ての代わりに、中括弧を例と組み合わせて使用できます。
エラーを無視する場合は、;
を介して終了ステータスを使用する代わりに、||
を使用してリダイレクト後にコマンドを終了できます。
{ 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
ではうまく機能しません。