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

Por: Anonimo Oculto Culto em 06/08/2018


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



Nas páginas anteriores desse artigo apresentaram-se os fundamentos do que vêm a ser os assim chamados terminais burros (videotextos ou teletipos), os arquivos de dispositivo, os descritores de arquivos e os arquivos descritores. A continuidade da leitura pressupõe compreensão destes conceitos conforme relatados, visto que nesta seção apresentar-se-ão os exemplos práticos associados à parte teórica descrita.

Atualmente os antigos teletipos (terminais de vídeo) são simulados no próprio console da máquina rodando o sistema operacional a fim de prover um canal de comunicação entre o usuário e o sistema em si, visto não serem mais usuais os teletipos físicos. A comunicação com esses pseudoterminais se dá através de arquivos de dispositivo, assim como o outrora feito com os teletipos reais.

Inciando-se a parte prática com o auxílio de pseudoterminais, solicita-se que se sigam as instruções abaixo a fim de se executar, na máquina do leitor, o mesmo relatado dentro do possível através das capturas de tela apresentadas nessa seção. Solicita-se de início a abertura de (apenas) três pseudoterminais do konsole (ou de outro pseudoterminal como o gnome-terminal). Executando-se o comando "tty" em cada um deles, ter-se-ão exibido os respectivos arquivos de dispositivo atrelados a cada janela; e executando-se o comando " ls -la " a partir do diretório /dev/fd/ , a situação atual dos descritores de arquivo padrão para cada um dos pseudoterminais será exibida. O número de processo da instância do BASH atrelado a cada terminal também será necessário, podendo-se obtê-lo com "echo $BASHPID". [Ref.: 6 | 9 | 14 | 16 | 18 | 19]

Uma vez abertos, execute pois em cada terminal a linha de comando:

tty ; echo $BASHPID ; cd /dev/fd ; ls -la ; cd ~
FIGURA 06: preparativos para a parte prática. Um exemplo avulso das saídas esperadas para a linha de comandos acima, executada em pseudoterminais konsole em ambiente KDE - SUSE Linux 13.2 (Harlequin). Os valores dos números de processos (PIDs) são "aleatórios" e particulares a cada execução do programa. [Ref.: 24]

Posicione as três janelas de forma a se localizá-las facilmente em função da numeração dos respectivos arquivos de dispositivos reportados na primeira linha da saída dos comandos acima; e de forma que se possa vê-las todas em íntegra, dê destaque à tela com pts de valor mais baixo; nos exemplos que se seguem /dev/pts/1. Nessa última janela se fará doravante todo o processamento que se segue.

Uma vez identificadas as informações necessárias, a partir da tela de dispositivo /dev/pts/1, execute o seguinte comando:

exec 1>/dev/pts/3

Podem-se ter de adaptar os valores à situação, em particular os PIDs, mas se apenas três pseudoterminais foram abertos, o comando acima não se altera. Com este comando se transfere a saída de dados (stdout) do bash atrelado ao pts/1 para o pts/3 (ver Carta de Redirecionamentos à página 4 deste artigo [Ref.: 23]). Doravante as saídas de comandos executados no terminal pts/1 vão à tela do pts/3. O comando "exec" faz com que o redirecionamento tenha efeito na instância corrente do shell, e não apenas nos subshell ou comandos invocados a partir dela como visto em página anterior desse artigo [Ref.: 9 | 25]. Para certificar-se do redirecionamento, como exemplo execute os seguintes comandos no terminal pts/1:

echo
$ cd /dev/fd
$ ls
$ ls -la
$ echo


O comando echo pula a linha de forma a não se embolarem os dados e dar uma estética melhor. Todas as saídas desse comando não seguem as respectivas linhas de instrução na tela /dev/pts/1. Elas são exibidas na tela do dispositivo /dev/pts/3. Observe descritor 1 e seu apontamento para visualizar e compreender o que se fez.

O passo seguinte é perceber que, na tela /dev/pts/3 há também uma instância do bash rodando, e se esta janela ganhar foco (não o faça, mas se o fizer, volte o foco à janela pts/1), ela também poderá executar seus próprios comandos. Dois programas escrevendo na mesma tela assincronamente podem fazer uma verdadeira bagunça na tela. Assim, a fim de configurar a tela pts/3 como apenas uma tela de saída de dados, deve-se matar o bash associado a ela. Execute, com o foco em pts/1, o comando:

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

