Brincando com pseudoterminais e redirecionamentos

Há uma máxima no mundo dos sistemas similares ao Unix: tudo é arquivo. Dispositivos físicos, processos ou instâncias de programas comunicam-se um com os outros através de arquivos de dispositivo ou arquivos em dispositivos referenciados em nível de execução de software em descritores de arquivos. Neste artigo ver-se-ão alguns exemplos que auxiliarão na compreensão deste princípio conforme implantado em várias distribuições Linux modernas.

[ Hits: 11.683 ]

Por: Anonimo Oculto Culto em 06/08/2018


A máxima nos sistemas Unix-similares: tudo é arquivo. Pseudoterminais e redirecionamentos (entrada)



Nesta última seção do artigo "Brincando com pseudoterminais e redirecionamentos" far-se-á algo intuitivo perto do realizado na seção anterior, onde redirecionaram-se as saídas padrão (stdout e stderr) de uma instância do shell bash atrelada a uma janela do konsole a duas outras janelas; uma destas janelas ficando responsável pela exibição dos dados de saída dos comandos e a outra pela exibição do "prompt" e dos dados de controle e de erro atrelados à execução de programas invocados sem redirecionamentos explícitos ou mesmo oriundos da própria instância do bash. Nesta seção redirecionar-se-á a entrada padrão (stdin) do bash atrelado a uma janela de terminal a outra janela de terminal, de modo que se tenha que lhe dar o foco para a digitação de comandos ao bash.

Inicie abrindo duas janelas do konsole e exibindo seus respectivos arquivos de dispositivo com o comando "tty" e os respectivos PIDs das instâncias do bash com o comando "echo", executando em cada pseudoterminal o seguinte conjunto de comandos:

tty ; echo $BASHPID ; cd /dev/fd ; ls -la

que pode ser digitado em linha única, conforme mostrado.
FIGURA 10: uma implementação prática dos procedimentos para redirecionamento de entrada (stdin) sendo descritos. [Ref.: 37]

Se apenas as duas janelas solicitadas encontram-se abertas, seus respectivos tty serão /dev/pts/1 e /dev/pts/2. Adapte ao caso a numeração própria se distinta desta.

Desta vez iniciar-se-á o procedimento matando-se a instância do shell bash atrelada à janela pts/2. Com o foco em pts/1, execute o comando:

kill -9 {PID do bash na janela /dev/pts/2}

O "9" , número atrelado à sinalização SIGKILL, é necessário para se matar a instância do bash pois em modo interativo o bash não se mata via sinal TERM, o sinal default de "kill" caso não lhe seja informado um. Para uma lista de sinais reconhecidas pelo bash e respectiva numeração associada execute o comando "trap -l". [Ref.: 9 | 26 | 34 | 35]

Uma mensagem em vermelho deve aparecer na tela da janela pts/2 informando que o shell associado está morto (travou).

Com o foco ainda em pts/1, execute o comando:

exec </dev/pts/2

que redirecionar o descritor 0 (stdin) da instância do bash ainda em execução ao pseudoterminal pts/2. [Ref.: 20 | 23]

Doravante, digitando-se qualquer coisa com o foco na janela pts/1, ecoar-se-á o digitado na tela em virtude da função de eco estar por padrão ativa, mas nada será processado, mesmo pressionando-se Enter, pois a instância do bash ainda ativa efetivamente não tomou conhecimento de tal digitação para interpretação (ela está esperando dados de pts/2). Importante perceber contudo que a função de escrever os caracteres digitados na tela não é da instância do bash, mas de uma parte da estrutura de conexão conhecida como driver de terminal, cuja existência de uma instância atrela-se inexoravelmente à existência de uma instância do bash atrelada [Ref.: 8].

Para se processar algum outro comando doravante, deve-se mudar o foco para a janela pts/2, que assumiu a entrada padrão da instância ativa do bash. Comandos digitados nesta janela serão executados, mas suas saídas serão exibidas em pts/1 contudo. Tente, com foco em pts/2, digitar "ls -la" e veja o resultado. Importante perceber que o comando será entrado às segas. Não se verá eco do mesmo, pois junto ao terminal /pts/2 o bash (com o readline) e o driver de terminal (responsável pelo eco) associados estão mortos. Em pts/2 está ativo apenas o driver do console (ou pseudo-tty no caso), ou seja, a parte da estrutura responsável pela janela em si; por nela escrever apenas o recebido, e enviar o através dela inserido via teclado. E não há eco nesse caso.

A estrutura geral envolvendo um pseudo terminal é para fins didáticos esquematizada da seguinte forma (n representando dígitos) [Ref.: 8]:

Programa escravo (bash) <---> Driver de terminal (onde há o eco) <---> (/dev/pts/n) Driver de console ou pseudo-tty <---> Programa mestre (janela)

O driver do console opera da seguinte forma [Ref.: 8]:

Programa escravo <---> Driver de terminal <---> (/dev/pts/n) Driver do console <==> |

|----> Driver de vídeo ---> Vídeo

| <---- Driver de teclado <--- Teclado

Através da estrutura conclui-se que matando-se o programa escravo (bash) bem como o driver de terminal, o bash de outro terminal com redirecionamento ao driver pseudo-tty liberado opera sem recurso para reconhecer e auxiliar o gerenciamento do terminal a qual se conecta. Comandos oriundos do console que seriam interceptados e interpretados pelo driver de terminal (sequências de escape para configuração do terminal) são agora levados diretamente ao bash, que muitas vezes não sabe o que fazer com tais comandos (pois não são comandos do bash); o mesmo valendo no caso do fluxo inverso de dados.

