В bash я могу асинхронно открывать сокеты и использовать их позже?

Я понятия не имел, что Bash поддерживает множество дополнительных функций! Я начал работать над простой сетевой программой, чтобы попытаться использовать некоторые из этих вещей, которые я нашел. Моя конкретная программа является базовым клиентом redis, полностью написанным в Bash. В настоящее время я могу сделать что-то вроде следующего:

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

Он отправит команду «ping» ко всем экземплярам (около 2100) и вернет результаты. Я в настоящее время посылаю команду «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 другой функции, которая фактически отправляет команду и анализирует ответ. В сценарии pre-connect я вызываю 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.0\r\n\r' >&${hostA[1]} cat <&${hostA[0]} 

Так как вы в конечном итоге запускаете две команды cat , вы также можете обойтись без /dev/tcp (что не всегда включено) и использовать, например, socat:

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

Или вы можете удалить зависимость от bash, используя именованные каналы:

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