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:
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).