J'ai un programme P
qui s'attend à recevoir "Bonjour" et à afficher "Pourquoi?" avant de fournir une fonctionnalité. Cette fonctionnalité est utilisée par d'autres programmes qui ne savent pas qu'il est courant de commencer une conversation avec "Bonjour". Je veux donc écrire un wrapper pour P
ça fonctionne comme ça (syntaxe zsh):
coproc P
print -p Hello # Send Hello to P
read -pr line # Read what P has to say
[[ "$line" = "Why?" ]] && Replace current process with the coprocess.
echo Could not get P's attention.
L'utilisation de cat
ou dd
dans la Replace...
pièce (quelque chose comme cat <&p &; exec cat >&p
) entraîne une mise en mémoire tampon inutile. Quelles sont mes options?
zsh
solution ou unebash
solution est-elle acceptable?bash
solution qui n'est pas applicable danszsh
, mais qui l'accepterait certainement ☺ssh
et son optionProxyCommand
.cat
ne tamponne généralement pas. Si c'est le cas sur votre système, essayezcat -u
.Réponses:
Le problème que vous avez indiqué ne concerne pas vraiment le remplacement d'un processus , mais le remplacement des flux d' un processus existant . Le but est d'interagir un peu avec le processus puis de transmettre son entrée / sortie à une autre paire de flux connectés.
Il n'y a aucun moyen de le faire directement (au moins, dans le shell; à l'intérieur du processus, un
dup2
appel pourrait éventuellement fonctionner). Vous devrez épisser les flux. C'est à dire:Utiliser
coproc
comme dans votre exemple est également OK. Notez que la commande enregistre les descripteurs de fichiers dans un tableau et que vous pouvez les utiliser ultérieurement pour les redirections.Cela ne devrait pas provoquer de mise en mémoire tampon supplémentaire (au moins avec GNU cat), sauf si P inspecte les flux d'entrée / sortie auxquels il est connecté et prend une décision de mise en mémoire tampon en fonction de cela. Par exemple, la bibliothèque standard C active la mise en mémoire tampon sur
stdout
/stderr
s'ils sont connectés à un fichier, mais n'effectue la mise en mémoire tampon de ligne que s'ils sont connectés à un terminal.la source
Capable de tester avec le code ci-dessous en utilisant perl pour éviter la mise en mémoire tampon, essayez si cela fonctionne pour vous
la source
dd ibs=1
, par exemple. Je ne suis pas d'accord avec ça. D'une certaine manière, le coproc a sa propre mise en mémoire tampon, et c'est celui-ci que je veux utiliser.