É possível alimentar a entrada para vários processos. Quando vários processos estão lendo do mesmo canal ou terminal, cada byte vai para um dos processos, o que quer que aconteça ler primeiro esse byte em particular. Quando apenas um processo está lendo ativamente, ele recebe a entrada. Quando vários processos estão lendo ativamente ao mesmo tempo, qual recebe a entrada é imprevisível.
Você está entrando em conflito com o armazenamento em buffer . A maioria dos programas, evidentemente incluindo A, lê um buffer inteiro de cada vez - normalmente algumas centenas de bytes ou alguns kilobytes - e os armazena em sua própria memória até processá-los. Isso é muito mais rápido do que ler um byte de cada vez. Mas neste cenário, isso significa que A lê mais do que a parte que irá processar antes de chamar B, então a entrada significada para B já é consumida por A quando B começa.
Se você pode fazer B ler de uma fonte diferente, é claro que é uma solução.
Se você tiver controle sobre como A é executado, tente stdbuf
de GNU coreutils . Ele conecta-se às chamadas da biblioteca para fazer com que o processo leia um byte de cada vez. Isso funciona com a maioria dos programas, mas não todos: ele não funciona com executáveis vinculados estaticamente e não funciona se o programa usa um método de buffer diferente da biblioteca padrão (stdio).
… | stdbuf -i 1 A
Como alternativa, tente ler em um arquivo comum. Quando A leu a entrada de um cano ou terminal, não pode colocá-lo de volta. Mas quando é lido a partir de um arquivo normal, ele pode retroceder a posição de leitura antes de chamar B. É assim que o read
shell embutido se comporta, por exemplo. Não há garantia de que o programa em particular A o faça, na verdade, não é um comportamento muito comum, mas se isso acontecer, é uma solução simples.
Se isso não funcionar, ou se você não tiver controle sobre como A é executado, será necessário organizar o tempo da entrada para que a parte destinada para B não esteja presente até que B seja iniciado. Como fazer isso depende de como você pode detectar que o B foi iniciado. Uma solução possível, mas frágil, é colocar um atraso:
{ echo 123; sleep 1; echo xyzzy; } | A
Isso só funciona se A chamar B dentro de 1 segundo, o que é frágil. Uma solução mais confiável é detectar a saída produzida por A (ou B). Esse é o tipo de problema que espera foi projetado para resolver. Por exemplo, se B exibir algum tipo de prompt como B>
:
#!/usr/bin/expect -f
spawn A
send "123\r"
expect "B>"
send "xyzzy\r"