GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Kann ich in Bash Sockets asynchron öffnen und später verwenden?

Ich hatte keine Ahnung, dass Bash so viele erweiterte Funktionen unterstützt! Ich fing an, an einem einfachen Netzwerkprogramm zu arbeiten, um zu versuchen, einige dieser Dinge, die ich fand, zu verwenden. Mein spezielles Programm ist ein grundlegender Redis-Client, der vollständig in Bash geschrieben ist. Derzeit kann ich so etwas tun:

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

Es sendet den „Ping“-Befehl an alle Instanzen (etwa 2100) und gibt die Ergebnisse zurück. Ich sende derzeit den Befehl „ping“ seriell, aber ich dachte, ich könnte mein Programm beschleunigen, indem ich die gesamte anfängliche Socket-Erstellung parallel durchführe. Ich habe mein Programm mit/ohne Optimierung getestet und festgestellt, dass meine Optimierung die Dinge tatsächlich verlangsamt hat. So sieht die Optimierung aus:

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

Normalerweise funktioniert die Funktion get_socket() alleine hervorragend. Wenn ich jemals einen Befehl an einen bestimmten Server senden muss, rufe ich get_socket() im Voraus auf und übergebe das FD an eine andere Funktion, die den Befehl tatsächlich sendet und die Antwort analysiert. Im Pre-Connect-Szenario rufe ich get_socket im Hintergrund über &auf. Da get_socket()&in einem separaten Prozess ausgeführt wird, ist der erstellte FD im aufrufenden Prozess nicht verfügbar/zugreifbar, daher ist meine Optimierung nutzlos.

Gibt es eine Möglichkeit, Sockets in Bash zu senden, oder eine andere Möglichkeit, meine Verbindungen zu parallelisieren, ohne einen separaten Prozess zu verwenden?

Akzeptierte Antwort:

Nicht mit /dev/tcp/x/y direkt, aber Sie könnten Pipes verwenden, um mit Prozessen zu kommunizieren, die im Hintergrund gestartet werden, um die TCP-Sockets zu verbinden und Daten zu übertragen.

So etwas wie

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]}

Am Ende laufen zwei cat trotzdem auf /dev/tcp verzichten (was nicht immer aktiviert ist) und verwenden Sie zum Beispiel socat:

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

Oder Sie könnten die Abhängigkeit von Bash entfernen, indem Sie Named Pipes verwenden:

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

Linux
  1. So speichern Sie Linux-Befehle und verwenden sie bei Bedarf

  2. Verwendung des Befehls zum Herunterfahren von Linux, Neustarts geplant und sofort

  3. Wie kann ich nach Dateien suchen und sie in einer Zip-Datei komprimieren?

  4. Wie kann ich Platzhalter im ms-dos-Stil mit ls und mv verwenden?

  5. Kann den Userspace-Cpufreq-Governor nicht verwenden und die CPU-Frequenz einstellen

Dateipfade verstehen und wie man sie unter Linux verwendet

So erstellen Sie Ansible-Rollen und verwenden sie im Playbook

So verwenden Sie bash if -z und if -n zum Testen von Zeichenfolgen in Linux

Kann ich mit Calibre Hörbücher bestellen und anhören?

Farbschemata in Vim:Wie man sie ändert und verwendet

Bash-Scripting Teil 6 – Erstellen und Verwenden von Bash-Funktionen