Fundamentos de Shell Scripting - Variaveis, Condicionais, Loops, test

Fundamentos de Shell Scripting - Variaveis, Condicionais, Loops, test

O Que Voce Vai Conquistar

  • Explicar o papel do shebang (#!/bin/bash) e tornar um script executavel
  • Usar variaveis, parametros posicionais, parametros especiais e substituicao de comandos corretamente
  • Testar strings, numeros e arquivos com test / [ ] / [[ ]]
  • Escrever estruturas de controle com if / case / for / while / until
  • Escolher entre exit status e exit / && / ||, e funcoes de shell

Este e o nucleo do objetivo 105.2 do LPIC-1 "Personalizar ou escrever scripts simples" (LPIC 102). E a menor unidade de tecnica para automatizar operacoes diarias.

Qual e a Estrutura Basica de um Shell Script?

Um shell script consiste em "shebang -> definicoes de variaveis -> corpo do processamento". O shebang na primeira linha determina o interpretador, e uma vez concedida a permissao de execucao com chmod +x, voce pode executa-lo com ./script.sh.

Elemento Sintaxe Funcao
Shebang #!/bin/bash Especificar o interpretador a executar
Variavel name=value Armazenar um valor (sem espacos ao redor do =)
Referencia $name / ${name} Expandir o valor da variavel
Substituicao de cmd $(command) Obter saida de comando como valor
Saida exit N Sair com status N

O kernel interpreta o shebang quando os dois primeiros bytes de um script sao #!. #!/bin/bash executa sob bash, e #!/bin/sh executa sob um shell POSIX. Este e o metodo padrao de invocacao definido na secao "INVOCATION" do man bash.

O shebang deve estar no inicio da primeira linha. Se uma linha em branco ou espaco o preceder, ele sera tratado como um comentario comum e nao tera efeito.

Passos

Passo 1: Escrever o shebang e tornar executavel

cat > hello.sh <<'EOF'
#!/bin/bash
echo "Hello, LPIC"
EOF
chmod +x hello.sh
./hello.sh
Hello, LPIC

A primeira linha #!/bin/bash especifica o interpretador. Conceda permissao de execucao com chmod +x e execute com ./hello.sh. Passar o script explicitamente ao interpretador como bash hello.sh nao requer permissao de execucao nem shebang, mas na pratica e convencional definir ambos.

Passo 2: Usar variaveis e aspas

#!/bin/bash
name="Penguin Gym"
count=3
echo "${name} : ${count}"
echo "${name}_log"
Penguin Gym : 3
Penguin Gym_log

A atribuicao usa a forma name="value", e voce nao deve colocar espacos ao redor do =. Ao referenciar, envolver em chaves como ${name} torna o limite do nome da variavel claro mesmo quando caracteres seguem imediatamente, como em ${name}_log. Note as aspas duplas "..." porque o valor contem um espaco.

Passo 3: Ler parametros posicionais e especiais

#!/bin/bash
echo "Script name: $0"
echo "First argument: $1"
echo "Argument count: $#"
echo "All arguments: $@"
Script name: ./args.sh
First argument: alpha
Argument count: 2
All arguments: alpha beta

$0 e o nome do script, e $1 ate $9 sao os argumentos em ordem. $# e o numero de argumentos, e $@ e $* representam todos os argumentos. A diferenca e que "$@" expande cada argumento como uma string separada, enquanto "$*" expande como uma unica string (man bash "Special Parameters"). Para iterar sobre argumentos, use "$@".

Variavel Significado
$0 Nome do script
$1 a $9 Parametros posicionais (enesimo argumento)
$# Numero de argumentos
$@ / $* Todos os argumentos
$? Exit status do comando anterior
$$ PID do shell atual
$! PID do comando em background mais recente

Passo 4: Capturar saida em uma variavel com substituicao de comando

#!/bin/bash
today=$(date +%F)
files=$(ls /etc | wc -l)
echo "${today} : ${files} items in /etc"
2026-05-30 : 152 items in /etc

$(command) expande a saida padrao de um comando como string. Isso e a substituicao de comando. E equivalente a sintaxe mais antiga `command` (crase), mas $(...) e recomendada por facilitar aninhamento e leitura (man bash "Command Substitution").

Passo 5: Testar condicoes com test / [ ] / [[]]

#!/bin/bash
a="abc"; n=5
[ "$a" = "abc" ] && echo "string match"
[ "$n" -gt 3 ] && echo "number: greater than 3"
[ -f /etc/passwd ] && echo "file exists"
string match
number: greater than 3
file exists

[ ... ] e um alias para o comando test, e um espaco e obrigatorio logo apos [ e logo antes de ]. Use = e != para comparacao de strings, -eq, -ne, -lt, -gt para comparacao numerica, e -f (arquivo regular), -d (diretorio), -e (existe), -r, -w, -x (permissao de leitura, escrita, execucao) para testes de arquivo (man test). A extensao bash [[ ... ]] suprime word splitting e expansao de pathname e permite escrever &&, ||, <, > diretamente, sendo mais facil de lidar quando voce se limita ao bash.

Tipo Operadores Exemplo
String = / != [ "$a" = "$b" ]
Numerico -eq -ne -lt -gt -le -ge [ "$n" -eq 0 ]
Arquivo -f -d -e -r -w -x [ -d /tmp ]

Usar > ou < para comparacao numerica dentro de [ ] e interpretado como "redirecionamento" ou "comparacao lexicografica de string" e produz resultados inesperados. Sempre use -gt / -lt e similares para comparacao numerica.

Passo 6: Ramificar com if / case

#!/bin/bash
score=$1
if [ "$score" -ge 80 ]; then
    echo "pass"
elif [ "$score" -ge 60 ]; then
    echo "review"
else
    echo "fail"
fi
pass

A forma basica e if condition; then ... elif condition; then ... else ... fi. O ponto crucial e que if ramifica com base no exit status 0 (verdadeiro) do comando de condicao. Para ramificar por um conjunto de valores, case e mais legivel.

#!/bin/bash
case "$1" in
    start) echo "starting" ;;
    stop)  echo "stopping" ;;
    *)     echo "usage: $0 {start|stop}" ;;
