Separando o terminal stdin e stdout

2

Existe alguma maneira de exibir o alimentador 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 ncursesprograma capaz de fazer isso?

Navegantes
fonte

Respostas:

0

Este é um recurso disponível para implementações comuns de terminais Linux?

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

Se não, existe um programa ncurses capaz de fazer isso?

Se for, nunca ouvi falar disso. Você precisaria que ele fosse executado como um processo paralelo ao script / aplicativo principal, significando 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 dividi-lo em dois terminais. No primeiro terminal, você executa o script e aceita stdin, mas stdout e stderr são redirecionados para um canal 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 cat ./myoutputenquanto stdin ainda é aceito no terminal original.

Marek Rost
fonte
0

Isso pode ser feito, embora exija que seu programa lide com várias coisas. Em particular, o programa precisará saber tudo o que o usuário digitou, o que significa que o programa precisará colocar o terminal no modo raw (desligar ICANON, ver a termiospágina de manual ) e lidar com as teclas individuais quando elas entram. o programa precisa imprimir algo periodicamente, ele pode usar uma impressão de retorno de carro (ou uma seqüência de escape adequada para mover o cursor para onde ele precisa ir, embora geralmente sejam abstraídos por ncurses) para apagar o que o usuário digitou; assumindo que o usuário digitou, whatmas não retornou, o programa executaria o equivalente da sleepsobrescrita subsequente 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, sttypode ser usado para definir o modo raw, e alguns shells são adequados readpara leitura de caracteres por caractere (ah, então você também pode precisar controlar o controle + c e outros caracteres especiais)

thrig
fonte