Portal do Governo Brasileiro

shell

Descrição

É o interpretador de comandos do Linux.

Informações complementares

Arquivos

Suponha que o shell padrão do sistema seja o bash. Então, quando o usuário acessa o sistema, o bash utiliza os arquivos abaixo do diretório home para montar o ambiente (estes arquivos são criados automaticamente pelo comando adduser):

  1. .bashrc : contém funções, nomes alternativos (alias) e variáveis de ambiente do usuário.
  2. .bash_history : contém a lista dos últimos (o padrão é 1000) comandos digitados pelo usuário.
  3. .bash_logout : contém os comandos executados pelo sistema no fechamento da sessão pelo usuário.

Quando o usuário abre uma sessão, inicialmente são carregadas as definições gerais (armazenadas em /etc) e, em seguida, as definições específicas do usuário (armazenadas em /home): inicialmente o bash executa os comandos de /etc/profile, se ele existe; em seguida, o sistema procura e executa os arquivos /etc/bash.bashrc (configurações gerais do ambiente) e ~/.bashrc (configurações pessoais do usuário).

Os arquivos do shell bash para os usuários estão em /etc/skel. Estes arquivos são copiados para o diretório do usuário durante a criação da conta.

Parâmetros

No shell, um parâmetro é uma entidade que pode armazenar um número, um nome ou um caractere especial. Quando o parâmetro é identificado por um nome, ele é uma variável.

Existem três tipos de parâmetros:

Parâmetros posicionais

Um parâmetro posicional corresponde a um argumento fornecido na linha de comando. Ele é representado por $ seguido um ou mais dígitos. O menor valor para o dígito é 1, já que o parâmetro $0 corresponde ao nome do script. No caso da posição ser maior que 9, os dígitos deve ser colocados entre chaves.

Por exemplo, considere o script shell abaixo. Neste caso, o script informa quais são o primeiro, o segundo e o décimo parâmetros recebidos.

#!/bin/sh
echo "O nome do script = " $0
echo "O primeiro argumento = " $1
echo "O segundo argumento = " $2
echo "O decimo argumento = " ${10}
exit

Suponha que o nome do script seja teste_param e que doze parâmetros são fornecidos.

bash teste_param 1 oi a b c 7 8 9 teste xxx yyy zzz

A saída do programa é mostrada abaixo.

O nome do script = teste_param
O primeiro argumento = 1
O segundo argumento = oi
O decimo argumento = xxx

Parâmetros especiais

Este tipo de parâmetro é tratado de forma especial pelo shell. O programador pode referenciar os parâmetros especiais, mas não pode modificá-los.

São exemplos:

Por exemplo, considere o teste_param com o seguinte código:

#!/bin/sh
echo "O número de argumentos = " $#
echo "Argumentos passados = " $*
exit

O script é então executado usando o comando abaixo.

bash teste_param 1 oi a b c 7 8 9 teste xxx yyy zzz

A saída do programa será:

O número de argumentos = 12
Argumentos passados = 1 oi a b c 7 8 9 teste xxx yyy zzz

Caracteres especiais

O shell trata de forma especial as aspas, os apóstrofos e a barra invertida. Por exemplo, podemos digitar um dos quatro comandos abaixo

echo Guia Linux
echo "Guia Linux"
echo 'Guia Linux'
echo Guia\ Linux
e o resultado será o mesmo
Guia Linux
Entretando, quando um caractere especial é colocado entre as aspas, o shell interpreta este caractere. Assim, para saber o PID do shell sendo usado, podemos digitar
echo "pid = " $$
ou
echo "pid = $$"
Teremos a mesma resposta do sistema. Mas se usarmos
echo 'pid = $$'
a resposta será
pid = $$
pois, neste caso, o sistema não interpreta $$.

O shell não tenta interpretar o caractere que vem depois da barra invertida. Por exemplo,

echo \*
apenas mostra o caractere * na linha de comandos, enquanto
echo *
lista o conteúdo do diretário atual.

Variáveis

Uma variável pode ser definida como:

nome=[valor]

Se um valor não é fornecido, a variável é associada a uma string nula (null string).

Um tipo especial de variável são as variáveis do shell que customizam o ambiente de trabalho do usuário. Por isso, elas são também conhecidas como variáveis de ambiente.

Variáveis do shell

