# Shell do Unix

Um shell do Unix é um interpretador de linha de comando ou shell que fornece uma interface semelhante ao Unix tradicional. Os usuários indicam a operação do computador pela entrada de comandos como texto para um interpretador de linha de comando executar, ou criando scripts de texto de um ou mais de tais comandos. Usuários tipicamente interagem com um shell do Unix usando um emulador de terminal, entretanto, operação direta via conexão serial de hardware, ou sessão de rede de computadores, são comuns para sistemas de servidor. Todos os shells do Unix fornecem caracteres-curinga de nome de arquivo, encadeamento, here documentos, substituição de comando, variáveis e estruturas de controle para teste condicional e iteração.

## Conceito

O senso mais genérico do termo shell significa algum programa que o usuário emprega para tipificar comandos. Um shell esconde os detalhes do sistema operacional subjacente e gerencia detalhes técnicos da interface do kernel do sistema operacional, que é o nível mais baixo, ou componente "mais íntimo" de muitos sistemas operacionais.
Em sistemas operacionais tipo Unix, usuários tipicamente têm muitas escolhas de interpretadores de linha de comando para sessões interativas. Quando um usuário faz login no sistema interativamente, um programa shell é automaticamente executado para a duração da sessão. O tipo do shell, que deve ser customizado por cada usuário, é tipicamente armazenado no perfil do usuário, por exemplo, no arquivo passwd local ou em um sistema de configuração distribuída como o NIS ou LDAP; contudo, o usuário deve executar algum outro shell disponível interativamente.
O shell do Unix é ambos, um linguagem de comando interativa, e também uma linguagem de script, e é usado pelo sistema operacional como a facilidade para controlar (shell script) a execução do sistema. Shells criados para outros sistemas operacionais frequentemente fornecem funcionalidade similar.
Em hosts com um sistema de janelas, como o macOS, alguns usuários nunca devem usar o shell diretamente. Em sistemas Unix, o shell foi historicamente a linguagem de implementação de scripts de boot do sistema, incluindo o programa que inicia um sistema de janelas, configura a rede de computadores, e muitas outras funções essenciais. Porém, alguns fornecedores de sistema substituíram o sistema de boot tradicional baseado em shell (init) com abordagens diferentes, tais como o systemd.

## Primeiros shells

O primeiro shell do Unix foi o Thompson shell, sh, escrito por Ken Thompson no Bell Labs e distribuído com versões 1 até o 6 do Unix, de 1971 a 1975. Embora rudimentar pelos padrões modernos, ele introduziu muitos dos recursos básicos comuns, mais tarde, a todos os shells do Unix, incluindo encadeamento, estruturas de controle simpl usando if e goto, e caracteres-curinga de nome de arquivo. Embora não esteja em uso atualmente, é ainda disponível como parte de alguns antigos sistemas UNIX.
Ele foi modelado depois do shell da Multics, que foi modelado depois do programa RUNCOM de Louis Pouzin, que o mostrou à equipe da Multics. O sufixo "rc" em alguns arquivos de configuração Unix (por exemplo, ".vimrc"), é um remanescente da linhagem RUNCOM dos shells do Unix.
O shell PWB ou shell Mashey, sh, foi uma versão compatível do Thompson shell, expandida por John Mashey e distribuída com o Workbench do Programador UNIX, por volta de 1975-1977. Ele realçou em fazer um shell de programação prática, especialmente em grandes centros de informática compartilhados. Ele adicionou variáveis shell (precursoras das variáveis de ambiente, incluindo o mecanismo path de pesquisa que evoluiu para $PATH), scripts shell executáveis por usuário, e tratamento de interrupções. Estruturas de controle foram estendidas de if/goto para if/then/else/endif, switch/breaksw/endsw, e while/end/break/continue.
Como a programação de shell tornou-se muito difundida, estes comandos externos foram incorporados ao shell para a sua performance.
Mas, os mais amplamente distribuídos e influentes dos primeiros shells do Unix foram o Bourne shell e o C shell. Ambos os shells foram usados como código-base e modelo das muitas derivações e trabalhos de shells semelhantes com configurações de fábrica estendidas.

### Bourne shell

O Bourne shell, sh, foi reescrito por completo por Stephen Bourne no Bell Labs. Distribuído como o shell para o UNIX Versão 7 em 1979, ele introduziu o resto dos recursos básicos considerados comuns a todos os shells do Unix, incluindo here documentos, substituição de comando, mais variáveis genéricas e mais estruturas de controle embutidas extensivas. A linguagem, incluindo o uso de uma palavra-chave invertida para marcar o fim de um bloco, foi influenciada por ALGOL 68. Tradicionalmente, o nome do programa Bourne shell é sh e seu path na hierarquia do sistema de arquivos Unix é /bin/sh. Mas um número de trabalhos semelhantes compatíveis estão também disponíveis com várias melhorias e recursos adicionais.
Em muitos sistemas, sh deve ser uma ligação simbólica ou ligação forte para uma destas alternativas:
* Almquist shell (ash): escrito como uma substituição licenciada do BSD para o Bourne Shell; frequentemente usado em ambientes restritos de recurso. O sh do FreeBSD, NetBSD (e seus derivados) são baseados no ash que foi aprimorado para ser POSIX conforme a ocasião.
* Bourne-Again shell (bash): escrito como parte do Projeto GNU para fornecer um superset de funcionalidade do Bourne shell. Este shell pode ser encontrado instalado e é o shell interativo padrão para os usuários em muitos sistemas Linux e MacOS.
* Debian Almquist shell (dash): uma substituição moderna para ash em Debian e Ubuntu
* Korn shell (ksh): escrito por David Korn baseado nas fontes do Bourne shell enquanto trabalhava no Bell Labs
* Public domain Korn shell (pdksh)
* MirBSD Korn shell (mksh): um descendente do OpenBSD /bin/ksh e pdksh, desenvolvido como parte de MirOS BSD
* Z shell (zsh): um shell relativamente moderno que é compativelmente reverso com bash
* Busybox: um set de utilidades Unix para sistemas pequenos e embarcados, que inclui 2 shells: ash, uma derivação do Almquist shell; e hush, uma implementação independente de um Bourne shell.
O padrão POSIX especifica seu shell padrão como uma subconfiguração rigorosa do Korn shell, uma versão melhorada do Bourne shell. Da perspectiva do usuário, o Bourne shell foi imediatamente reconhecido quando ativo pelo caractere de prompt de linha de comando padrão característico, o símbolo de dólar ($).