ajustando o número do PID do bash à situação particular. Na figura seguinte o {PID ...} era 5458. Uma linha vermelha na janela pts/3 informará que o bash associado está devidamente morto. [Ref.: 9 | 26]

Uma observação aqui: em sistemas mais antigos, por experiência, não é viável se matar o bash pois tal procedimento mata também o pseudoterminal associado (a janela simplesmente fecha). Caso seja este o caso, não execute tal procedimento, deixando ambos os shells concorrentes. Para fins desse artigo não haverá maiores problemas.
FIGURA 07: uma execução, com comentários no próprio terminal (linhas iniciadas por #), dos procedimentos sendo indicados acima. O terminal com foco é aquele em janela própria, à direita. À esquerda, a janela de erros e comandos (situação final), no centro, a janela de saída de dados (stdout). [Ref.: 27]

Dando sequência aos procedimentos, faremos agora a mesma peripécia com a saída de erro (stderr) do bash iniciado junto ao terminal pts/1. A saída de erro é redirecionada agora ao outro terminal, /dev/pts/2, com o comando:

exec 2>/dev/pts/2

Doravante, tudo o que se escreve com o foco na janela pts/1 aparece na tela pts/2, incluindo-se o prompt de comandos do bash, que é veiculado através do canal de erro (stderr) e não de saída (stdout) da instância do shell. O passo seguinte é matar o bash na janela pts/2:

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

devendo-se aqui aplicar o PID particular à situação. Na implementação desse procedimento conforme ilustrada (figura acima), o PID era 5429. Repare que as instruções para se matar o bash à janela pts/2 são vistas agora nesta própria janela, embora o foco esteja com pts/1.

Repare na saída do comando "la -la" realizado a partir do diretório /dev/fd (execute antes "cd /dev/fd" caso necessário). O descritor zero, a entrada padrão (stdin) do bash em pts/1, aponta para /dev/pts/1 , implicando que a entrada de dados via teclado se dá com foco em pts/1; o descritor 1, a saída padrão, agora aponta para /dev/pts/3, indicando que os dados de saídas dos comandos serão exibidos em pts/3; e o descritor 2, a saída de erro padrão (stderr), aponta para /dev/pts/2, indicando que os alarmes de processamento bem como o prompt de comandos e as entradas de teclado ecoadas serão vistos em /dev/pts/2.

Para finalizar, uma observação sobre como se limpam as telas. No Linux há duas formas de se limparem as telas quando se executa o bash: a primeira se dá via combinação de teclas CTRL-L (ou seja, as teclas Control mais L); a segunda através do comando "clear" [Ref.: 28]. A combinação de teclas gera em verdade uma sequência de escape conhecida como "form feed", carregamento de folha, referenciando-se aqui o comportamento do papel perfurado nas antigas impressoras matriciais.

A tela é limpa por deslocamento para cima (o que se pode ver rodando-se a barra de rolagem à lateral da janela do terminal após um CTRL-L). A sequência contudo é "despachada" à saída de erro, de forma que, na configuração realizada, CTRL-L limpa a janela pts/2. Já "clear" é um comando, e sua saída limpa pois a janela conectada à sua saída de dados conforme herdada do bash que o invoca (ou conforme redirecionamento explícito), no caso, a janela pts/3. [Ref.: 29 | 30]
FIGURA 08: Control-L limpa a saída de erro, a janela pts/2. Já o comando "clear" limpa a saída padrão, pts/3 no exemplo. [Ref.: 31]

Vale ressaltar que o procedimento acima descrito tem finalidade meramente didática. Uma implementação prática e útil do descrito por certo dispensa o redirecionamento da saída de erro, e apenas duas janelas de terminal se fazem necessárias. A figura abaixo ilustra uma implementação efetivamente prática: janela de comandos e erros em um pseudoterminal, saída limpa de comandos na tela de outro pseudoterminal. Pouco usual, contudo.
FIGURA 09: uma implementação útil dos pseudoterminais mediante redirecionamentos. [Ref.: 32]

Por razões técnicas a serem vistas, recomenda-se que as janelas de saídas de dado e de erro sejam feitas do mesmo tamanho preferencialmente, ou maiores, que a janela com a instância do bash, observados tanto comprimentos como larguras. Tal procedimento evita distorções de exibição dos textos de saída nas janelas de destino (ver próxima seção).

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

Monitorando servidores pelo celular

Simples sistema de backup com acesso remoto

Liberar navegação para Speedy Home

ShellBot - Crie Bots para Telegram em Shell Script

Entendendo, criando e editando pacotes Debian (.deb)

  
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