Os arquivos carregados pelo shell definem as variáveis de ambiente, que nada mais são que definições e valores que o shell e os outros programas do sistema reconhecem. Para ver quais as variáveis de ambiente no seu sistema você pode digitar printenv ou env. Por exemplo, são algumas das variáveis de ambiente do bash:

É possível criar novas variáveis, excluir variáveis existentes ou apenas alterar o conteúdo de uma variável de ambiente.

Para criar uma nova variável de ambiente, basta definir o nome e o valor da nova variável de ambiente e usar o comando export para permitir que a variável seja visualizada pelos aplicativos (por exemplo, um novo shell ou um novo terminal) inicializados no mesmo terminal (neste caso a variável existirá enquanto a sessão estiver aberta). Por exemplo,

TESTE=10; export TESTE
ou
export TESTE=10
cria a variável de ambiente TESTE com valor inicial 10. O comando export faz com que a nova variável seja conhecida por todos os processos a partir deste shell. Os nomes das variáveis de ambiente são, tradicionamente, definidas usando apenas letras maiúsculas. Entretanto, isto não é obrigatório. Você pode também usar letras minúsculas. Mas, CUIDADO! O Linux é case sensitive. Isto significa que o sistema diferencia letras maiúsculas de letras minúsculas. Portanto, o comando
teste=10; export teste
cria uma nova variável de ambiente chamada teste e que é diferente da variável TESTE criada anteriormente.

É importante observar que as variáveis de ambiente definidas a partir da linha de comando são temporárias. Para criar uma variável permanente, deve-se acrescentar a definição e o comando export no arquivo .bash_profile (no caso de shell bash).

Para excluir uma variável de ambiente, deve-se usar o comando unset. Por exemplo, o comando

unset teste
exclui a variável de ambiente teste criada no exemplo anterior.

Para alterar o valor de uma variável de ambiente, basta fornecer o nome da variável e o novo valor a ser atribuido a variável. Para a variável de ambiente TESTE definida anteriormente nesta seção, podemos digitar

TESTE=200
e a variável TESTE passa a ter valor 200. Neste caso, o conteúdo da variável é completamente alterado. Pode ser que ao invés de alterar o conteúdo, você queira apenas acrescentar mais alguma informação ao conteúdo armazenado em uma variável. Por exemplo, suponha que você queira acrescentar o diretório /teste/bin no caminho de busca, ou seja, no PATH. Devemos, então digitar
PATH=$PATH:/teste/bin
O símbolo $ usado acima antes de PATH informa ao shell para usar o conteúdo da variável de ambiente PATH.

Suponha agora que temos "USER=aluno" e que queremos "USER=aluno linux". Então podemos definir

USER="$USER Linux"
As aspas acima são necessárias devido ao espaço em branco existente no novo conteúdo da variável USER. Note que novamente usamos $ para indicar ao shell que se deve substituir o nome USER pelo conteúdo da variável ambiente USER.

Os exemplos mostrados acima são alterações temporárias no ambiente do usuário. Para tornar uma alteração efetiva, deve-se alterar o arquivo profile do usuário (.bash_profile no shell bash). Por exemplo, suponha que queremos personalizar o prompt das linhas de comando. Podemos então incluir no arquivo de profile

PS1="[\W]\$"
e
export PS1
onde o novo prompt apenas exibe o nome do diretório atual de trabalho do usuário (\W) e o símbolo $ (\$).

Consulte o manual on line para conhecer um pouco mais sobre os comandos embutidos no seu shell (por exemplo, "man bash" para ler sobre o script bash).

Usando as variáveis de ambiente em um programa C

O terceiro argumento da função main() é a lista de variáveis de ambiente. Em um programa C, pode-se usar a função putenv() para criar/alterar variáveis de ambiente, a função getenv() para obter o valor das variáveis e a função unsetenv() para remover variáveis.

O exemplo mostrado a seguir exibe um dump das variáveis de ambiente e de algumas funções de C, antes e depois, que algumas modificações são introduzidas no ambiente do sistema.

