Parâmetros posicionais
Esta aula aborda os parâmetros posicionais em scripts Bash, ensinando como acessar argumentos passados na linha de comando usando $1, $2, $@, $* e $#, além da utilidade do comando shift para manipular esses argumentos.
Parâmetros posicionais são variáveis especiais no Bash que armazenam os argumentos passados para um script ou função. Eles permitem que scripts sejam mais dinâmicos e reutilizáveis, processando entradas fornecidas pelo usuário ou por outros programas. Nesta aula, exploraremos como acessar esses parâmetros individualmente, como trabalhar com todos eles de uma vez, como contar quantos foram fornecidos e como deslocá-los com o comando shift.
Dominar esses conceitos é essencial para criar scripts que aceitem opções e argumentos de forma flexível, algo comum em ferramentas de linha de comando. Vamos detalhar cada tópico com exemplos práticos.
$1, $2
As variáveis $1, $2, ..., $9 representam o primeiro, segundo, nono argumento posicional, respectivamente. Para argumentos além do nono, é necessário usar chaves: ${10}, ${11}, etc. Essas variáveis são preenchidas automaticamente quando o script é invocado ou quando uma função é chamada.
Exemplo: suponha um script chamado saudacao.sh que recebe um nome e uma saudação como argumentos.
#!/bin/bash
echo "$1, $2!"
Ao executar ./saudacao.sh Olá Mundo, a saída será Olá, Mundo!. Note que $1 é "Olá" e $2 é "Mundo".
É importante lembrar que esses parâmetros são apenas leitura, mas podem ser reatribuídos via set comando.
$@ e $*
Ambos representam todos os argumentos passados ao script, mas com diferenças sutis no tratamento de aspas. $@ expande cada argumento como uma palavra separada, preservando espaços em argumentos entre aspas. $* expande todos os argumentos como uma única palavra, separando-os pelo primeiro caractere do IFS (normalmente espaço).
Exemplo para demonstrar a diferença:
#!/bin/bash
echo "Usando \$@:"
for arg in "$@"; do
echo " $arg"
done
echo "Usando \$*:"
for arg in "$*"; do
echo " $arg"
done
Execute com ./script.sh "um argumento" "outro argumento". A saída será:
Usando $@:
um argumento
outro argumento
Usando $*:
um argumento outro argumento
Perceba que $* trata todos os argumentos como um único elemento. Por isso, é recomendado usar "$@" (com aspas duplas) para preservar a estrutura original dos argumentos, especialmente ao passá-los para outros comandos.
$#
A variável $# contém o número de argumentos posicionais fornecidos ao script ou função. É útil para validar se o usuário passou a quantidade correta de argumentos.
Exemplo de uso:
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Nenhum argumento fornecido."
else
echo "Foram fornecidos $# argumentos."
fi
Se executar sem argumentos, exibe "Nenhum argumento fornecido." Caso contrário, mostra o número. É comum usar $# em verificações para exibir mensagens de uso.
shift
O comando shift desloca os parâmetros posicionais para a esquerda. Por padrão, shift remove o primeiro argumento ($1) e renumera os demais: o que era $2 torna-se $1, $3 vira $2, etc. É possível passar um número para deslocar mais de uma posição: shift N.
Exemplo de processamento de argumentos em loop com shift:
#!/bin/bash
while [ $# -gt 0 ]; do
echo "Processando argumento: $1"
shift
done
Esse loop itera sobre todos os argumentos, imprimindo um por vez, e vai removendo-os até que não haja mais argumentos ($# chega a zero). É uma técnica comum para implementar opções de linha de comando (ex.: -v, --verbose).
Boas práticas
Sempre que possível, use "$@" (com aspas duplas) para preservar argumentos com espaços. Evite modificar $IFS desnecessariamente, pois pode afetar o comportamento de $*. Documente os parâmetros esperados no cabeçalho do script. Prefira opções nomeadas (com getopts) para scripts mais complexos, mas para scripts simples, parâmetros posicionais são suficientes.
Referências
- GNU Bash Manual: Positional Parameters
- Advanced Bash-Scripting Guide: Positional Parameters
- Linux Hint: Bash shift Command
- Shell Script Tutorial: Positional Parameters
- Stack Overflow: What are special dollar sign shell variables?
Exercícios
- Crie um script que receba dois números como argumentos e imprima a soma deles. Se não forem fornecidos exatamente dois argumentos, exiba uma mensagem de erro.
- Escreva um script que use $@ para imprimir cada argumento em uma linha separada, mas com a formatação: "Argumento X: valor".
- Faça um script que aceite uma lista de nomes de arquivos como argumentos e exiba apenas aqueles que existem (use -f). Use shift para processar.
- Crie um script que simule um comando de soma de números passados como argumentos, usando $# para verificar se há pelo menos um argumento, e shift para somar todos.
- Escreva um script que imprima o primeiro e o último argumento passados, usando $1 e ${$#} (dica: use eval ou indireção).
#!/bin/bash
if [ $# -ne 2 ]; then
echo "Uso: $0 numero1 numero2"
exit 1
fi
soma=$(( $1 + $2 ))
echo "Soma: $soma"
#!/bin/bash
cont=1
for arg in "$@"; do
echo "Argumento $cont: $arg"
((cont++))
done
#!/bin/bash
while [ $# -gt 0 ]; do
if [ -f "$1" ]; then
echo "$1 existe"
fi
shift
done
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Uso: $0 num1 [num2 ...]"
exit 1
fi
soma=0
while [ $# -gt 0 ]; do
soma=$(( soma + $1 ))
shift
done
echo "Soma total: $soma"
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Nenhum argumento."
exit 1
fi
echo "Primeiro: $1"
# Para o último, usa indireção com ${!#}
echo "Último: ${!#}"