### C shell

O C shell, csh, foi escrito por Bill Joy, enquanto um estudante graduado na Universidade da Califórnia em Berkeley e largamente distribuído com o BSD Unix. A linguagem, incluindo as estruturas de controle e a gramática de expressão, foi modelada em C. O C shell também introduziu um largo número de recursos para trabalho interativo, incluindo os mecanismos de história e edição, pseudônimos, pilhas de diretório, notação til, cdpath, job control e path hashing. Em muitos sistemas, csh deve ser uma ligação simbólica ou ligação forte ao TENEX C shell (tcsh), uma versão melhorada do csh original de Joy. Embora os recursos interativos do C shell foram copiados em muitos outros shells atuais, a linguagem em si mesma não foi amplamente copiada. O único trabalho semelhante é o Hamilton C shell, escrito por Nicole Hamilton, primeiro distribuído no OS/2 em 1988 e no Windows desde 1992.

## Arquivos de configuração

Shells leem arquivos de configuração em múltiplas circunstâncias que diferenciam dependendo do shell. Estes arquivos comumente contém comandos para o shell particular e são executados quando carregados; eles são frequentemente usados para configurar importantes variáveis usadas para encontrar executáveis, como $PATH, e outras que controlam o comportamento e aparência do shell. A tabela nesta seção mostra os arquivos de configuração para shells populares.
| | sh | ksh | csh | tcsh | bash | zsh |
| /etc/.login | | | login | login | | |
| /etc/csh.cshrc | | | yes | yes | | |
| /etc/csh.login | | | login | login | | |
| ~/.tcshrc | | | | yes | | |
| ~/.cshrc | | | yes | yes | | |
| ~/etc/ksh.kshrc | | int. | | | | |
| /etc/sh.shrc | int. | | | | | |
| $ENV (typically ~/.kshrc) | int. | int. | | | int. | |
| ~/.login | | | login | login | | |
| ~/.logout | | | login | login | | |
| /etc/profile | login | login | | | login | login |
| ~/.profile | login | login | | | login | login |
| ~/.bash_profile | | | | | login | |
| ~/.bash_login | | | | | login | |
| ~/.bash_logout | | | | | login | |
| ~/.bashrc | | | | | int.+n/login | |
| /etc/zshenv | | | | | | yes |
| /etc/zprofile | | | | | | login |
| /etc/zshrc | | | | | | int. |
| /etc/zlogin | | | | | | login |
| /etc/zlogout | | | | | | login |
| ~/.zshenv | | | | | | yes |
| ~/.zprofile | | | | | | login |
| ~/.zshrc | | | | | | int. |
| ~/.zlogin | | | | | | login |
Explicação:
* blank significa um arquivo que não é lido por um shell por inteiro.
* "yes" significa um arquivo que é sempre lido por um shell sobre o boot.
* "login" significa um arquivo que é lido se o shell é um login shell.
* "n/login" significa um arquivo que é lido se o shell não é um login shell.
* "int." significa um arquivo que é lido se o shell é interativo.
* ↑ apenas se ~/.tcshrc não é encontrado
* ↑ Novas versões do Bourne shell apenas
* ↑ Disponível em sistemas que suportam "User Portability Utilities option"; valor da variável deve ser um path absoluto, e ela é ignorada "se o ID real do usuário e o do usuário efetivo ou o ID real e o de um grupo efetivo são diferentes."
* ↑ $ENV is $HOME/.shrc em novas versões do Bourne shell
* ↑ Mesmo comportamento como sh, mas apenas se invocado como sh (bash 2+) ou, a partir do bash 4.2, também se invocado explicitamente no modo de compatibilidade POSIX (com opções --posix ou -o posix).
* 1 2 Apenas no modo de compatibilidade sh/ksh (quando invocado como bash, sh, ksh)
* 1 2 3 de fato, o primeiro legível do ~/.bash_profile, ~/.bash_login e ~/.profile; e apenas ~/.profile se invocado como sh ou, como pelo menos Bash 4.2, se invocado explicitamente no modo de compatibilidade POSIX (com opções --posix ou -o posix)

## Shells exóticos

Das muitas variações exóticas no conceito do shell do Unix, incluem os seguintes:
* es: um shell compatível com rc em programação funcional escrito na metade da década de 1990.
* Friendly interactive shell (fish): primeiro lançamento em 2005.
* rc: o shell padrão no Plan 9 from Bell Labs e Version 10 Unix escritos por Tom Duff. Portas foram feitas em vários sistemas operacionais tipo Unix.
* scsh, um shell em Scheme.
* wish: um shell em sistema de janelas para Tcl/Tk.