1. #include<stdio.h>
2. #include<stdlib.h>
3. #include<unistd.h>
4. #include<string.h>
5. #include<errno.h>
6. void imprime_variavel(const char *desc, const void *addr)
7. {
8.    printf("0x%08lX %-s\n", (long)addr, desc);
9. }
10. void dump(char * const envp[], const char *cabecalho)
11. {
12.    int x; /* índice envp[x] */
13.    /* Exibe um título */
14.    printf("\n%s\n\n", cabecalho);
15.
16.    /* Exibe as variáveis de ambiente */
17.    for (x = 0; envp[x] != 0; ++x)
18.    {
19.       imprime_variavel(envp[x], envp+x); /* imprime variável */
20.    }
21.    /* Exibe outras variáveis */
22.    imprime_variavel("stderr",stderr);/* Dump do endereço de stderr */
23.    imprime_variavel("stdout",stdout);/* Dump do endereço de stdout */
24.    imprime_variavel("stdin", stdin); /* Dump do endereço de stdin */
25.    imprime_variavel("dump", dump); /* Dump do endereço de main */
26. }
27. int main(int argc, char * const argv[], char * const envp[])
28. {
29.    /* Faz dump das variáveis de ambiente */
30.    dump(envp, "AMBIENTE INICIAL:");
31.    /* inclui duas novas variáveis de ambiente */
32.    if (putenv("TESTE1=100") == -1)
33.    {
34.       printf("%s: putenv()\n", strerror(errno));
35.       exit(1);
36.    }
37.    if (putenv("TESTE2=teste de variaveis") == -1)
38.    {
39.       printf("%s: putenv()\n", strerror(errno));
40.       exit(2);
41.    }
42.    /* altera valor da variável de ambiente LOGNAME */
43.    if (putenv("LOGNAME=linux") == -1)
44.    {
45.       printf("%s: putenv()\n", strerror(errno));
46.       exit(3);
47.    }
48.    /* Faz dump das variáveis de ambiente */
49.    dump(envp, "AMBIENTE Modificado:");
50.    /* Verifica o valor de LOGNAME, TESTE1 e TESTE2 */
51.    printf("\ngetenv(LOGNAME) = %s;", getenv("LOGNAME"));
52.    printf("\ngetenv(TESTE1) = %s;", getenv("TESTE1"));
53.    printf("\ngetenv(TESTE2) = %s;\n", getenv("TESTE2"));
54.    return 0;
55. }

Uma observação interessante em relação ao programa acima diz respeito ao parâmetro envp[] antes e depois da alteração da variável LOGNAME e da inclusão das variáveis TESTE1 e TESTE2: o vetor envp[] não se altera. Isto significa que as alterações introduzidas pelo programa no ambiente são feitas em outra área de memória e monitoradas pelo sistema enquanto o programa está sendo executado. Não é possível alterar as variáveis de ambiente do shell pois as variáveis do shell são definidas na própria memória privada do shell.

Alteração do shell

É possível mudar de shell em tempo de execução. Para isto, basta digitar o nome do novo shell na linha de comandos. Para encerrar o novo shell e voltar para o shell anterior basta digitar exit.

Para ver quais os shells que estão disponíveis no sistema, basta verificar o conteúdo do arquivo /etc/shells.

Para mudar o shell padrão, o usuário pode usar o comando chsh (change shell). Suponha, por exemplo, que queremos adotar como padrão o shell ash, então podemos digitar

chsh -s /bin/ash

O Linux apenas pedirá a senha do usuário logado para confirmar a alteração. Na próxima vez que o usuário logar no sistema, o ash será o seu shell padrão. O uso do comando chsh, sem parâmetros, fará com que, além da senha, o Linux também solicite o nome do novo shell. Neste caso, deve-se fornecer o caminho completo do novo shell.

É também importante observar que quando uma nova sessão é aberta com o comando bash, apenas os arquivos /etc/bash e ~/.bashrc são lidos. Nestes arquivos são colocados os comandos que devem continuar existindo na nova sessão como, por exemplo, os aliases.

Programação em shell script

Como vimos acima, o shell funciona como mediador entre o usuário e o kernel do sistema. Quando o usuário digita um comando, o shell analisa o comando e solicita ao kernel a execução das ações correspondentes ao comando em questão.

Normalmente, o usuário (principalmente se ele é o administrador do sistema) executa um mesmo conjunto de tarefas diariamente. O ideal então é que o usuário possa automatizar as suas tarefas, ou seja, o usuário digita um único comando e o shell o interpreta como um conjunto de comandos a serem executados pelo sistema. Este tipo de automatização de tarefas é possível através da programação shell.

Abaixo são mostrados alguns exemplos de scripts.

Operações aritméticas

Existem várias formas de executar uma operação aritmética no shell.

Mais exemplos

Observações

  Topo   |   Guia   |   Home