GNU/Linux >> Linux の 問題 >  >> Linux

Bashでは、ソケットを非同期で開いて後で使用できますか?

Bashがこれほど多くの高度な機能をサポートしていることを私は知りませんでした!私は、見つけたこれらのもののいくつかを試して使用するために、単純なネットワークプログラムに取り組み始めました。私の特定のプログラムは、完全にBashで記述された基本的なredisクライアントです。現在、私は次のようなことをすることができます:

redis_command -c "ping" redis{001..100}:{6379..6400}

すべてのインスタンス(約2100)に「ping」コマンドを送信し、結果を返します。現在、「ping」コマンドをシリアルに送信していますが、最初のソケット作成をすべて並行して実行することで、プログラムを高速化できると思いました。最適化の有無にかかわらずプログラムをテストしたところ、最適化によって実際に速度が低下することがわかりました。最適化の外観は次のとおりです。

declare -A SOCKETS
function get_socket {
  # args: <hostname> <port>
  # returns: the socket number, or failure return code

  # verify args
  if [[ -z "${1}" ]]; then
    return 1
  fi
  if [[ -z "${2}" ]]; then
    return 1
  fi

  local HOSTPORT="${1}:${2}"
  if [[ -z ${SOCKETS[${HOSTPORT}]} ]]; then
    exec {fd}<>/dev/tcp/${1}/${2}
    SOCKETS[${HOSTPORT}]=${fd}
    RES=${fd}
  else
    RES="${SOCKETS[${HOSTPORT}]}"
  fi
}

if [[ ${PRECONNECT} -eq 1 ]]; then
  echo -n "Pre-connecting to ${#HOSTS[@]} instances... " >&2
  for HOST in ${HOSTS[@]}; do
    get_socket "${HOST%%:*}" "${HOST##*:}" &
    PIDS+=($!)
  done

  # make sure all of our async connections finished before starting
  # TODO, check for errors
  for PID in ${PIDS[@]}; do
    wait ${PID}
  done
  echo "done" >&2
fi

通常、get_socket()関数自体はうまく機能します。特定のサーバーにコマンドを送信する必要がある場合は、事前にget_socket()を呼び出し、実際にコマンドを送信して応答を解析する別の関数にFDを渡します。接続前のシナリオでは、バックグラウンドで&を介してget_socketを呼び出しています。 get_socket()&は別のプロセスで実行されるため、作成されたFDは呼び出しプロセスで使用/アクセスできないため、最適化は役に立ちません。

ソケットをbashで送信する方法、または別のプロセスを使用せずに接続を並列化できる他の方法はありますか?

承認された回答:

/dev/tcp/x/yではありません 直接ですが、パイプを使用して、バックグラウンドで開始されたプロセスと通信し、TCPソケットを接続してデータを転送することもできます。

のようなもの

coproc hostA {
  exec {fd}<> /dev/tcp/127.0.0.1/80
  cat <&$fd & cat >&$fd
}

# same for hostB...

echo -e 'HEAD / HTTP/1.0rnr' >&${hostA[1]}
cat <&${hostA[0]}

最終的に2つのcatを実行することになります とにかくコマンド、あなたは/dev/tcpなしでやったほうがいいかもしれません (常に有効になっているわけではありません)そして、例えばsocatを使用します:

coproc hostA { socat - tcp:localhost:80; }

または、名前付きパイプを使用してbashへの依存を削除することもできます:

mkfifo hostA.in hostA.out
socat - tcp:localhost:80 < hostA.in > hostA.out &

Linux
  1. Linux – / dev / ptsファイルに保存されており、それらを開くことはできますか?

  2. bash から変数をエクスポートして Python で使用する

  3. ユーザー空間の cpufreq ガバナーを使用できず、CPU 周波数を設定できません

  1. Linuxコマンドを保存してオンデマンドで使用する方法

  2. Linuxシャットダウンコマンドの使用方法、計画された即時の再起動

  3. grep を使用してファイル内のコンテンツを検索し、一致する場合は移動します

  1. xargs でエイリアス化されたコマンドを使用するにはどうすればよいですか?

  2. ファイルを検索して 1 つの zip ファイルに圧縮する方法

  3. Bash で eval を避ける必要があるのはなぜですか? 代わりに何を使用する必要がありますか?