Aula 1 – Conceitos Básicos

Índice | Aula 2 – Antes do primeiro script


Seu apoio é muito importante para a criação e a manutenção dos cursos gratuitos do canal debxp:


1.1 – O que é o ‘shell’

Mesmo que você nunca tenha criado nenhum script, mesmo que não saiba nada de programação, se você usa o terminal ou o console de qualquer distribuição GNU/Linux, ou o terminal do seu Mac, ou até o console do Windows, você já está utilizando algum tipo de shell.

De forma geral, você pode entender o shell como uma camada que envolve o sistema operacional como uma "casca" (daí no nome shell). Essa camada é responsável por fazer uma interface entre o usuário e o núcleo do sistema, que é chamado de kernel. A principal função do kernel é fazer a parte física do seu computador (ou hardware) funcionar. Mas, para isso, ele também precisa receber instruções dos vários programas que você irá executar e, principalmente, instruções vindas de você, o usuário. É aí que entra o shell.

1.2 – Terminais e consoles

Nos tempos mais remotos da computação, a comunicação física entre o usuário e o kernel era feita através da entrada de comandos por fitas ou cartões perfurados, com ou sem a ajuda de um teclado, e do recebimento de respostas através de uma impressora.

Naquela época, o conjunto composto por um equipamento de exibição de mensagens e um dispositivo de entrada de comandos era chamado de console. Mais tarde, quando os grandes computadores já permitiam o compartilhamento de seus recursos entre vários consoles distribuídos em locais diferentes, cada uma dessas estações de trabalho passou a ser chamada de terminal.

Com os avanços tecnológicos, à medida em que os equipamentos foram reduzindo de tamanho e os monitores de vídeo começaram a ser utilizados para exibir mensagens, os consoles e terminais já não eram mais equipamentos exatamente. Assim como hoje nós utilizamos sistemas operacionais inteiros virtualizados, os consoles e terminais também foram virtualizados através de programas, dando origem à terminologia console virtual (VC) e terminal virtual (VT).

Hoje portanto, quando dizemos "console" ou "terminal", estamos nos referindo justamente à virtualização em software (feita pelo kernel) dos antigos terminais e consoles eletrônicos dos primórdios da computação, e o programa responsável por tornar essa virtualização capaz de receber comandos de um teclado e exibir mensagens em um monitor, é precisamente o shell!

1.3 – O ‘prompt’ de comandos

Assim que você faz o login no console ou abre um terminal no seu ambiente gráfico, o shell é iniciado e nos mostra um ou mais caracteres e um cursor no local onde serão exibidos os comandos digitados por nós. Este ponto onde aparece o cursor é o prompt de comandos. Sua função é indicar que o shell está "pronto" (daí prompt) para receber comandos. Na verdade, podemos dizer que acessar o prompt de comandos é o mesmo que acessar o shell.

Nós temos basicamente três formas de acessar o prompt de comandos em sistemas GNU/Linux:

  • Nos ambientes gráficos, abrindo um emulador de terminal.
  • A partir de um ambiente gráfico, podemos abrir um console virtual teclando o atalho Ctrl+Alt+F[n], onde F[n] é uma tecla de função entre F1 e F6, teclando Ctrl+Alt+F7 (ou Ctrl+Alt+F8 em algumas distribuições) para retornar ao ambiente gráfico.
  • Simplesmente não instalando/iniciando um ambiente gráfico, caso em que temos apenas o console virtual para trabalhar.

Ainda em termos gerais, as principais diferenças entre trabalhar com um emulador de terminal ou trabalhar com um console são:

Emulador de Terminal (ambiente gráfico) Console Virtual (modo "texto")
Você já está "logado" no ambiente gráfico e, portanto, não será pedida nenhuma informação de login e senha. Sempre que for iniciado, você terá que informar o seu login e senha para ter acesso ao prompt.
Você pode usar o mouse para selecionar textos, rolar o histórico da sessão, copiar, colar, etc… Embora existam programas para implementar o uso do mouse, o normal é que todas as ações sejam realizada por atalhos de teclado.
A quantidade de caracteres por linhas e colunas de texto dependem da largura e da altura da janela do terminal e do tamanho da fonte que você escolheu. A quantidade de linhas e colunas de texto dependem apenas da resolução que o kernel identificou para o seu monitor.
Você pode escolher diversos tipos de fontes e exibir corretamente caracteres gráficos dos mais diversos tipos. Você está limitado ao conjunto de fontes específicas para o console e ao conjunto de caracteres que elas são capazes de exibir corretamente.

