Separando o terminal stdin e stdout

2

Existe alguma maneira de exibir o feed de linha de entrada padrão do shell separadamente do fluxo de saída padrão? Esta parece ser uma questão muito básica, mas eu não notei muitas pessoas perguntando sobre isso por algum motivo.

Em particular, estou tentando evitar que minha entrada seja dividida por impressões de saída padrão (e erro padrão). Por exemplo, estou tentando evitar o seguinte cenário:

$while true; do echo "Hello there. Sorry to barge in; were you busy?"; sleep 1.5; done
Hello there. Sorry to barge in; were you busy?
whaHello there. Sorry to barge in; were you busy?
t Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
stopHello there. Sorry to barge in; were you busy?
 Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
whyHello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?

Em vez disso, quero algo parecido com isto:

$while true; do echo "Hello there. Sorry to barge in; were you busy?"; sleep 1.5; done
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
>>what
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
>>stop
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
>>why
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
>>unsent linefeed content appears fixed over here

Este é um recurso disponível para implementações comuns de terminais Linux? Se não, existe um programa ncurses capaz de fazer isso?

    
por Navneeth 02.12.2017 / 14:16

2 respostas

0

Is this a feature available for common Linux terminal implementations?

Eu não acho que haja uma solução geral disponível. Não é muito comum os scripts normais exibirem a saída e aceitarem a entrada ao mesmo tempo - isso é essencialmente o comportamento do aplicativo multiencadeado, e as pessoas geralmente compilam bibliotecas de saída gráficas como ncurses nelas ...

If not, is there an ncurses program capable of doing this?

Se for, nunca ouvi falar disso. Você precisaria que ele fosse executado como um processo paralelo ao script / aplicativo principal, o que significa que você teria que usar o forking, não poderia canalizar a entrada nele ... seria complicado.

Eu acho que você tem apenas duas opções - ou escreva isso ncurses wrapper ou divida-o em dois terminais. No primeiro terminal, você executa o script e aceita stdin, mas stdout e stderr são redirecionados para um pipe nomeado.

$ mkfifo myoutput
$ function blah() { 
>   while true; do 
>     echo "Hello there. Sorry to barge in; were you busy?"; sleep 1.5; 
>   done
> }
$ blah 2>&1 >./myoutput

Agora você pode ler a saída em outro terminal com cat ./myoutput enquanto stdin ainda é aceito no terminal original.

    
por 02.12.2017 / 15:36
0

Isso pode ser feito, embora exija que seu programa lide com várias coisas. Em particular, o programa precisará saber tudo que o usuário digitou, o que significa que o programa precisará colocar o terminal no modo raw (desativar ICANON , veja a página de manual termios ) e lide com pressionamentos de teclas individuais à medida que aparecem. Então, quando o programa precisa imprimir algo periodicamente, ele pode usar uma impressão de retorno de carro (ou < um href="http://invisible-island.net/xterm/ctlseqs/ctlseqs.html"> uma seqüência de escape adequada para mover o cursor para onde ele precisa ir, embora geralmente sejam abstraídos por ncurses ) para eliminar o que o usuário digitou; supondo que o usuário tenha digitado what mas não retornado, o programa executaria o equivalente a sleep e subseqüente sobrescrita echo -e :

 echo -n what; sleep 1; echo -e "\rHello there..."

E, em seguida, seu programa precisará reexibir o que o usuário digitou, mas foi substituído pelo acima; daí a necessidade de operar o terminal no modo raw e armazenar essa informação. Em um programa shell, stty poderia ser usado para definir o modo raw, e então alguns shells têm read adequado para leitura de caractere por caractere (oh e então você também pode precisar controlar o controle + c e outros caracteres especiais ...)

    
por 02.12.2017 / 17:13