esac
starting

A forma e case value in pattern) action ;; esac. Cada ramo termina com ;;, e *) captura "nenhuma das opcoes acima". Esse e o padrao classico para scripts de inicializacao de servicos.

Passo 7: Repetir com for / while / until

#!/bin/bash
for f in *.log; do
    echo "processing: $f"
done

n=1
while [ "$n" -le 3 ]; do
    echo "count: $n"
    n=$((n + 1))
done
processing: access.log
processing: error.log
count: 1
count: 2
count: 3

for variable in value-list; do ... done processa uma lista em ordem. while condition; do ... done repete enquanto a condicao for verdadeira, e until condition; do ... done repete inversamente ate que a condicao se torne verdadeira. $((...)) e a expansao aritmetica, usada para calculo inteiro (man bash "Arithmetic Expansion").

Passo 8: Receber entrada com read e sair com exit

#!/bin/bash
read -p "Enter your name: " who
if [ -z "$who" ]; then
    echo "name is empty" >&2
    exit 1
fi
echo "Welcome ${who}"
exit 0
Enter your name: rina
Welcome rina

read variable le uma linha da entrada padrao para uma variavel (-p exibe um prompt). exit N encerra o script com exit status N. Por convencao, 0 e sucesso e 1 ou mais e falha. [ -z "$who" ] testa se a string esta vazia.

Como Usar Exit Status e && / ||

O exit status do comando anterior e armazenado em $?. 0 e sucesso e diferente de zero e falha. Usando esse valor, voce pode encadear comandos com && (executa o proximo se o anterior teve sucesso) e || (executa o proximo se o anterior falhou).

mkdir -p /tmp/work && echo "created" || echo "failed"
echo "$?"
created
0

A && B executa B apenas quando o exit status de A e 0. A || B executa B apenas quando A e diferente de zero. O teste do if tambem e baseado nesse exit status, e quando voce entende a definicao de verdade especifica do shell onde "verdadeiro = exit status 0", o comportamento da ramificacao condicional parece consistente.

