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"
fipass
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}" ;;
esacstarting
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))
doneprocessing: 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 0Enter 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.