A exemplo. o comando CTRL-L não funcionará imediatamente via redirecionamento de entrada acima descrito, a menos que um "Enter" seja pressionado após a combinação de teclas. "Enter" leva o pseudoterminal com foco para entrada de dados a descarregar o "buffer" de teclado (o CTRL-L) no bash, que reconhece e processa, então, a limpeza de tela (o pseudoterminal opera em modo canônico: [Ref.: 8]).

Por tal, concluindo-se, é importante manter as janelas de entrada e saídas as mais parecidas possível com aquela janela associado à instância do bash em execução e que ainda retém um driver de terminal associado (mesmo que este não atue nos redirecionamentos), evitando-se assim erros de formatação na exibição e na entrada de dados junto às janelas que receberam redirecionamentos. Igualmente devem-se evitar comandos com foco na configuração do terminal no caso de redirecionamento de entrada e saídas.
FIGURA 11: redirecionamento de entrada em sistema onde a existência do pseudoterminal atrela-se inexoravelmente à existência da instância do bash associada. Feito o redirecionamento, para se executar um comando, com foco no terminal alvo (pts/1 na figura), deve-se digitar em dobro todos os caracteres, incluindo-se o(s) espaço(s) entre comando(s) e argumento(s). As instâncias concorrentes do bash recebem, alternadamente, o que se digita; de forma que ambas executarão o mesmo comando após "Enter", também duplo. Não há eco no outro terminal (pts/0) da parte digitada que lhe cabe. [Ref.:38]

Poder-se-ia pensar agora: mas o que ocorre se redirecionarmos a entrada padrão sem contudo se matar o bash (e o driver de terminal) do pseudoterminal alvo? Deixa-se como dever de casa esta situação, mas facilmente percebe-se que haverá duas instâncias do bash concorrendo pelo dado digitado. O que se esperar?

Executar o redirecionamento de entrada (e saídas) sem se matar o bash será a situação exemplo viável em alguns sistemas mais antigos, onde, por experiência, matando-se o bash mata-se também, automaticamente, o pseudoterminal (a janela associada simplesmente fecha após o comando "kill").

Em qualquer sistema contudo, mantendo-se ambas as instâncias ativas e com entradas padrão comuns, haverá concorrência pelo dado digitado, geralmente um caractere indo a uma das instâncias, outro à outra das duas instâncias conectadas ao pseudoterminal, alternadamente (para se conseguir executar um comando com foco na janela com as entradas, cada caractere deverá ser digitado em dobro).
FIGURA 12: redirecionamento dos três descritores principais (stdout, stderr, stdin) em exemplo envolvendo quatro pseudoterminais do konsole, exemplificando todo o arcabouço abordado no artigo. Após identificação do arquivo de dispositivo e do PID da instância associada do bash em cada janela, os demais comandos foram digitados com foco na janela pts/3; até a transferência da entrada padrão ao pseudoterminal pts/4, quando comandos entrados às segas em pts/4 levaram às saídas em pts/1.

Inicialmente, a partir de pts/3, matou-se de uma só vez as instâncias do bash nas outras janelas (linhas vermelhas). Posteriormente executaram-se os redirecionamentos um a um, conforme listagem de /dev/fd/ na janela pts/1. Repare a sequência de escape produzida pela digitação dupla de "seta à esquerda", acidental, durante a digitação do comentário. [Ref.: 39]

Bem, é hora de reconhecer que não se trata de um artigo dos mais rigorosos tecnicamente - e certamente há falhas técnicas nele, pois muito se apoiou em experiência pessoal e não apenas na literatura recomendada - mas espera-se ao menos se ter ajudado a elucidar, "visualmente", o princípio de funcionamento dos redirecionamentos nos sistemas Unix-similares, e o valor prático da sensacional estrutura lógica atrelada.

Comentários e correções certamente são bem-vindos. E entre os Unix similares, "Viva o Linux"...

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. A máxima nos sistemas Unix-similares: tudo é arquivo. Bash e os descritores de arquivos
   3. A máxima nos sistemas Unix-similares: tudo é arquivo. Bash e os arquivos descritores
   4. A máxima nos sistemas Unix-similares: tudo é arquivo. Arquivos descritores e redirecionamentos
   5. A máxima nos sistemas Unix-similares: tudo é arquivo. Pseudoterminais e redirecionamentos (saídas)
   6. A máxima nos sistemas Unix-similares: tudo é arquivo. Pseudoterminais e redirecionamentos (entrada)
   7. A máxima nos sistemas Unix-similares: tudo é arquivo. Referências - Comentários - Créditos às imagens
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Script GitPratico para criar repositórios remotos sem logar no GitHub

Ingressando estações de trabalho Ubuntu no AD com Closed In Directory

Alta disponibilidade de links

flock - Gerenciador de lockfiles

Redundância de link de internet

  
Comentários
[1] Comentário enviado por albfneto em 06/08/2018 - 14:02h

Seu artigo é ótimo, excelente. Bem escrito, muito detalhado.
favoritado,
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
Albfneto,
Ribeirão Preto, S.P., Brasil.
Usuário Linux, Linux Counter: #479903.
Distros Favoritas: [i] Sabayon, Gentoo, OpenSUSE, Mageia e OpenMandriva[/i].

[2] Comentário enviado por anonimoculto em 06/08/2018 - 19:18h

@Albfneto: fico grato ter apreciado. À disposição.

[3] Comentário enviado por binbash em 25/08/2018 - 00:29h

Favoritei!


"Primeiro eles te ignoram, depois riem de você, depois brigam, e então você vence."
Mahatma Gandhi
http://terminalroot.com.br/shell

[4] Comentário enviado por F4xl em 18/10/2018 - 08:22h

Parabéns pelo excelente artigo! É praticamente um livro pronto!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts