shellScript
shellScript
Campo Mourão
2024
Sumário
1 Introdução 1
3 Condicionais 16
3.1 Verificações de strings, números e arquivos . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1.1 Comando test e [ .. ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2 Condicional com if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.2.1 if e else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2.2 Mais condições elif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2.3 case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.3 Operadores aritméticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.4 Diferença entre [ .. ] e [[ .. ]] . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4 Laços de repetição 33
4.1 Repetição com for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.2 continue e break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.3 Repetição com while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
i
Básico do básico de Shell Script 2024
5 Funções 40
5.1 Passagem de parâmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.1.1 Variável global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.1.2 Variável local . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.2 Retorno de funções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.2.1 Retorno do resultado da execução da função . . . . . . . . . . . . . . . . . . 45
5.2.2 Utilizando o return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.2.3 Retornando valor numérico . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.2.4 Utilizando echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.2.5 Utilizando variáveis para retornar strings . . . . . . . . . . . . . . . . . . . . . 48
5.2.6 Passando múltiplas strings utilizando vetor . . . . . . . . . . . . . . . . . . . 49
6 Conclusão 51
7 Bibliografia 52
Shell Script é uma linguagem de programação interpretada utilizada normalmente para automatizar
tarefas em sistemas operacionais, principalmente os baseados em Unix, tais como Linux, FreeBSD,
entre outros. Shell Script combina comandos normalmente utilizados nos sistemas operacionais
com comandos e sintaxes de programação disponíveis em shells, tais como bash, sh, zsh, etc. Os
programas desenvolvidos a partir dos recursos oferecidos por esses shells são chamados de scripts,
que podem ser executados para realizar desde operações simples, como manipulação de arquivos, até
tarefas mais complexas, como o gerenciamento de múltiplos servidores de rede.
É claro que a programação em shell script possui certas desvantagens, tais como: não são
desenvolvidos pensando em performance ou estrutura de dados complexas, já que são voltados
para tarefas administrativas e não para computação de alta performance. Além disso, pode ser
difícil depurar erros em scripts, e scripts mal escritos podem trazer problemas de segurança, como
vulnerabilidades ou execução de comandos que podem danificar o computador. Todavia, é certo que
o uso de shell script traz mais benefícios do que malefícios quando bem desenvolvido e empregado da
forma correta por um bom administrador de sistemas.
Assim, shell script é uma ferramenta poderosa para quem trabalha com sistemas UNIX-like,
especialmente em tarefas administrativas que precisam ser automatizadas. Esses scripts ajudam
a simplificar tarefas diárias, economizando tempo e esforço, sendo especialmente úteis para
administradores de sistemas que desejam utilizar sua criatividade para facilitar e agilizar suas tarefas,
tornando-as mais rápidas, seguras e profissionais.
Desta forma, antes de prosseguir é necessário saber que shell script vem de duas palavras, sendo:
1
Básico do básico de Shell Script 2024
• Shell - é o interpretador de comandos que atua como interface entre o usuário e o sistema
operacional. Asim, o shell permite que o usuário insira comandos, que são interpretados
e executados pelo sistema. Ou seja, um shell é um ambiente texto (não gráfico), no qual
principalmente o administrador do sistema utiliza para realizar tarefas simples como cópias de
arquivos (que pode ser considerada uma tarefa de usuário não administrador) ou para alterar
a senha de outro usuário do sistema (o que é considerada uma tarefa administrativa). Exitem
vários tipos de shell, tais como: Bash (Bourne Again Shell), Zsh (Z Shell), Ksh (KornShell), Csh (C
Shell) e Sh (Bourne Shell), cada um possui suas vantagens e desvantagens, mas o mais comum é
encontrar o Bash nos sistemas por ai, principalmente os Linux.
Portanto, shell scripts são arquivos textos que contém comandos e instruções (scripts), que ao
serem executadas são interpretadas por algum shell, para realizar alguma tarefa dentro de sistemas
computacionais.
• Um sistema UNIX-Like, tal como o Linux, por exemplo o Ubuntu ou Manjaro. Esses terão
basicamente todas as ferramentas necessárias para criar shell scripts;
• Dentro do Linux precisamos das seguintes ferramentas:
– Um console texto - que é um ambiente fornecido pelo sistema operacional que é o próprio
shell, provavelmente terá como o Bash, como shell padrão. Isso pode ser conseguido
executando no ambiente gráfico algum console/terminal como o xterm, konsole,
xfce4-terminal, etc, ou acessando algum terminal texto puro com um Ctrl+Alt+F3
(ou qualquer um dos Fs - deve ser possível voltar para o gráfico com um Ctrl+Alt+F7).
– Um editor de texto, tais como:
* Algum editor de texto, via console, tais como: vim, nano, etc;
* Editor de texto gráfico simples, tais como: como o gedit, kate, etc. Atenção, não é
recomendável utilizar editores de texto no estilo LibreOffice ou Microsoft Office.
Sabendo do mínimo necessário para executar shell script, a seguir são apresentados os principais
comandos e estruturas utilizados em shell script. É importante destacar que o objetivo deste texto
não é explorar em profundidade todos os aspectos relacionados com shell script, nem abordar
detalhadamente os comandos UNIX, utilizados nos exemplos (para isso procure livros como os
citados na bibliografia). Desta forma, este material é destinado à alunos de Ciência da Computação,
profissionais de informática e entusiastas que já possuem conhecimento prévio em administração
Então para iniciar no mundo dos shell scripts vamos começar pelo famoso “Olá mundo!”, ou seja,
vamos criar um programa que escreva na terminal do computador uma frase. Isso parece e é bem
básico, mas conseguir isso significa que o ambiente de programação está funcionando.
Para fazer o sript do “ola mundo”, precisamos primeiro iniciar um terminal com um shell, neste caso
e em todos os exemplos utilizaremos o Bash. Então dentro do terminal vamos executar o editor de
textos
1 $ vi hello.sh
No comando anterior, estamos utilizando o editor de textos vi para criar um arquivo chamado hello
.sh.
Se você vai utilizar o ambiente gráfico, abra o seu editor gráfico favorito, tal como o Kate
ò do KDE ou o gedit do Gnome - só lembre de não usar editores no estilo LibreOffice, pois
esses sujam o código e vão causar erros. Outra prática para para estudos é criar uma
pasta/diretório para manter todos os scripts que vamos testar aqui.
Bem, dentro do editor de textos vamos editar o arquivo hello.sh e deixa-lo com o seguinte
conteúdo:
1 #!/bin/bash
2
3 echo "Olá mundo!"
4
5 exit 0
4
Básico do básico de Shell Script 2024
• #!/bin/bash - esse é o shebang, que indica qual deve ser o interpretador utilizado, neste caso
vamos utilizar o bash, e /bin/bash é o caminho absoluto para o executável do interpretador.
Este é opcional, mas recomendado, caso contrário o interpretador vai ser o shell que vai executar
o script, caso o arquivo tenha permissão de execução.
• echo "Olámundo!" - é o comando que vamos executar, neste caso é o echo que mostra na
tela o que estiver entre as aspas, neste caso “Olá mundo”.
• exit 0 - por fim, há o comando exit que com o valor 0 (zero), indica que o programa terminou
normalmente. Este é opcional, mas é recomendado.
Então, com o primeiro script pronto, vamos executá-lo, isso pode ser feito de várias formas tais como:
1 $ bash hello.sh
2 Olá mundo!
Quando se passa o interpretador, existe a certeza que o script foi executado com o interpretador correto.
Está técnica é boa para quem só está realizando testes e não vai executar tal arquivo com frequência,
também se esse for o caso, não precisa colocar o shebang no script, pois o interpretador já é passado
via linha de comando.
Para executar o arquivo direto, sem precisar passar o interpretador (no caso o shell), é necessário
tornar o arquivo um executável com o comando chmod a+x <nomeAquivo>. Isso é feito apenas
uma vez, e depois disso basta executar o script diretamente.
Só é preciso executar o comando chmod uma única vez, depois disso é só preciso digitar
ò o nome do script.
Neste método de execução direta do script, torna o script mais profissional, pois facilita a sua execução.
Todavia utilizando este método é altamente recomendável que o script tenha o shebang, para indicar
qual é o interpretador esperado para tal script, caso contrário o script será executado com o shell do
terminal corrente.
Note também que no exemplo anterior, o script foi executado com ./, lembrando que o ., representa
o diretório atual, então tal prática que seja executado outro arquivo executável que não o script em
questão. Também dá para executar o script utilizando o caminho absoluto, ou verificar se não há outro
executável com o mesmo nome do arquivo do script, ai seria possível chamar apenas pelo nome do
script, sem medo de haver duplicidades. O script não precisa ter extensão, mas aqui estamos utilizando
o .sh, para indicar que é um script.
Ao se tornar o script um executável ele se torna um comando. Tal comando pode ser
ò acessível inicialmente somente dentro do diretório no qual ele se encontra, mas é
possível torná-lo acessível para todo o sistema, como por exemplo, copiando ou criando
um link dele para um diretório como o /bin, ou colocando o diretório no qual ele se
encontra no $PATH do sistema.
Feito o “Olá mundo!”, agora sabemos que o ambiente está funcionando, então vamos expandir o script
passando algum argumento para ele. Um argumento é um valor passado via linha de comando, ou
seja, quando se está digitando o comando que representa o script e isso é muito útil no dia a dia. Desta
forma já existem algumas variáveis especiais em shell script para tratar a passagem de parâmetros,
tais como:
Essas variáveis também valem para funções de shell script, que serão abordadas
ò posteriormente.
A seguir são apresentados exemplo do uso de argumentos em scripts e dessas variáveis especiais dos
shells.
Para o primeiro exemplo vamos pegar o primeiro argumento passado via linha de comando e apresentá-
lo na saída do “Olá mundo”, veja o conteúdo do script:
1 #!/bin/bash
2
3 echo "Olá mundo $1!"
4
5 exit 0
Observe que no final do comando echo há o $1, esse representa o primeiro argumento passado para
o script.
Como padrão de escrita no texto, o nome do arquivo que representa o script sempre
ò estará na saída seguinte, na execução deste arquivo. Então caso você esteja seguindo os
nomes dos scripts apresentados aqui, sempre olhe a saída (que vem depois do conteúdo
do script), e veja o nome utilizado no arquivo do script. Esse será o padrão em todo esse
texto.
Agora quando vamos executar o script, que chama ./hello.sh também vamos passar algum
texto/número para ele, tal como:
1 $ ./hello.sh luiz
2 Olá mundo luiz!
Todos estas variáveis são apresentadas pelo comando echo somadas a textos autoexplicativos. Veja o
script:
1 #!/bin/bash
2
3 echo "Olá mundo do script $0"
4 echo "Seja bem vindo $1"
5 echo "Você passou $# argumentos, sendo esses: $*"
6
7 exit 0
Para executar tal script vamos executar o seguinte comando: ./hello.sh luiz da aula de
administração, tal como:
Ou seja, no comando anterior, ./hello.sh é o script, luiz é o primeiro argumento e foram passados
5 argumentos ao total, sendo esses luiz da aula de administração.
Se for necessário acessar argumentos acima da posição 9, será necessária utilizar chaves,
- por exemplo para acessar o décimo argumento seria necessário utilizar ${10}, ou vigésimo
primeiro seria ${21}, etc.
Shell scripts são conhecidos por não serem muito fáceis de depurar erros, ou seja, em algum momento
algum comando pode ser digitado errado dentro do script ou alguma sintaxe pode estar errada. Neste
caso ao se executar o script será retornado um erro, normalmente apontando onde está o possível
erro no script (apontando a linha do erro, por exemplo). Vamos alterar o script anterior, para que ele
tenha um erro, veja:
1 #!/bin/bash
2
3 echo "Olá mundo do script $0"
4 echo "Seja bem vindo $1
1 $ ./hello.sh
2 Olá
3 ./hello.sh: linha 5: encontrado EOF inesperado enquanto procurava por
`"' correspondente
Observe a saída anterior, note que ela aponta um erro na linha 5, ou seja, a linha 5 do script deve ter
algo errado. Então é preciso abrir o script com um editor de textos e verificar o que pode ser, neste
caso o interpretador aponta o erro na linha 5 e aponta também que deve ser um problemas com aspas,
entretanto a falta de aspas ocorre na linha 4 - analise o código! É claro que nem sempre a identificação
de erros é tão simples quanto as aspas que estão faltando, como neste caso, principalmente no caso
de shell script que pode ser um erro de um comando externo, então o programador deve analisar
atentamente para ver se é um erro com o comando ou com a construção do script.
As vezes o problema será apontado em uma linha, mas pode estar em outra, então é
- preciso analisar com calma para tentar solucionar o mistério.
Para ajudar um pouco na depuração de erros em shell script, é possível utilizar a opção -v ou -x,
sendo que o resultado de ambas são basicamente a mesma coisa, mas no -x há uma marcação de +
para o comando, tal como:
No exemplo anterior não há erros, mas é interessante executar o script assim, para ver a ordem de
execução e a saída de cada instrução do script.
É bem comum utilizar do comando echo para gerar saídas e verificar onde pode estar
ò o erro no script, também uma prática bem comum é mostrar os valores de variáveis
utilizando echo para investigar erros.
Ainda com bash é possível utilizar a opção -e, que vai parar no primeiro erro, então caso exista mais
de um erro, a execução vai apontar apenas o primeiro. Assim, por exemplo, é possível ir resolvendo
erro, por erro, o que pode ser mais fácil do que ver/analisar vários erros em uma única saída.
Também é possível enviar os erros para arquivos de log, utilizando por exemplo o redirecionamento
2>. Além do que há ferramentas externas como a shellcheck, que podem ajudar na depuração de
erros.
É importante utilizar as aspas corretamente durante a criação de scripts, pois o uso de aspas de forma
incorreta pode gerar resultados inesperados e muitas vezes errados. Assim, é necessário lembrar que
há diferenças no uso das aspas com comandos de saída tal como o echo.
• Aspas simples ('): Usadas em textos literais, sendo que tudo dentro delas é interpretado
exatamente como está, sem interpretações de variáveis ou caracteres especiais;
• Aspas duplas (""): Usadas quando é necessário a interpretação de variáveis e caracteres
especiais;
• Crase (`): Usada para executar comandos e capturar a saída. Atualmente a recomendação é
utilizar $(comando) e não `comando`.
O exemplo a seguir mostra em um único código todos os tipos de uso de aspas em shell script:
1 #!/bin/bash
2
3 echo "O usuário $USER está executando o comando $0"
4
5 echo 'O usuário $USER está executando o comando $0'
6
7 echo "O usuário $USER está executando o comando \$0"
8
9 echo "Estamos em `date`"
1 $ ./aspas.sh
2 O usuário luiz está executando o comando ./aspas.sh
3 O usuário $USER está executando o comando $0
4 O usuário luiz está executando o comando $0
5 Estamos em qui 28 nov 2024 09:32:56 -03
Note que quando utilizadas aspas duplas as variáveis são substituídas por seus respectivos valores, se
for necessário apresentar por exemplo o $0, ao invés do valor da variável, é necessário colocar o \
antes de $0, assim fica \$0
Já utilizando aspas simples, tudo é interpretado como está, ou seja, as variáveis não são substituídas
por valores.
Quando se utiliza crase, é executado o comando e esse é inserido/retornado para quem chamou.
Uma tarefa muito comum em programação é obter dados digitados pelo usuário via teclado, em shell
script há por exemplo as seguintes formas de se fazer isso:
– entrada=$(cat) - neste exemplo será executado o comando cat que espera o usuário
digitar algo, ao final o usuário pressiona Ctrl+D, e o que foi digitado vai parar na variável
entrada.
– entrada2=$(</dev/stdin) - nesta realmente pega-se a entrada do teclado (/dev/
sdtin) e se repassa para a variável entrada2.
• Comando readarray - similar ao comando read, mas tudo que for digitado será armazenado
em um vetor.
A seguir são apresentados alguns exemplos sripts que obtém entradas do teclado:
O comando read tem várias opções as mais comuns são apresentadas na tabela a seguir:
Vamos iniciar com um exemplo simples que repassa o que foi digitado para o read para uma variável,
veja o script a seguir:
1 #!/bin/bash
2
3 echo "Qual é o seu nome?"
4 read nome
5 echo "Seja bem vindo $nome"
6 exit 0
1 $ bash teclado.sh
2 Qual é o seu nome?
3 luiz
4 Seja bem vindo luiz
No exemplo anterior, ao se questionar o nome do usuário, foi digitado “luiz”, tal valor foi apresentado
na mensagem seguinte (Seja bem vindo luiz).
A opção -p, mostra um texto de deve estar entre aspas. O exemplo a seguir é basicamente o mesmo do
anterior, mas com uma linha a menos, pois foi retirado um echo, já que o próprio read -p mostrou
mensagem que deveria ser exibida inicialmente.
• Código de exemplo:
1 #!/bin/bash
2
3 read -p "Qual é o seu nome? " nome
4 echo "Seja bem vindo $nome"
5 exit 0
1 $ bash teclado.sh
2 Qual é o seu nome? luiz
3 Seja bem vindo luiz
A opção -n seguida de um número inteiro determina a quantidade de valores que serão aceitos pelo
teclado, no caso -n1, espera que o usuário digite um único valor. Também é possível utilizar a opção
-s, que não apresenta o que foi digitado, isso é muito útil para senhas.
1 $ cat teclado.sh
2 #!/bin/bash
3
4 read -s -n 5 -p "digite um segredo de cinco letras: " segredo
5 echo -e "\nSegredo digitado foi: $segredo"
6 exit 0
1 $ bash teclado.sh
2 digite um segredo de cinco letras:
3 Segredo digitado foi: senha
Na saída anterior, o usuário digitou o segredo como sendo senha, então essa foi apresentada pelo
echo.
Se no comando read não for passada nenhuma variável, ainda assim é possível ler o
ò que foi digitado, por essa é armazenada na variável $REPLY.
Também é possível passar a entrada do comando read para mais de uma variável, tal como:
1 $ cat teclado.sh
2 #!/bin/bash
3
4 read -t 5 -p "Digiete duas palavras em apenas 5 segundos: " palavra1
palavra2
5 echo -e "\nForam digitadas: \n\t1) $palavra1 \n\t2) $palavra2"
6 exit 0
1 $ bash teclado.sh
2 Digiete duas palavras em apenas 5 segundos: ola mundo
3
4 Foram digitadas:
5 1) ola
6 2) mundo
Nesta saída anterior, o usuário digitou e menos de 5 segundos (read -t 5), duas palavras e essas
foram armazenadas em palavra1 e palavra2 e posteriormente apresentadas na tela.
Se o usuário não digitar nada em 5 segundos, o script vai para a próxima instrução, após o read e
neste exemplo apresenta as variáveis em branco, devido à opção -t 5.
Em alguns casos pode ser útil armazenar o que o usuário digitou em um vetor, isso pode ser feito com
o comando read -a, e também pelo comando readarray. O script a seguir apresenta o uso do
comando readarray, e como acessar o vetor:
1 #!/bin/bash
2
3 echo "Digite uma frase: "
4 readarray vetor
5 echo -e "A primeira palavra digitada foi: ${vetor[0]} \nAs palavras
digitadas foram:\n${vetor[@]}"
6 exit 0
Ao executar o script será necessário o uso do Ctrl+D indicar que os valores do vetor já foram digitados,
veja a saída de exemplo a seguir:
1 $ bash teclado.sh
2 Digite uma frase:
3 ola
4 mundo
5 dos
6 vetores
7 A primeira palavra digitada foi: ola
8
9 As palavras digitadas foram:
10 ola
11 mundo
12 dos
13 vetores
Neste exemplo o que foi digitado foi armazenado no array chamado vetor, depois a primeira posição
foi acessado utilizando-se {vetor[0]} e o índice especial @, apresenta o valor de todas as posições.
Lembrando que o mesmo resultado seria obtido utilizando-se o comando read -a vetor.
Em ambientes de programação, é comum o uso de estruturas para avaliar condições, como o if. Essas
estruturas permitem tomar decisões com base no resultado da condição testada, alterando o fluxo de
execução do programa de maneira dinâmica.
Tais estruturas de condição também estão presentes em * shell scripts. Então, a seguir, serão
apresentados os métodos para criar testes condicionais em shell scripts*, proporcionando melhor
controle na execução das tarefas.
Assim, inicialmente serão apresentadas técnicas para realizar comparações com números, strings e
arquivos, depois como combinar tais comparações com estruturas de decisões, tal como o if.
• Comando test ou [ .. ].
• [[ .. ]], que é uma extensão do [ .. ] disponível em shells como o Bash e oferece mais
recursos.
• (( .. )), para testes de verificação numéricas e condições ariméticas.
• Usando comandos externos como grep, find, awk, etc.
• Operadores lógicos e redirecionamento, tal como &>, || e &&.
• Dentre outros.
É importante perceber que em shell script a comparação pode ser feita por comandos separados
das estruturas de decisão. Assim, os comandos mencionados anteriormente serão posteriormente
combinados com estruturas de decisões mais elaboradas como o if do shell script.
16
Básico do básico de Shell Script 2024
Por exemplo , o código a seguir verifica se o usuário digitou um parâmetro, caso não tenha digitado
a saída será apenas o primeiro echo, caso contrário o test -z $1 vai falhar e então é executado o
segundo echo.
1 $ cat hello3.sh
2
3 #!/bin/bash
4
5 echo "Você está utilizando $0"
6 test -z $1 || echo "Olá $1"
7 exit 0
1 $ ./hello3.sh
2
3 Você está utilizando ./hello3.sh
É importante saber que a estrutura de decisão do script em questão se dá pelo ||, que é um AND lógico,
que só executa o comando echo "Olá$1", caso o comando test -z $1, tenha sido executado
com sucesso. Como no primeiro exemplo não foi passado nenhum parâmetro, o comando test -z
retorna com uma falha então a execução da linha terminal ali. Já no seguindo teste, a seguir, é passado
um parâmetro, então é executado o segundo echo, veja a saída a seguir:
1 $ ./hello3.sh teste
2
3 Você está utilizando ./hello3.sh
4 Olá teste
O comando test também pode ser executado utilizando os [ .. ], ou seja o colchetes é a mesma
coisa que o comando test, assim o comando anterior test -z $1 || echo "Olá$1", poderia
ser escrito assim:
É importante perceber que há espaços entre os colchetes e o que está escrito dentro ou
- fora dele, caso contrário o interpretador não entenderá que o colchetes é o test. Ou
seja, o comando anterior estaria errado se fosse escrito assim: [test -z $1], sem
espaço.
Assim, o comando test e [ .. ] é muito utilizado em scripts. Quando o comando test é executado
sem nenhum parâmetro ele retorna falso. O test tem os seguintes operadores lógicos:
Operador Descrição
-a E lógico (AND).
-o OU lógico (OR).
! NÃO lógico (NOT), para inverter uma condição.
Ou seja, é possível fazer combinações entre ANDs, ORs, e negação em comparações com o comando
test ou [..]. Tais opções lógicas e opções de comparação de string, números e arquivos são
apresentadas nas seções seguintes. Todavia atualmente é mais recomendável utilizar os operadores
&& e ||, para AND e OR, respectivamente.
Opção Descrição
A seguir é apresentado um código de exemplo que utiliza essas opções para comparar strings, veja:
1 #!/bin/bash
2
3 var1="ola"
4 var2="mundo"
5
6 echo "Você deve ver sim 2, sim 4, sim 5, sim 6 e sim 8:"
7
8 # test é falso, então com o and, não será exibido o echo
9 test && echo "não 1"
10
11 # test negação do test, então será exibido o echo
12 test ! && echo "sim 2"
13
14 # var1 não é igual var2, então não será exibido o echo
15 test $var1 = $var2 && echo "não 3"
16
17 # var1 é igual ola, então será exibido o echo
18 test $var1 = ola && echo "sim 4"
19
20 # var1 é igual ola e (-a) var2 é igual a mundo, então será exibido o
echo
21 test $var1 = ola -a $var2 = mundo && echo "sim 5"
22
23 # var1 é igual ola e var2 é não igual a ola, mas é um or (-o), então
será exibido o echo
24 test $var1 = ola -o $var2 = ola && echo "sim 6"
25
26 # usando colchetes ao invés do test: var1 não é igual var2, então não
será exibido o echo
27 [ $var1 = $var2 ] && echo "não 7"
28
29 # usando colchetes ao invés do test: var1 não é igual var2, então será
exibido o echo devido a negação (!)
30 [ ! $var1 = $var2 ] && echo "sim 8"
A função de cada linha, ou seja, a comparação que ela está fazendo está comentada no
ò script. Assim, para comentar código em shell script utilizá-se um #, no inicio da linha.
No exemplo de código anterior, foram utilizados com o comando teste o &&, que é o AND do próprio
shell. Também daria para utilizar o ||, que é o OR do shell. Assim, no exemplo, a saída do echo só vai
aparecer na tela caso o teste retorne sucesso, ou seja, 1.
Ainda no exemplo anterior observe que é possível utilizar colchetes [..] ao invés do comando test,
também é possível utilizar -a e -o respectivamente para AND e OR lógico e ! para negação.
A seguir é apresentada a saída do script anterior, mas utilizando-se o bash -x para acompanhar a
execução de cada teste e sua saída:
1 $ bash -x ./test.sh
2 + var1=ola
3 + var2=mundo
4 + echo 'Você deve ver sim 2, sim 4, sim 5, sim 6 e sim 8:'
5 Você deve ver sim 2, sim 4, sim 5, sim 6 e sim 8:
6 + test
7 + test '!'
8 + echo 'sim 2'
9 sim 2
10 + test ola = mundo
11 + test ola = ola
12 + echo 'sim 4'
13 sim 4
14 + test ola = ola -a mundo = mundo
15 + echo 'sim 5'
16 sim 5
17 + test ola = ola -o mundo = ola
18 + echo 'sim 6'
19 sim 6
20 + '[' ola = mundo ']'
21 + '[' '!' ola = mundo ']'
22 + echo 'sim 8'
23 sim 8
O comando test, bem como o [..], também realiza comparação de números, para isso ele
disponibiliza várias opções, que são apresentadas na tabela a seguir:
O script a seguir, apresenta exemplos de uso das opções de comparação de números utilizando test
.
1 #!/bin/bash
2
3 var1=1
4 var2=2
5
6 echo "Você deve ver sim 1, sim 2, sim 3 e sim 4:"
7
8 # var1 é igual 1, será apresentado o echo
9 test $var1 -eq 1 && echo "sim 1"
10
11 # var1 é diferente de var2, será apresentado o echo
12 test $var1 -ne $var2 && echo "sim 2"
13
14 # var1 é menor que var2, será apresentado o echo
15 test $var1 -lt $var2 && echo "sim 3"
16
17 # var1 é menor igual que var2, será apresentado o echo
18 test $var1 -le $var2 && echo "sim 4"
19
20 # var1 é maior que var2, será não será apresentado o echo
21 test $var1 -gt $var2 && echo "não 5"
22
23 # var1 é maior igual que var2, será será apresentado o echo
24 test $var1 -ge $var2 && echo "não 6"
Também é possível utilizar o colchetes ao invés do comando test, tal como: [$var1
ò -ge $var2] && echo "não 6".
1 $ bash -x ./testNumeros.sh
2
3 + var1=1
4 + var2=2
5 + echo 'Você deve ver sim 1, sim 2, sim 3 e sim 4:'
6 Você deve ver sim 1, sim 2, sim 3 e sim 4:
7 + test 1 -eq 1
8 + echo 'sim 1'
9 sim 1
10 + test 1 -ne 2
11 + echo 'sim 2'
12 sim 2
13 + test 1 -lt 2
14 + echo 'sim 3'
15 sim 3
16 + test 1 -le 2
17 + echo 'sim 4'
18 sim 4
19 + test 1 -gt 2
20 + test 1 -ge 2
Como no exemplo com strings o código do script está todo comentado, isso ajuda a entender tal código
e é uma boa prática de programação.
É muito comum em que shell scripts realizem operações com arquivos e diretórios em sistemas. Então,
por exemplo, as vezes é necessário verificar se um dado arquivo ou diretório existe, antes de continuar
com alguma tarefa. Assim, o test fornece várias opções quanto a teste de arquivos, diretórios e links.
A tabela a seguir apresentas as opções de verificação de arquivos e diretórios do test.
-s Verifica se o arquivo tem tamanho maior que 0 (não Size greater than zero
vazio).
-L Verifica se o caminho é um link simbólico. Symbolic Link
-h Verifica se o caminho é um link simbólico (igual a -L). Hard/Symbolic Link
-p Verifica se o arquivo é um pipe nomeado (FIFO). Named Pipe
-b Verifica se o arquivo é um dispositivo de bloco. Block Device
-c Verifica se o arquivo é um dispositivo de caractere. Character Device
-u Verifica se o arquivo tem o bit setuid configurado. Set User ID
-g Verifica se o arquivo tem o bit setgid configurado. Set Group ID
-k Verifica se o arquivo tem o bit sticky configurado. Sticky Bit
-t Verifica se o descritor de arquivo refere-se a um Terminal
terminal.
A seguir é apresentado um script que faz uso das principais opções de verificação de arquivos/diretórios
do test:
1 #!/bin/bash
2
3 echo "Você deve ver sim 1, sim 2, sim 4 e sim 8:"
4
5 # /etc é um diretório, exibe a saída do echo
6 test -d /etc && echo "sim 1"
7
8 # /etc/hosts é um arquivo, exibe a saída do echo
9 test -f /etc/hosts && echo "sim 2"
10
11 # /etc/naoExiste existe como arquivo ou diretório, nao exibe a saída do
echo (pois não deve existir)
12 test -e /etc/naoExiste && echo "nao 3"
13
14 # /etc/hosts é possível ler, exibe a saída do echo
15 test -r /etc/hosts && echo "sim 4"
16
17 # /etc/hosts é possível escrever, não exibe a saída do echo (um usuário
normal não deve ter permissão de escrita neste arquivo)
18 test -w /etc/hosts && echo "não 5"
19
20 # /etc/hosts é possível executar, não exibe a saída do echo (não deve
ser possível executar esse arquivo)
Como nos exemplos anteriores o código está comentado e descreve o uso de cada uma das funções. O
resultado do script pode ser visto na saída a seguir:
1 $ ./testeArquivos.sh
2 Você deve ver sim 1, sim 2, sim 4 e sim 8:
3 sim 1
4 sim 2
5 sim 4
6 sim 8
Agora que foram apresentadas as formas de testar condições, vamos juntar isso com o if, que é uma
das principais estruturas de tomadas de decisão.
A ideia da estrutura do if em shell script é a mesma para basicamente qualquer linguagem de
programação ou seja: SE (if) alguma coisa for verdade, ENTÃO (then) faça algo. Toda a estrutura
termina com um fi. Então, a estrutura do if é:
1 if <condição> ; then
2 ...
3 fi
ou
1 if <condição>
2 then
3 ...
4 fi
É importante observar nos exemplo da estrutura do if, apresentado anteriormente, que if, then
e fi, são comandos, e por isso devem ser executados de forma separada (um em cada linha), ou
utilizando-se ; para indicar o final de um comando na mesma linha, por isso que no primeiro exemplo
temos: if <condição> ; then.
O exemplo a seguir mostra o uso da estrutura do ifpara verificar se o nome de usuário informado via
read é igual ao nome do usuário logado no sistema. Veja o código a seguir:
• Código:
1 #!/bin/bash
2
3 read -p "Qual é o seu primeiro nome? " nome
4 if [ $nome = $USER ] ; then
5 echo "Bem vindo $USER"
6 exit 0
7 fi
8 echo "$nome não corresponde com o usuário $USER"
9 exit 1
• Exemplo de saída:
1 $ bash nomeUsuario.sh
2 Qual é o seu primeiro nome? luiz
3 Bem vindo luiz
4
5 $ bash nomeUsuario.sh
6 Qual é o seu primeiro nome? raul
7 raul não corresponde com o usuário luiz
3.2.1 if e else
Outra estrutura complementar ao if é o else, que representa o SENÃO, ou seja, se a condição inicial
não for atendida, será executada as instruções que estão dentro do bloco do else e não do then.
Assim, a estrutura com if, then e else fica da seguinte forma:
1 if <condição>; then
2 ...
3 else
4 ...
5 fi
1 #!/bin/bash
2
3 read -p "Qual é o seu primeiro nome? " nome
4 if [ $nome = $USER ] ; then
5 echo "Bem vindo $USER, o seu nome corresponde com o usuário logado
atualmente."
6 else
7 echo -e "Você não é o $USER, mas seja vindo $nome!"
8 fi
9 echo "Tchau $nome..."
10 exit 0
Então o script anterior, pergunta o nome de quem está no terminal via read, depois compara com o
nome do usuário do Linux, se (if e then) for igual apresentar uma mensagem dizendo que ele é o
usuário logado atualmente, caso contrário (else), ele diz que o nome dado não é igual ao do usuário
do sistema.
As saídas a seguir apresentam a execução do script, primeiro passando pelo then depois passando
pelo else, veja:
1 $ bash nomeUsuario2.sh
2 Qual é o seu primeiro nome? luiz
3 Bem vindo luiz, o seu nome corresponde com o usuário logado atualmente.
4 Tchau luiz...
1 $ bash nomeUsuario2.sh
2 Qual é o seu primeiro nome? samuel
3 Você não é o luiz, mas seja vindo samuel!
4 Tchau samuel...
O comando if do shell tem outro comando que é o elif, tal comando premite realizar outras
comparações dentro do if, ou seja, não fica restrito ao se uma expressão for verdadeira executa
o bloco do then e caso contrário executa o else. Permitindo uma gama de comparações maiores. A
seguir é apresentada a estrutura do elif:
1 if <condição>; then
2 ...
3 elif <condição>; then
4 ...
5 else
6 ...
7 fi
O exemplo a seguir apresenta um código que pergunta o nome de quem está executando o script e
caso a pessoa não digite o seu nome, ele para a execução do programa com o exit que está dentro
do bloco do primeiro then. Já caso o usuário digite algo, isso é comparado no elif, que ai segue o
fluxo do exemplo anterior.
1 #!/bin/bash
2
3 read -p "Qual é o seu primeiro nome? " nome
4 if [ -z $nome ] ; then
5 echo "você deveria ter digitado algo"
6 exit 1
7 elif [ $nome = $USER ] ; then
8 echo "Bem vindo $USER, o seu nome corresponde com o usuário logado
atualmente."
9 else
10 echo -e "Você não é o $USER, mas seja vindo $nome!"
11 fi
12 echo "Tchau $nome..."
13 exit 0
1 $ bash nomeUsuario3.sh
2 Qual é o seu primeiro nome?
3 você deveria ter digitado algo
4
5 $ bash nomeUsuario3.sh
6 Qual é o seu primeiro nome? luiz
7 Bem vindo luiz, o seu nome corresponde com o usuário logado atualmente.
8 Tchau luiz...
9
10 $ bash nomeUsuario3.sh
11 Qual é o seu primeiro nome? arthur
12 Você não é o luiz, mas seja vindo arthur!
13 Tchau arthur...
No exemplo anterior, na primeira execução não é digitado nada para o read, na segunda é passado
um nome que corresponde ao usuário do sistema e na última é digitado um nome diferente do usuário
atual do sistema.
3.2.3 case
Outra estrutura condicional muito utilizada em programação é o case, essa por exemplo é
frequentemente empregadas em menus de sistema, permitindo que o usuário escolha entre várias
opções no sistema. A sintaxe do case basicamente consistem em comparar qual dentre as várias
possibilidades foram escolhidas pelo usuário, inclusive permitindo não escolher nenhuma das
esperadas. Veja a sintaxe do case:
1 case <expressão> in
2 <padrão1>)
3 ...
4 ;;
5 <padrão2>)
6 ...
7 ;;
8 * )
9 ...
10 ;;
11 esac
Nesta estrutura a <expressão> é o que vai ser comparado, na sequência vem com o que será
comparado (<padrão1>, <padrão2>, etc - é possível criar várias combinações) e é possível criar
um bloco de execução caso o que está sendo comparado não combine com nenhum dos padrões pré-
programados, isso é feito com o * ). É importante notar que cada bloco de execução deve terminar
com ;;. Por fim, o case espera terminar com o comando esac.
O exemplo a seguir, espera que o primeiro parâmetro passado via linha de comando para o script, seja
comparado com o case. Assim, caso o usuário digite ola, será apresentado na tela Ola mundo; se o
usuário digitar mundo, será apresentado mundo cruel; e se o usuário digitar qualquer outra coisa
será apresentada uma mensagem informando o que ele deveria digitar o comando com a palavra ola
ou mundo. Veja o código a seguir e o exemplo de saída da execução deste script:
• Código de exemplo:
1 #!/bin/bash
2
3 case $1 in
4 ola)
5 echo "Ola mundo"
6 ;;
7 mundo)
8 echo "mundo cruel"
9 ;;
10 *)
11 echo "Você deve digitar $0 ola ou $0 mundo"
12 esac
• Exemplo de saída:
1 $ ./case.sh
2 Você deve digitar ./case.sh ola ou ./case.sh mundo
3
4 $ ./case.sh ola
5 Ola mundo
6
7 $ ./case.sh mundo
8 mundo cruel
Os operadores aritméticos podem ser utilizados com os comandos let ou entre dois parenteses,
tal como (( .. )) e $(( .. )), sendo que a diferença entre as duas últimas é que (( . .))
não gera saída e é uma atribuição direta, enquanto $(( .. )) gera saída e pode ser utilizada em
substituições.
1 #!/bin/bash
2
3 num=1
4
5 # Atribuição (=)
6 echo "num=$num"
7
8 # num recebe o próprio num mais 1
9 num=$((num+1))
10 echo "num=$num"
11
12 # Num recebe 2+2
13 let num=2+2
14 echo "num=$num"
15
16 #num recebe o próprio num mais 1
17 num=$((num++))
18 echo "num=$num"
19
20 #num recebe o próprio num menos 1
21 num=$((num--))
22 echo "num=$num"
23
24 #num é menor que 1?
25 ((num < 1)) && echo "num é menor que 1"
26
27 #num é maior igual 1?
28 ((num >= 1)) && echo "num é maior igual que 1"
1 $ bash -v contas.sh
2 #!/bin/bash
3
4 num=1
5 echo "num=$num"
6 num=1
7
8 num=$((num+1))
9 echo "num=$num"
10 num=2
11
12 let num=2+2
13 echo "num=$num"
14 num=4
15
16 num=$((num++))
17 echo "num=$num"
18 num=4
19
20 num=$((num--))
21 echo "num=$num"
22 num=4
23
24 ((num < 1)) && echo "num é menor que 1"
25
26 ((num >= 1)) && echo "num é maior igual que 1"
27 num é maior igual que 1
Note que dá para usar $((..)), que deve ser utilizando quando se quer utilizar o resultado da
operação arimética. Já o ((..)) deve ser utilizado em expressões lógicas e retorna 0 para verdadeiro
e 1 para falso, ou quando se realiza operações ariméticas que não retornam saídas diretas.
• [ .. ] - esse funciona em qualquer shell script, ou seja é portável para qualquer shell
compatível com POSIX. Todavia possui algumas limitações tal como ser suscetível a erros em
strings vazias ou espaços e é mais complexo com parênteses extras;
• [[ .. ]] - esse só funciona basicamente no Bash e Zsh. Todavia é mais robusto e seguro
quanto a manipulação de strings, suporta operadores adicionais como expressões regulares e
permite o uso de operadores lógicos, como && e ||.
1 #!/bin/bash
2
3 var=teste
4
5 if [ "$var" = "teste" ]; then
6 echo "Comparando string utilizando [..]"
7 fi
8
9 if [[ $var == "teste" ]]; then
10 echo "Comparando string utilizando [[..]]"
11 fi
12
13 var2=ola
14
15 if [ "$var" = "teste" -a $var2 = "ola" ]; then
16 echo "Utilizando AND com [..]"
17 fi
18
19 if [[ $var == "teste" && $var2 == "ola" ]]; then
20 echo "Utilizando && com [[..]]"
21 fi
22
23 var3=1
24
25 if [[ $var3 =~ ^[0-9]+$ ]]; then
26 echo "Utilizando [[..]] com regex para ver se é número"
27 fi
28
29 if echo $var3 | grep -Eq '^[0-9]+$'; then
30 echo "Descobrindo se é número sem [[..]]"
31 fi
32
33 case $var3 in
34 [0-9]*)
35 echo "Descobrindo se é número com case"
36 ;;
37 esac
38
39 str="ola mundo"
40
41 if [[ $str == "ola mundo" ]]; then
42 echo "Comparação de string com espaço com [[..]]"
43 fi
44
45 if [ $str = "ola mundo" ]; then
46 echo "Comparação de string com espaço com [..]"
47 fi
1 $ bash colchetes.sh
É uma boa prática utilizar aspas ao redor de variáveis ou strings durante comparações,
- principalmente utilizando [..].
O uso de laços de repetição é muito comum em programas como é o caso de shell script, a seguir são
apresentados os principais métodos de loops em shell script:
Um dos laços de repetição mais utilizados em programação é o for, ele é utilizado para iterar sobre
um conjunto de itens, tal como valores, arquivos, resultados de comandos, etc, tudo utilizando uma
estrutura bem definida. Assim, ele é útil para automatizar tarefas repetitivas.
Então, como apresentado anteriormente, o laço inicia com o comando for, seguido de uma variável,
que receberá valores de uma lista a cada iteração do laço. O bloco de comandos a ser executado em
cada iteração deve ficar entre os comandos do e done.
1 #!/bin/bash
2
3 # Itera do 1 ao 5
4 echo "{1..5}"
5 for i in {1..5}; do
6 echo "i=$i"
7 done
8
9 # Apresenta na tela do 2 ao 10, pulando de dois em dois
10 echo -e "\n{2..10..2} - conta de 2 em 2"
11 for i in {2..10..2}; do
12 echo "i=$i"
13 done
14
15 # Utilizando o comando seq para gerar a lista a ser iterada pelo for
16 echo -e "\nUtilizando o seq, para quando não dá para usar {"
33
Básico do básico de Shell Script 2024
1 $ bash para.sh
2 {1..5}
3 i=1
4 i=2
5 i=3
6 i=4
7 i=5
8
9 {2..10..2} - conta de 2 em 2
10 i=2
11 i=4
12 i=6
13 i=8
14 i=10
15
16 Utilizando o seq, para quando não dá para usar {
17 i=1
18 i=2
19 i=3
20 i=4
21 i=5
22
23 Loop no estilo C
24 i=1
25 i=2
26 i=3
27 i=4
28 i=5
29
30 Interando em uma lista
31 Usuário: root
32 Usuário: bin
33 Usuário: daemon
34 Usuário: mail
35 Usuário: ftp
36
37 Loop infinito
38 loop infinito
39 loop infinito
40 loop infinito
41 ^C
A seguir é apresentado um exemplo mais prático de como utilizar o for para obter informações a
respeito do sistema:
1 #!/bin/bash
2
3 echo -e "Iterando em uma lista com os 5 primeiros usuários do sistema"
4 for user in $(head -n 5 /etc/passwd | cut -d: -f1); do
5 echo "Usuário: $user"
6 done
7
8
9 echo -e "\nIterando em uma lista todos arquivos que iniciam com host,
no diretório /etc"
10 for f in /etc/host*; do
11 file "$f"
12 done
13
14
15 echo -e "\nIterando em uma lista todos parâmetros passados via linha de
comando"
16 i=1
17 for p in $*; do
18 echo "Parâmetro $i é $p"
19 ((i++))
20 done
O script anterior apresenta três laços for, sendo a função de cada um:
É importante notar, que em shell script sempre serão utilizados comandos com as estruturas de
programação do shell, pois os comandos servirão como se fossem funcionalidades à linguagem
de programação que é o shell, tal como se fossem bibliotecas ou plugins, de outras linguagens de
programação. Assim é muito importante ter uma boa noção dos comandos do sistema e de suas
capacidades.
Os comandos continue e break podem ser utilizados junto com os blocos dos scripts, tais como os
blocos de loops, normalmente com estruturas de decisões, tal como o if.
O comando continue, executa o bloco de execução até o ponto que ele se encontra, ou seja, se
houver comandos/instruções a baixo do continue elas não serão executadas. Assim, caso o comando
continue estiver dentro de um laço de repetição, a execução volta para o inicio desse laço e recomeça
a partir dai.
Já o comando break, é utilizado para sair de dentro de um bloco de execução. Então, se o fluxo de
execução do bloco, tal como de um laço de repetição, encontrar o comando break ele vai sair fora do
laço de repetição.
A seguir é apresentado um script que ilustra o uso dos comandos break e continue, veja:
1 #!/bin/bash
2
3 echo "{1..5}"
4 for i in {1..5}; do
5 if [ "$i" -eq 3 ]; then
6 echo "Pulou"
7 continue
8 fi
9 if [ "$i" -eq 5 ]; then
10 echo "Parou..."
11 break
12 fi
13 echo "i=$i"
14 done
1 $ bash para2.sh
2 {1..10}
3 i=1
4 i=2
5 Pulou
6 i=4
7 Parou...
Ou seja, o script do exemplo anterior, entra em um laço de repetição que deve mostrar na tela o
incremento da variável i, e se não houvesse os comandos break e continue seriam apresentados
números indo de 1 até 5. Todavia, o script apresenta do 1 ao 2, pula o 3, pois executa o continue,
apresenta novamente o 4, e termina sem apresentar o 5, pois encontra o comando break.
1 while <condição>; do
2 ...
3 done
Como mostrado anteriormente o while tem a condição que será verificada, depois o bloco de
execução do laço inicia com o do e termina com o done. Veja um exemplo de uso do while:
1 #!/bin/bash
2
3 echo "Incremento com while 1"
4 i=0
5 while [ $i -lt 5 ]; do
6 echo "i=$i"
7 ((i++))
8 done
9
10
11 echo -e "\nDecremento com while 2"
12 i=5
13 while (( i >= 0 )); do
14 echo "i=$i"
15 (( i-- ))
16 done
17
18 echo -e "\nLendo o conteúdo de um arquivo"
19 while read linha; do
20 echo "$linha"
21 done < /etc/hosts
22
23 echo -e "\nLoop infinito com while"
24 while true
25 do
26 echo "Repete... Ctrl+C para cancelar"
27 sleep 2
28 done
É importante observar nos exemplos anteriores que em muitos desses exemplo de laços com o while,
que a variável teve que ser iniciada fora do laço de repetição (linha anterior ao while), pois como
mencionado anteriormente, o while não faz por padrão todo o controle do que está sendo iterado,
como faz o for.
Outro ponto a ser notado do script anterior, é que é possível passar para o while uma lista no final,
junto com o done e tal lista será iterada utilizando-se, por exemplo o comando read, isso é muito útil
para na utilização de arquivos em script, como foi feito no penúltimo exemplo do script.
1 $ bash enquanto.sh
2 Incremento com while 1
3 i=0
4 i=1
5 i=2
6 i=3
7 i=4
8
9 Decremento com while 2
10 i=5
11 i=4
12 i=3
13 i=2
14 i=1
15 i=0
16
17 Lendo o conteúdo de um arquivo
18 127.0.0.1 localhost
19 ::1 localhost
20 127.0.0.1 fielDell
21
22 Loop infinito com while
23 Repete... Ctrl+C para cancelar
24 Repete... Ctrl+C para cancelar
25 Repete... Ctrl+C para cancelar
26 ^C
1. Iterando i indo do 0 ao 5.
2. Decrementando o i do 5 ao 0.
3. Apresentando o conteúdo de um arquivo.
4. Loop infinito.
Funções são muito importantes no desenvolvimento de programas, desta forma essas também existem
em shell script, pois auxiliam na modularização e organização do código, facilitando sua organização e
manutenção.
ou
1 <nome da função>() {
2 ...
3 }
A seguir são apresentados um script, com duas funções, uma chamada ola, outra mundo. Tais funções
apenas apresentam mensagens na tela, veja:
1 function ola() {
2 echo "dentro da função ola()"
3 }
4
5 function mundo() {
6 echo "dentro da função mundo()"
7 }
8
9 echo "Inicio do script"
10 ola
11 mundo
12 echo "Final do script"
É importante notar que o script inicia em echo "Inicio do script", então é chamado ola,
que desvia a execução do script para function ola(), na sequência é chamado mundo, que por
sua vez desvia o fluxo de execução para function mundo(), por fim é executado o último echo.
Veja o fluxo de execução na saída a seguir:
1 $ bash -x funcoes.sh
2 + echo 'Inicio do script'
3 Inicio do script
4 + ola
40
Básico do básico de Shell Script 2024
É importante perceber que uma função em shell script é como se fosse um comando
- dentro do script, isso vale para como se chama a função, passagem de parâmetros e
retorno.
A passagem de parâmetros para função em shell script funciona como se fosse a passagem de parâmetro
para um comando ou script. Ou seja, é só passar os parâmetros na frente do nome da função e não é
necessário declarar tais parâmetros no cabeçalho da função. Para acessar os parâmetros dentro da
função é através das variáveis como se fosse passagem de parâmetros para o script, veja o exemplo a
seguir:
1 #!/bin/bash
2
3 comidas() {
4 echo "Sua comida favorita deve ser \"$1\", pois você colocou ela em
primeiro (\$1)"
5 echo "A função que você chamou foi \"$0\", isso é descoberto em \$0
"
6 echo "Você passou um total de \"$#\", tal valor pode ser obtido em
\$#"
7 echo "As comidas que você passou como parâmetro para $0, foram \"$
*\", isso pode ser visto em \$*"
8 }
9
10 echo "Inicio do script"
11
12 echo "Primeira vez que chamou a função comidas():"
13 comidas lasanha sushi
14
15 echo -e "\nSegunda vez que chamou a função comidas():"
16 comidas pudim bolo chocolate
17
18 echo "Final do script"
Note que no exemplo anterior, é criada a função comidas() - sim dá para criar a função sem utilizar
o comando function. Depois tal função é chamada duas vezes no script. Sendo na primeira vez da
seguinte forma: comidas lasanha sushi, sendo:
A segunda vez que a função comida é chamada são passados três parâmetros, sendo esses pudim
bolo chocolate, o total de parâmetros passado pode ser obtido pela variável $#.
Como dito anteriormente, uma função recebe parâmetros tal como são passados
ò parâmetros para um script, inclusive utilizando as mesmas variáveis do shell script.
1 $ bash funcoes3.sh
2 Inicio do script
3 Primeira vez que chamou a função comidas():
4 Sua comida favorita deve ser "lasanha", pois você colocou ela em
primeiro ($1)
5 A função que você chamou foi "funcoes3.sh", isso é descoberto em $0
6 Você passou um total de "2", tal valor pode ser obtido em $#
7 As comidas que você passou como parâmetro para funcoes3.sh, foram "
lasanha sushi", isso pode ser visto em $*
8
9 Segunda vez que chamou a função comidas():
10 Sua comida favorita deve ser "pudim", pois você colocou ela em primeiro
($1)
11 A função que você chamou foi "funcoes3.sh", isso é descoberto em $0
12 Você passou um total de "3", tal valor pode ser obtido em $#
13 As comidas que você passou como parâmetro para funcoes3.sh, foram "
pudim bolo chocolate", isso pode ser visto em $*
14 Final do script
O próximo script recebe dois números, soma esses números e apresenta o resultado
1 #!/bin/bash
2
3 function soma() {
4 resultado=$(($1+$2))
5 echo "O resultado de $1+$2 é $resultado"
6 }
7
8 echo "Inicio do script"
9
10 soma 1 2
11
12 echo "Final do script"
Outra forma de passar parâmetros em shell script é utilizando variáveis globais, ou seja, declarando
uma variável que o valor pode ser lido e alterado em qualquer parte do script.
O exemplo a seguir cria uma variável global chamada nome, que inicialmente recebe o valor
anonimo, posteriormente essa variável é alterada pela função getNome e depois utilizada na função
printNome, veja:
1 #!/bin/bash
2
3 nome="anonimo"
4
5 getNome() {
6 echo "Digite o seu nome, por favor:"
7 read nome
8 }
9
10 printNome() {
11 echo "Seja bem vindo $nome"
12 }
13
14 echo "Inicio do script"
15
16 getNome
17 printNome
18
19 echo "Final do script"
1 $ bash funcoes4.sh
2 Inicio do script
3 Digite o seu nome, por favor:
4 luiz
5 Seja bem vindo luiz
6 Final do script
Também existe variável local em shell script, variáveis locais não compartilham seu valor entre outros
função, tal como as variáveis globias.
No exemplo a seguir, há uma variável global chamada i, e na função chamada funcao1() é criada
uma variável local também chamada i, no contexto de variável local e global, quando se alterar o
valor de i, que está dentro de funcao1, não será alterado o valor da variável i global e o contrário
também.
1 #!/bin/bash
2
3 i=1
4
5 funcao1(){
6 local i=10;
7 echo "O valor de \"i\" local é $i"
8 }
9
10 echo "Inicio do script"
11
12 echo "O valor de \"i\" global é $i"
13 funcao1
14 echo "O valor de \"i\" global ainda é $i"
15
16 echo "Final do script"
1 $ bash funcoes5.sh
2 Inicio do script
3 O valor de "i" global é 1
4 O valor de "i" local é 10
5 O valor de "i" global ainda é 1
6 Final do script
Note que mesmo alterando o valor de i local, dentro da função, não foi alterado o valor de i global,
quando se retorna da função.
Em shell script existe o return, tal como em outras linguagens de programação. Todavia o return
em shell script é usado para indicar o status da execução e não para passar valores.
Se a função não utilizar o comando return ela retornará o status do último comando
- executado pela função.
Neste caso a função executa alguma dada tarefa, e se tudo correr bem ela retorna naturalmente que
foi executada com sucesso, ou seja, retorna zero (0). Também é possível verificar o status de retorno
da função através da variável $?. Caso exista algum erro, será retornado um valor diferente de zero,
que indica o tipo de erro.
• Código de Exemplo:
1 #!/bin/bash
2
3 verificaRoot(){
4 [ $(id -u) -eq 0 ]
5 }
6
7 echo "Inicio do script"
8
9 if verificaRoot; then
10 echo "Você é o root"
11 else
12 echo "Você não é o root"
13 fi
14
15 echo "Final do script"
No código anterior dentro da função temos [ $(id -u)-eq 0 ], que obtém a identificação do
usuário atual, e questiona se essa é igual a zero, ou seja, se o usuário é root. Caso sim, ela vai retornar
zero o que indica que ele é root, caso contrário vai retornar 1, que indica que ele não é o administrador.
Veja a saída a seguir.
• Saída:
1 $ bash funcoes6.sh
2 Inicio do script
3 Você não é o root
4 Final do script
5
6 $ sudo bash funcoes6.sh
7 Inicio do script
8 Você é o root
9 Final do script
Inicialmente foi executado o script com um usuário comum, na sequência foi executado com o sudo, o
que tornou o usuário root.
Tal como outras linguagens de programação, o shell script também possui o comando return, todavia
tal comando basicamente retorna 0 e 1, ou seja, 0 para sucesso e 1 para falha. A principio dá para
retornar valores numéricos entre 0 e 255, entretanto não é aconselhável utilizar isso para retornar
nada que não seja 0 e 1.
O código a seguir é similar ao anterior, mas verifica se o usuário está exatamente em seu diretório
home, caso esteja neste diretório, retornará 0. Caso contrário, retornará 1, indicando que não está em
seu diretório home. Note que neste caso, ele não pode nem estar dentro de um subdiretório dentro do
seu home, ou seja ele deve estar exatamente no seu diretório home.
• Código de exemplo:
1 #!/bin/bash
2
3 verificaHome(){
4 echo "`pwd` - $HOME"
5 if [ $(pwd) = $HOME ]; then
6 return 0
7 else
8 return 1
9 fi
10 }
11
12 echo "Inicio do script"
13
14 verificaHome && echo "Você está exatamente no seu diretório home" ||
echo "Você não está exatamente no seu diretório home"
15
16 echo "Final do script"
Neste código não foi utilizado if na parte principal do código, mas sim foi utilizado uma comparação
aninhada.
• Saída:
1 $ bash /home/luiz/scripts/funcoes7.sh
2 Inicio do script
3 /home/luiz/scripts - /home/luiz
4 Você não está exatamente no seu diretório home
5 Final do script
6
7 $ cd ..
8 $ bash /home/luiz/scripts/funcoes7.sh
9 Inicio do script
10 /home/luiz - /home/luiz
11 Você está exatamente no seu diretório home
12 Final do script
Na saída anterior primeiro foi executado o script fora do diretório home, depois ele foi executado
dentro do home. Note que para executar o código fora da onde está o script, foi passado o caminho
absoluto.
É importante lembrar para para o shell zero (0) é verdadeiro e um (1) é falso.
-
5.2.3 Retornando valor numérico
Há várias formas de se retornar valores em shell script, a seguir são apresentadas algumas.
Lembrando que o return no geral, não é para repassar dados complexos, então geralmente utilizá-se
o echo ou print para passar valores mais complexos. Também é possível fazer uso de variáveis,
como já foi apresentado anteriormente.
• Código de exemplo:
1 #!/bin/bash
2
3 getValor(){
4 read valor
5 echo $valor
6 }
7
8 echo "Inicio do script"
9
10 x=$(getValor)
11 if [ $x -eq 1 ]; then
12 echo "Valor igual à 1"
13 else
14 echo "Valor diferente de 1"
15 fi
16
17 echo "Final do script"
• Saída:
1 $ bash funcoes8.sh
2 Inicio do script
3 10
4 Valor diferente de 1
5 Final do script
6
7 $ bash funcoes8.sh
8 Inicio do script
9 1
10 Valor igual à 1
11 Final do script
O detalhe de utilizar echo é que a função não pode mostrar muito mais saídas do que o necessário,
caso contrário, quem chamou a função vai ter que ficar tratando/filtrando essas saída para chegar no
resultado, tal como ilustra o código a seguir:
• Código de exemplo:
1 #!/bin/bash
2
3 getTexto(){
4 echo "ola mundo"
5 echo "cruel"
6 }
7
8 echo "Inicio do script"
9
10 texto=$(getTexto)
11 echo "O texto passado foi: $texto"
12
13 echo "Final do script"
• Saída:
1 $ bash funcoes8.sh
2 Inicio do script
3 O texto passado foi: ola mundo
4 cruel
5 Final do script
Talvez uma das formas mais fáceis de retornar variáveis de uma função para outra seja utilizando
variáveis globais, tal como é apresentado a seguir.
• Código de exemplo:
1 #!/bin/bash
2
3 getTexto(){
• Saída:
1 $ bash funcoes9.sh
2 Inicio do script
3 ola mundo
4 O texto passado foi: cruel
5 Final do script
Se for necessário repassar vários valores simultâneos, uma boa alternativa é utilizar arrays, tal como o
exemplo a seguir.
• Código de exemplo:
1 #!/bin/bash
2
3 getTexto(){
4 vetor=("ola" "mundo" "cruel")
5 }
6
7 echo "Inicio do script"
8
9 getTexto
10 echo "Primeira palavra: ${vetor[0]}"
11 echo "Todas as palavras: ${vetor[@]}"
12
13 echo "Final do script"
• Saída:
1 $ bash funcoes10.sh
2 Inicio do script
3 Primeira palavra: ola
4 Todas as palavras: ola mundo cruel
5 Final do script
Também é possível utilizar arquivos para fazer retorno de valores, é muito comum utilizar
ò arquivos temporários para este tipo de tarefa, então uma função pode gravar o resultado
dentro de um arquivo e outra função pode ler tal resultado deste arquivo.
A programação em shell script pode facilitar muito o dia a dia do administrador de sistemas, pois é uma
linguagem de programação simples de utilizar, principalmente por fazer uso de comandos disponíveis
no próprio sistema operacional.
Desta forma, um bom administrador de sistemas deve saber o mínimo de comandos do sistema
e estruturas de shell scripts para automatizar tarefas repetitivas, economizando tempo e evitando
erros.
51
7 Bibliografia
• ANDREW MALLETT. Mastering Linux Shell Scripting. Birmingham: Packt Publishing, 2015.
Disponível em: https://research.ebsco.com/linkprocessor/plink?id=229fb515-ee69-3da8-b3f6-
3cc7c7b4b4ea. Acesso em: 23 out. 2023.
• VEDRAN DAKIC; JASMIN REDZEPAGIC. Linux Command Line and Shell Scripting Techniques :
Master Practical Aspects of the Linux Command Line and Then Use It As a Part of the Shell
Scripting Process. Birmingham: Packt Publishing, 2022. Disponível em: https://research.ebsco.c
om/linkprocessor/plink?id=63fb3fb5-6f67-395c-a786-99df7f179636. Acesso em: 3 out. 2024.
• MOKHTAR EBRAHIM; ANDREW MALLETT. Mastering Linux Shell Scripting, : A Practical Guide to
Linux Command-line, Bash Scripting, and Shell Programming. Birmingham: Packt Publishing,
2018. Disponível em: https://research.ebsco.com/linkprocessor/plink?id=445333d8-ec70-371f-
b587-37b350b1530d. Acesso em: 3 out. 2024.
52