J'ai créé un service réseau simple avec xinetd qui lit une chaîne à partir du socket tcp et affiche sa vue codée. Binaire original (qrencode) juste en train de lire stdin.
Cela fonctionne bien quand je l'utilise avec netcat
comme echo string | nc <ip> <port>
Mais il ne répond pas lorsque j'essaie de l'utiliser via la redirection tcp bash.
exec 7<>/dev/tcp/<ip>/<port>
echo string >&7
cat <&7
Il attend pour toujours. J'ai essayé de faire écho à \004, cat /dev/null à ce fd et pas de chance.
Comment puis-je le faire fonctionner ?
Réponse acceptée :
Ce inetd
service ou le vôtre attend probablement EOF avant de quitter (puis de fermer la connexion).
Pour ce faire, vous auriez besoin que le client ferme le côté envoi du socket tout en gardant le côté réception ouvert. C'est ce que nc
fait quand il détecte EOF sur son stdin.
Le /dev/tcp/host/port
interface virtuelle de bash
(copié de ksh) ne le permet pas. Même zsh
ztcp
une alternative plus flexible n'a pas la capacité d'arrêter les connexions de manière asymétrique.
Vous pourriez vous fier à un délai d'attente à la place, mais ce ne serait pas fiable. Il vaut donc mieux continuer à s'appuyer sur des utilitaires dédiés comme nc
ou socat
(éventuellement avec un coproc pour avoir une interface similaire), ou utiliser un langage de programmation avec une API réseau appropriée (avec une interface vers shutdown()
).
Le caractère 0x04 (^D
) signifie uniquement EOF pour les terminaux lorsque la discipline de ligne est dans icanon
mode (implémente un éditeur de ligne brute). Donc, pour que cela fonctionne, vous devez insérer un pseudo-terminal entre le socket créé par xinetd
et votre service. Par exemple, en le commençant par :
socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3
au lieu de
your-service
Ensuite, vous devrez envoyer :
printf 'text\n\4' >&7
Ou :
printf 'text\4\4' >&7
pour votre-service pour voir la fin de la saisie.
À cause de cet éditeur de ligne, your-service
ne verra l'entrée que lorsque vous envoyez une nouvelle ligne ou ^D
caractères (nous avons désactivé tous les autres caractères d'édition comme werase
, erase
, kill
ci-dessus et le ^C
, ^Z
… la gestion est également désactivée dans le cadre de raw
).
Donc, vous pourriez aussi bien insérer un préprocesseur d'entrée à la place qui se ferme sur ce caractère 0x4 comme :
awk -v RS='\4' -v ORS= '{print; exit}' | your-service
(notez que awk
ne peut pas être mawk
comme mawk
insiste pour ne pas traiter son entrée tant qu'il n'a pas reçu un tampon complet ou eof).