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

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

Executando backup do MySQL e enviando por FTP

Criando Autoridades Certificadores e Certificados de Testes no Linux

Simples sistema de backup com acesso remoto

Monitorando servidores pelo celular

Como programar backup com rsync e cron de maneira rápida e simples

  
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