GNU/Linux >> Tutoriels Linux >  >> Linux

Fin de transmission de la redirection Bash Tcp ?

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

En relation:convertir une table en fichier ini à l'aide de tableaux bash?
Linux
  1. Est-il possible que l'achèvement de Bash parcoure les alternatives ?

  2. Correction du script Bash attendant une entrée de chemin avec / à la fin se cassant lorsque le chemin ne se termine pas par /?

  3. Script bash pour supprimer tous les fichiers sauf N lorsqu'ils sont triés par ordre alphabétique

  4. Comment puis-je tuer le port TCP 16969 dans Bash ?

  5. Comment enregistrer + fermer le fichier lors de l'édition en bash ?

Utilisez ce script Bash utile pour observer les étoiles

Bash Shebang

La redirection bash expliquée avec des exemples

Ré-exécutez continuellement une commande lorsqu'elle se termine dans Bash

Quand utiliser Bash et quand utiliser Perl/Python/Ruby ?

Comportement étrange de l'historique bash lors de l'exécution de plusieurs sessions