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

Bash TCP-Umleitung Ende der Übertragung?

Ich habe mit xinetd einen einfachen Netzwerkdienst erstellt, der eine Zeichenfolge vom TCP-Socket liest und seine codierte Ansicht ausgibt. Ursprüngliche Binärdatei (qrencode) liest nur stdin.

Es funktioniert gut, wenn ich es mit netcat verwende als echo string | nc <ip> <port>

Aber es antwortet nicht, wenn ich versuche, es über die Bash-TCP-Umleitung zu verwenden.

exec 7<>/dev/tcp/<ip>/<port>
echo string >&7
cat <&7

Es wartet ewig. Ich habe versucht, \004, cat /dev/null an dieses fd zu senden, aber ohne Erfolg.
Wie kann ich es zum Laufen bringen?

Akzeptierte Antwort:

Dieser inetd Dienst oder Ihrer wartet wahrscheinlich auf EOF, bevor er beendet wird (und dann die Verbindung schließt).

Dazu müsste der Client die Sendeseite des Sockets herunterfahren, während die Empfangsseite weiterhin geöffnet bleibt. Das ist nc tut, wenn es EOF auf seiner stdin erkennt.

Der /dev/tcp/host/port virtuelle Schnittstelle von bash (kopiert von ksh) lässt das nicht zu. Sogar zsh ’s ztcp Die flexiblere Alternative kann Verbindungen nicht asymmetrisch beenden.

Sie könnten sich stattdessen auf ein Timeout verlassen, aber das wäre unzuverlässig. Verlassen Sie sich also am besten weiterhin auf dedizierte Dienstprogramme wie nc oder socat (möglicherweise mit einem Coproc, um eine ähnliche Schnittstelle zu haben), oder verwenden Sie eine Programmiersprache mit einer geeigneten Netzwerk-API (mit einer Schnittstelle zu shutdown()). ).

Das Zeichen 0x04 (^D ) bedeutet nur EOF für Endgeräte, wenn die Leitungsdisziplin in icanon steht Modus (implementiert einen groben Zeileneditor). Damit das funktioniert, müssten Sie also ein Pseudo-Terminal zwischen den von xinetd erstellten Socket einfügen und Ihren Dienst. Zum Beispiel, indem Sie es mit:

beginnen
socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3

statt

your-service

Dann müssten Sie Folgendes senden:

printf 'text\n\4' >&7

Oder:

printf 'text\4\4' >&7

damit your-service das Ende der Eingabe sehen kann.

Aufgrund dieses Zeileneditors your-service sieht nur Eingaben, wenn Sie Zeilenumbruch oder ^D senden Zeichen (wir haben alle anderen Bearbeitungszeichen wie werase deaktiviert , erase , kill oben und das ^C , ^Z … die Handhabung ist auch als Teil von raw deaktiviert ).

Sie können also genauso gut einen Eingabe-Präprozessor einfügen, der bei diesem 0x4-Zeichen beendet wird, wie:

awk -v RS='\4' -v ORS= '{print; exit}' | your-service

(Beachten Sie, dass awk kann nicht mawk sein als mawk besteht darauf, seine Eingabe nicht zu verarbeiten, solange es keinen vollen Puffer oder eof erhält).

Verwandte:Tabelle mithilfe von Bash-Arrays in eine INI-Datei konvertieren?
Linux
  1. Warum wird die Bash-Eingabeaufforderung fehlerhaft, wenn ich den Verlauf durchsuche?

  2. Ist es möglich, dass die Bash-Vervollständigung die Alternativen durchläuft?

  3. Einschließen Vs. Den Wert einer Variablen nicht in Anführungszeichen in Bash setzen?

  4. The Point Of The Bash Null-Operator „:“, Doppelpunkt?

  5. Bash-Skript zum Löschen aller bis auf N Dateien bei alphabetischer Sortierung

Verwenden Sie dieses hilfreiche Bash-Skript, wenn Sie Sterne beobachten

Bash Shebang

Bash-Umleitung mit Beispielen erklärt

Behoben:Bash-Skript, das eine Pfadeingabe mit / am Ende erwartet, bricht ab, wenn der Pfad nicht mit /? endet

Wie speichere und schließe ich die Datei beim Bearbeiten in Bash?

Seltsames Verhalten des Bash-Verlaufs beim Ausführen mehrerer Sitzungen