Fora isso, as únicas diferenças seriam aquelas relativas ao contexto dos seus comandos — não faria muito sentido executar comandos para abrir programas gráficos ou executar tarefas com eles estando no console, por exemplo.

1.4 – A aparência do ‘prompt’

Dependendo do sistema operacional e das customizações feitas, o prompt pode apresentar várias informações, mas o que importa para nós por enquanto são os símbolos mostrados imediatamente antes do cursor. Quando vemos $ ou % antes do cursor, o shell está indicando que você fez login como um usuário normal. Já o sinal # informa que você fez login como usuário administrativo, o usuário root.

O usuário root é uma conta especial que possui permissões para realizar qualquer tipo de operação no sistema, inclusive destruí-lo completamente! Portanto, a cerquilha (#) é um aviso de que estamos numa zona altamente perigosa para quem não sabe exatamente o que está fazendo e como fazer as coisas.

Importante! Fique atento ao seu prompt e, principalmente, a menos que seja orientado para isso, jamais execute os nossos exemplos e experimentos como usuário root!

Uma pequena convenção para os nossos estudos

Além de informar se estamos "logados" como usuários normais ou administrativos, o shell também é capaz de informar o nome do diretório em que estamos trabalhando. Como veremos bem mais adiante, em shells como o Bash, por exemplo, o símbolo ~ (til) representa o nome da sua pasta pessoal de usuário.

Por exemplo, se o seu nome de usuário for blau, o til representará o diretório /home/blau. Desta forma, o shell tem um jeito de informar em que pasta você está trabalhando sem ocupar muito espaço no prompt.

Outras informações que costumam vir configuradas para serem exibidas em sistemas GNU/Linux são o nome do usuário e o nome da máquina na rede (hostname). Então, é muito comum encontrar algo assim no prompt após o login ou quando abrimos um emulador de terminal:

blau@enterprise:~$

Onde blau é o meu nome de usuário, @ é um símbolo que, em inglês é lido como at ("em", em português), enterprise foi o nome que eu dei para a minha máquina na rede durante a instalação, : é só um separador, ~ é a minha pasta home e, finalmente, $ me diz que estou "logado" como um usuário comum.

Aqui nos nossos exemplos e execícios, porém, nós não precisamos de todas essas informações. Por isso, vamos adotar a seguinte convenção:

:~$ --> Pasta corrente mais indicação de usuário normal;

Ou…

:~# --> Pasta corrente mais indicação de usuário 'root';

1.5 – Shell interativo e não-interativo

Quando abrimos um terminal e começamos a digitar comandos, nós estamos utilizando o shell de forma interativa. No modo interativo, nós entramos com um comando, o shell processa esse comando, nos dá uma resposta, nós vemos a resposta, pensamos e decidimos o que fazer em seguida. Ou seja, nós interagimos diretamente com o shell através dos nossos comandos e observando os resultados obtidos.

Mas existe uma outra forma de trabalhar com o shell que pode ser muito útil e prática, principalmente quando temos que executar vários comandos em sequência e avaliar os possíveis retornos para decidir quais comandos dar em seguida. Trata-se do modo não-interativo, que nada mais é do que escrever todos os comandos em um arquivo de texto, tornar esse arquivo executável e simplesmente mandar o shell executá-lo de uma só vez. A este arquivo, que contém todos os comandos e instruções que queremos que o shell execute, nós damos o nome de script.

Como veremos, além dos comandos e programas para executar tarefas específicas, o shell também oferece diversos tipos de recursos capazes de transformar uma simples lista de comandos a serem executados em lote em verdadeiros programas!

Observação: como diz Aurélio Jargas, autor de vários materiais incríveis sobre programação em shell e expressões regulares, "um programa é apenas um script feito do jeito certo".

1.6 – Tipos de shell

Existem vários tipos de shell, figurando entre eles:

Nome Executável Descrição
Bourne Shell sh Desenvolvido por Stephen Bourne, da AT&T, é o Shell padrão do UNIX 7 em substituição do Thompson Shell, cujo executável possuía o mesmo nome, sh.
Bourne-Again Shell bash GNU/Bash ou, como é mais conhecido, Bash, é um shell de comandos Unix e uma linguagem interpretada escrita inicialmente por Brian Fox para o Projeto GNU em substituição ao Bourne Shell. Quando Fox foi afastado da FSF, em 1994, o desenvolvimento do Bash passou para Chet Ramey.
Almquist Shell ash, sh É um shell Unix escrito originalmente por Kenneth Almquist no fim dos anos ’80 como um clone da variente System V.4 do Bourne Shell e substituiu o Bourne Shell original nas versões do Unix BSD lançadas no começo dos anos ’90, razão pela qual algumas de suas implementações ainda utilizam o nome de executável sh.
Debian Almquist Shell dash, sh Em 1997, o Almquist Shell foi portado do NetBSD para o Debian, que em 2002 lançou uma versão renomeada para Debian Almquist Shell, ou dash, priorizando a compatibilidade com os padrões POSIX e uma implementação bem mais enxuta em relação à original.
KornShell ksh Desenvolvido sobre o código do Bourne Shell por David Korn no começo dos anos ’80, o KornShell era inicialmente um projeto proprietário e mais tarde adotou uma licença compatível com as diretrizes Open Source.
Z Shell zsh Criado com a proposta de ampliar as funcionalidades do Bourne Shell, o Zsh traz diversos recursos presentes no Bash e no KornShell. Em 2019, foi adotado como shell padrão do macOS Catalina, papel que era ocupado até então pelo Bash.

E a lista poderia seguir por várias páginas! Mas, para nós o que realmente interessa é o Bourne-Again Shell, que é o shell padrão do Projeto GNU e, portanto, o shell mais presente em sistemas GNU/Linux.

Outra coisa importante de destacar, é que cada shell tem a sua própria forma de reconhecer e interpretar os comandos dos usuários e trabalha com sintaxes que podem ser muito diferentes. Então, se estiver escrevendo um script em Bash que precisará ser compatível com plataformas que utilizem outros shells, provavelmente será necessário observar as definições da norma POSIX (Portable Operating System Interface, "Interface Portável Entre Sistemas Operacionais", em português). Como o nome diz, o objetivo é garantir a portabilidade do código de um programa ou de um script a partir de um conjunto de normas.

Ao longo deste treinamento, nós não teremos esse tipo de preocupação. Nosso objetivo aqui é conhecer e explorar o máximo possível as funcionalidades e os recursos do Bash. Contudo, o modo POSIX é uma dessas funcionalidades, então vamos tirar esse elefante da sala de uma vez.

O modo POSIX do Bash

Para começar, todo shell também é um programa executável, e o executável do Bash chama-se bash. Ele é invocado automaticamente após o login, mas também pode ser executado no terminal com o objetivo de iniciar outra sessão do shell. Este comportamento é equivalente ao que acontece quando executamos um script, ou seja, exceto em situações bem específicas que não vêm ao caso agora, cada script irá iniciar uma nova sessão do shell quando for executado.

Com isso em mente, fica mais fácil entender que o Bash possui algumas opções de execução, entre elas, a opção de ser executado no modo de compatibilidade com as normas POSIX, que é o modo POSIX. Quando iniciado com a opção --posix, ou executando o comando set -o posix em uma sessão já iniciada, o Bash terá seu comportamento padrão alterado para atender as normas POSIX.

Entrando em modo POSIX, o Bash altera uma lista de 59 aspectos do seu comportamento normal, o que não caberia detalhar neste tópico introdutório. Mas, se estiver curioso, a lista completa de mudanças pode ser lida diretamente no manual do Bash.

1.7 – Os comandos builtin do Bash

O bash possui um farto conjunto comandos internos chamados de builtin, e nós utilizamos alguns deles bem frequentemente no terminal, como é o caso do comando cd, usado para mudar de diretório.

Para ver a lista completa dos builtins, nós podemos executar o seguinte comando builtin:

:~$ help

Também podemos ver as informações sobre um comando interno do Bash com a sintaxe:

help nome_do_comando

Isso fará com que um manual resumido do comando seja exibido no terminal, ou uma mensagem de erro, caso o comando não seja um builtin.

Nota: nem tudo que você executa no terminal é um comando interno do bash!

Então, se estiver na dúvida se um comando é ou não é builtin, basta executar help nome_do_comando. Se a resposta for um erro, não é um builtin.

Outra forma de descobrir, é com o comando interno type:

type nome_do_comando

Se for o caso, ele retornará a mensagem:

nome_do_comando é um comando interno do shell

Para entender melhor, é uma boa ideia você abrir agora mesmo um terminal e executar os dois comandos abaixo:

:~$ help type
:~$ type help

Aliás, aproveitando que está com o terminal aberto, experimente esses comandos:

:~$ help cd
:~$ help ls
:~$ help command (observe o que diz na opção '-v')
:~$ type cd
:~$ type ls
:~$ type command

Observe não só o que o help diz sobre esses comandos, mas principalmente as mensagens que o Bash retorna, se são builtins ou não, e anote as suas descobertas.

Aproveite para ver o que acontece com os comandos abaixo:

:~$ command -v type
:~$ command -v help
:~$ command -v cd
:~$ command -v ls

1.8 – Como saber que tipo de shell você está utilizando

Para encerrar este tópico, nós vamos ver duas formas de descobrir qual shell está sendo utilizado no seu sistema. As duas formas podem apresentar resultados equivocados, mas são um bom ponto de partida.

Método 1: comando ‘echo $0’

No Bash, $0 é o que nós chamamos de parâmetro posicional (não se assuste com o nome por enquanto, nós falaremos sobre isso em detalhes em outros tópicos), que é uma variável especial que armazena o nome do programa em execução. Se você está no prompt de comando, o programa em execução o shell é o próprio shell!

Mas, o que faz esse tal de echo?

Não me pergunte, veja você mesmo!

:~$ help echo

Se você foi pesquisar, deve ter encontrado isso:

:~$ help echo
echo: echo [-neE] [ARG ...]
    Write arguments to the standard output.

    Display the ARGs, separated by a single space character
    and followed by a newline, on the standard output.

Que poderia ser traduzido como algo assim:

:~$ help echo
echo: echo [-neE] [ARGUMENTOS ...]
    Escreve argumentos na saída padrão.

    Exibe os ARGUMENTOS separados por um único espaço
    e seguidos de uma nova linha na saída padrão.

No nosso comando (echo $0), o argumento é o conteúdo armazenado em $0, e a tal da saída padrão, de forma bem simplificada, nada mais é do que a tela do seu terminal. Então, podemos dizer que o comando echo imprime na tela aquilo que nós passarmos para ele como argumento. Por exemplo, experimente isso:

:~$ echo Olá, mundo!

Aqui, a frase Olá, mundo! é o argumento que nós queremos que o comando echo exiba. Se você testou, deve ter visto algo como isso:

:~$ echo Olá, mundo!
Olá, mundo!

Agora que você já sabe como funciona o comando echo e que a variável $0 pode conter o nome do shell que você está usando, vamos ver o que acontece. Aqui no meu terminal, a saída foi essa:

:~$ echo $0
bash

Mas, perceba uma coisa: a variável $0 nem sempre irá conter o nome do shell! Esta foi uma situação especial em que você estava trabalhando diretamente no prompt. Lembre-se de que eu disse: $0 é uma variável especial que armazena o nome do programa em execução. Se você chamar esse comando dentro de um script, por exemplo, ela vai conter o nome do script, pois é ele, e não o prompt do shell que está sendo executado.

Ou seja, este método só funciona no modo interativo e não serve para verificar qual é o shell que está sendo usado dentro de um script!

Método 2: comando ‘echo $SHELL’

Aqui, nós vamos dar uma olhada no conteúdo de outra variável do Bash, a variável $SHELL. O interessante dessa variável é que ela está disponível para ser consultada por qualquer comando ou programa, por isso é chamada de variável de ambiente. Sua função é armazenar o caminho do executável do shell configurado para um determinado usuário assim que ele fizer um login. Executando o comando, foi isso que eu obtive na saída:

:~$ echo $SHELL
/bin/bash

Nota: Estas não são as únicas formas de encontrar o nome do shell em uso, mas são as mais simples para o propósito dessa introdução.


Índice | Aula 2 – Antes do primeiro script

4 Responses

  1. Olá Blau, venho acompanhando seus videos de linux em geral, mas principalmente em relação ao bash e ao scripts e funções, estou adorando!

    Você menciona inúmeros tipos de shells, não sei se você chegou a usar, mas em algum momento da década de 90 até meados de 2005,
    tive que aprender tanto o “ shell ‘sh’ “ quanto o ‘tcsh’ . Pois eram os únicos disponíveis para a distribuição do IRIX ( variação muito próxima do unix ).

    E na época, acabei descobrindo o ‘tcsh’ pois haviam vários recursos nele que não tinha no ‘sh’, como por exemplo, a seta pra cima para repetir os comandos anteriores.

    Eu usei o IRIX em máquinas específicas para produção e finalização de video para cinema e TV.

    Rodavam em maquinas da SGI – Silicon Graphics,
    maquinas na época CARÍSSIMAS, na ordem de $ 1 milhão de dólares. Como a INDIGO, OCTANE, OCTANE2, ONYX, ONYX 1, ONYX 2 e ONYX 350.

    Eram máquinas modulares, com 1 unidade de Rack de processadores, Normalmente com
    2 Arrays Fiber Channel com 15 discos FC de
    300 a 500GB. 1 Modulo Gráfico com suporte a até 2 Gb de video ( lembre-se que isso era entre 95 e ano 2000 .

    O início padrão do sistema era apenas com um terminal preto ( na parte de cima da tela ) e um console ( na parte de baixo ).

    Desculpe o texto longo, mas não soube como escrever mais resumidamente o porque eu acho importante mencionar o TCSH também.

    abraços,
    robtys

      • Trabalho a cerca 20 anos em uma empresa chamada Link Digital, quando comecei a trabalhar lá, era uma media empresa. No meio que eu trabalho se chama Finalizadora.
        Para simplificar, um cliente contrata uma produtora, que na época, editava e finalizava o video com a gente ( efeitos visuais, créditos, rotoscopia, correção de cor etc… )
        Tínhamos 1 Telecine 2k, 3 Fires, 2 Smokes e
        3 Avids e 1 Transfer.

        Quando eu entrei, eu ajudava na manutenção das máquinas, o que era bem complicado na época, por falta de manuais e também por ser um sistema todo fechado.

        Exemplo, o Fire 1, só rodava na Onyx 1 ( a menor de todas ), um pouco menor que uma lavadora de roupas.

        Tudo nessas máquinas era proprietário, inclusive o hardware ( acredite, até os HDs dos Arrays, tinha um firmware modificado ) os HDs tinham que vir do Canada. A arquitetura era Risk. E com exceção do teclado, do mouse e a conexões FC ( que já usávamos conector LC-LC de 2Gbps com 4 loops ) tudo era fora do padrão conhecido.

        Com o passar dos anos fui aprendendo mais e mais sobre esses sistemas e hardwares que acabei virando o gerente tecnico da empresa.

        Mas hoje as coisas mudaram muito, nós ainda
        temos alguns equipamentos top, e ainda temos um nome no mercado.

        Hoje fazemos DCP ( empacotamento e compreensão ) que vai para os cinemas hoje em dia. Também convertemos as Libras, closed captions e legendas para DCP.

        Temos uma ótima Ilha do correção de cor, etc…

        Se quiser mais detalhes me fale, que terei prazer e lhe informar o que quiser. Afinal, eu me sinto em dívida com você por tanto conhecimento que já me passou.

        Obrigado
        robtys

        • Que sensacional seus comentários cara. Eu trabalho com edição de vídeo mas obviamente eu já cheguei na era do Adobe Premier. Obrigado por compartilhar.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Post comment