Eu estou olhando para a saída strace de um processo bash em execução conectado a um terminal, para fins educacionais.
Meu processo de bash tem 2883 PID.
Eu digito
[OP@localhost ~]$ strace -e trace=openat,read,write,fork,vfork,clone,execve -p 2883 2> bash.strace
Em um terminal. Entro no meu processo do bash e tenho a seguinte interação:
[OP@localhost ~]$ ls
Olhando para a saída, vejo
strace: Process 2883 attached
read(0, "l", 1) = 1
write(2, "l", 1) = 1
read(0, "s", 1) = 1
write(2, "s", 1) = 1
read(0, "\r", 1) = 1
write(2, "\n", 1) = 1
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fec6b1d8e50) = 3917
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=3917, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
write(1, "\33]0;OP@localhost:~\7", 23) = 23
write(2, "[OP@localhost ~]$ ", 22) = 22
...
Estou confuso nas duas últimas linhas. Parece que o bash está tentando escrever dois prompts de shell? O que está acontecendo aqui?
cat
, há duas diferenças: ele lê a entrada linha por linha e, embora faça eco de sua entrada de volta para stdout, vejo a entrada duas vezes (uma vez quando digito e uma vez quando gato faz eco).^A
(Ctrl-A) ou os vários caracteres especiais forem pressionados. Além disso, desativa o eco do terminal, para que ele possa decidir o que produzir para cada caractere de entrada específico (novamente, o TAB normalmente não gera um TAB.)cat
Não faz nada disso. Se você, tente executardash
, o que não faz nenhum tratamento de linha de comando.read()
apenas para ler um byte de cada vez é que ele não consegue ler além de uma nova linha. A nova linha pode fazer com que execute um programa externo, que também pode ler da mesma entrada. (E esse programa deve ser capaz de ler todos os caracteres após a nova linha.) Se ele não precisa se preocupar com isso, ele poderia chamarread()
com um limite maior, e com o terminal no modo raw, ainda seria normalmente obter a entrada um caractere de cada vez. (Seria até quão rápido os caracteres de entrada chegaria e como o processo foi agendada.)read()
buffer com maior ainda poderia retornar as duas linhas em a mesma ligação. Eu não acho que há uma garantia de queread()
seria sempre retornar apenas uma linha no modo cozidos.