Voce tambem pode agrupar processamento em uma funcao de shell. Dentro de uma funcao, return N define o exit status da funcao, enquanto exit N encerra o script inteiro.

#!/bin/bash
greet() {
    echo "Hello, $1"
    return 0
}
greet "world"
echo "function return value: $?"
Hello, world
function return value: 0

Defina uma funcao com name() { ... } e chame-a com name arguments. Dentro da funcao, argumentos tambem sao referenciados com $1, $2, $#, porque os parametros posicionais alternam por chamada. Quando return e omitido, o exit status do ultimo comando executado na funcao e retornado.

Erros Comuns e Correcoes

Erro Sintoma Forma correta
Espacos ao redor de = na atribuicao var: command not found var=value (sem espacos)
Falta de aspas Argumentos divididos em valores com espacos Envolva em aspas duplas, como [ "$var" = "x" ]
Espacos faltando em [ ] [: missing ']' [ "$a" = "$b" ] (espaco apos [ e antes de ])
Usar = / > para comparacao numerica Lido como comparacao de string ou redirecionamento Use -eq / -gt para numeros
Interpretar mal o exit status if se comporta ao contrario Entenda que verdadeiro significa "exit status 0"

Um erro particularmente comum e o espaco na atribuicao. Se voce escrever var = value, o shell interpreta var como o nome do comando e = e value como argumentos, tenta executa-lo e reporta command not found.

Solucao de Problemas

Sintoma: O script nao inicia com "Permission denied"

Causa: Sem permissao de execucao, ou shebang invalido

Verificacao:

ls -l script.sh
head -n 1 script.sh

Correcao: Conceda permissao de execucao com chmod +x script.sh. Confirme tambem que o shebang esta na primeira linha sem linha em branco antes. Como alternativa, voce pode executa-lo diretamente com bash script.sh.

Sintoma: Atribuicao de variavel reporta "command not found"

Causa: Ha espacos ao redor do =

Verificacao:

bash -n script.sh

Correcao: Remova os espacos, como em var=value. bash -n pode ser usado para verificacao de sintaxe (verifica apenas a gramatica, sem executar).

Sintoma: Ramificacao condicional quebra quando um valor contem espacos

Causa: A referencia da variavel nao esta entre aspas, entao ocorre word splitting

Verificacao:

bash -x script.sh

Correcao: Envolva a variavel em aspas duplas, como [ "$var" = "value" ]. bash -x exibe o resultado expandido de cada comando, para que voce possa identificar onde a divisao ocorre.

Lista de Verificacao

  • [ ] Escreveu o shebang (#!/bin/bash) na primeira linha
  • [ ] Concedeu permissao de execucao com chmod +x
  • [ ] Confirmou que nao ha espacos ao redor do = nas atribuicoes
  • [ ] Colocou aspas nas referencias de variavel como "$var"
  • [ ] Verificou os espacos dentro de [ ] e os operadores de comparacao (string vs numerico)
  • [ ] Retornou um exit status com exit 0 / exit 1

Resumo

Cenario Sintaxe Finalidade
Primeira linha #!/bin/bash Especificar o interpretador
Obter valor $(command) Transformar saida de comando em variavel
Teste string [ "$a" = "$b" ] Igual / diferente
Teste numerico [ "$n" -gt 3 ] Comparacao de magnitude
Ramificacao if / case Ramificar por condicao ou valor
Repeticao for / while / until Processamento em loop
Encadeamento A && B / A || B Encadear por exit status

Shell scripting e a base da automacao de operacoes Linux. Apos cobrir 105.2, combine com variaveis de ambiente (105.1) e comandos de processamento de texto e expressoes regulares para escrever scripts de automacao praticos.

Proximas Leituras

Continue Sua Jornada LPIC-1

Hub LPIC-1

  • Hub de Aprendizado LPIC-1 -- Mapa completo de artigos LPIC-1, acompanhamento de progresso e cobertura dos objetivos do exame

Artigos LPIC-1 Relacionados

Pratica