Substitui o processo atual pelo seu co-processador / filho

10

Eu tenho um programa P que espera receber "Olá" e exibir "Por quê?" antes de fornecer um recurso. Esse recurso é usado por outros programas que não estão cientes de que é uma cortesia comum iniciar uma conversa com "Olá". Eu, portanto, quero escrever um wrapper para P que funciona assim (sintaxe 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.

Usar cat ou dd na parte Replace... (algo como cat <&p &; exec cat >&p ) resulta em buffer desnecessário. Quais são minhas opções?

    
por Michaël 13.11.2015 / 07:52

2 respostas

0

Capaz de testar com código abaixo usando perl para evitar o buffer, tente se isso funciona para você

Sample version of P

$ cat /tmp/P
#!/bin/bash
read input
if [[ $input = "Hello" ]]
then
    echo "Why?"
else
    exit 1
fi
echo "Got Hello from client, working ..."
sleep 10
echo "Need to read some input"
read x
echo "Got: $x"

The wrapper program

$ cat /tmp/wrapper 
#!/usr/bin/zsh
coproc /tmp/P
print -p Hello  # Send Hello to P
read -pr line   # Read what P has to say
if [[ "$line" = "Why?" ]]; then
    perl -e '$|=1;print $_ while(<>);' <& p &
    perl -e '$|=1;print $_ while(<>);' >& p
else
    echo "Could not get P's attention."
fi

Test run

$ /tmp/wrapper 
Got Hello from client, working ...
Need to read some input
hi there P!   <== Typed in at teminal
Got: hi there P!
    
por 17.11.2015 / 20:49
0

O problema que você declarou não é realmente substituir um processo , mas substituir os fluxos de um processo existente. O objetivo é interagir um pouco com o processo e então entregar sua entrada / saída para outro par de fluxos conectados.

Não há como fazer isso diretamente (pelo menos, no shell; dentro do processo, uma chamada dup2 pode funcionar). Você precisará unir os fluxos. Ou seja:

( echo Hello ; cat ) | P | ( read ; cat )

Usar coproc como em seu exemplo também é OK. Observe que o comando salva os descritores de arquivo em uma matriz e você pode usá-los posteriormente para redirecionamentos.

Isto não deve causar buffer adicional (pelo menos com GNU cat), a menos que P inspecione os fluxos de entrada / saída aos quais está conectado e tome uma decisão de buffer baseado nisso. Por exemplo, a biblioteca padrão C ativará o armazenamento em buffer em stdout / stderr se eles estiverem conectados a um arquivo, mas somente executarão o buffer de linha se estiverem conectados a um terminal.

    
por 22.07.2018 / 05:48