Imagine-se diagnosticando um dispositivo embarcado onde a rede parou de funcionar e o log do kernel está rolando no terminal serial. Localizar a causa manualmente entre centenas de linhas seria ineficiente. Nesses cenários, onde o ambiente é restrito em recursos, sem interface gráfica e frequentemente acessado remotamente, o domínio de alguns comandos Shell fundamentais determina a eficiência do engenheiro.
No mundo do desenvolvimento embarcado, baseado em Linux, o console de comandos é a ferramenta primária. Comandos como grep, awk, find e sed são indispensáveis por serem leves (presentes no BusyBox), poderosos (suportam expressões regulares e processamento de fluxo), e combináveis via tubulações, funcionando como uma suíte de ferramentas autossuficiente.
grep: Filtrando Informação em Logs
O grep é um mecanismo de filtragem baseado em expressões regulares, ideal para extrair linhas relevantes de grandes volumes de texto, como saídas do dmesg ou journalctl.
Exemplo Prático: Investigando Falha de Driver
Para buscar erros relacionados a um controlador de barramento, como USB ou I2C:
dmesg | grep -iE "(usb|i2c|error|failed)"
O parâmetro -i ignora maiúsculas e minúsculas, e -E permite expressões regulares estendidas para múltiplos padrões. Para obter contexto ao redor de uma falha específica:
dmesg | grep -C 3 "timeout"
Isso exibe três linhas antes e depois de cada ocorrência de "timeout", fornecendo uma visão mais ampla do estado do sistema naquele momento.
Armadilhas Comuns
- Caracteres especiais: Para buscar uma string literal como
reg_write(0xAB), use a flag-F:grep -F "reg_write(0xAB)". - Busca recursiva: Evite
grep -rem diretórios raiz em sistemas embarcados sem recursos, pois pode congelar. Limite o escopo.
awk: Processando Dados Estruturados
O awk é uma linguagem de domínio específico projetada para maniuplação de texto e relatórios, sendo perfeito para analisar a saída formatada de comandos ou arquivos como /proc/meminfo.
Exemplo: Calculando Uso de Memória Preciso
awk '
/^MemTotal/ {mem_total = $2}
/^MemAvailable/ {mem_avail = $2}
END {
used_kb = mem_total - mem_avail;
used_mb = used_kb / 1024;
percentage = (used_kb / mem_total) * 100;
printf "Memória em Uso: %.2f MB (%.1f%%)\n", used_mb, percentage
}' /proc/meminfo
Este script extrai os valores totais e disponíveis, realizando um cálculo aritmético preciso dentro do próprio awk, sem a necessidade de pós-processamento complexo.
Exemplo: Listando Processos por Consumo de CPU
ps aux --sort=-%cpu | awk 'NR > 1 {printf "%-8s %-20s %s%%\n", $2, $11, $3}' | head -5
Esta combinação ordena os processos por uso de CPU e formata a saída das cinco primeiras linhas (excluindo o cabeçalho) de maneira legível.
find: Localizando Recursos no Sistema de Arquivos
O comando find é essencial para navegar e administrar a hierarquia de arquivos, especialmente durante o desenvolvimento e otimização da imagem do sistema.
Otimizando o Tamanho da Imagem do Rootfs
Para identificar arquivos grandes que aumentam desnecessariamente a imagem final:
find /caminho/para/rootfs -type f -size +3M -exec ls -lh {} \;
Isso lista arquivos maiores que 3MB com seus tamanhos, ajudando a identificar bibliotecas ou binários inchados que podem ser removidos ou otimizados.
Automação de Limpeza e Permissões
Para remover arquivos de compilação intermediários (.o, .d):
find ./projeto/build -name "*.o" -o -name "*.d" -delete
Para adicionar permissão de execução a todos os scripts em um diretório:
find ./projeto/scripts -type f -name "*.sh" -exec chmod +x {} +
O uso de + no final do -exec em vez de \; otimiza a performance ao agrupar múltiplos argumentos em uma única chamada.
sed: Modificando Arquivos de Configuração de Forma Não-Interativa
O sed (Stream Editor) é a ferramenta ideal para alterar arquivos de configuração em dispositivos remotos via SSH ou durante scripts de provisionamento automatizado.
Habilitando Logs de Depuração
Supondo que um módulo use uma flag de nível de log em um arquivo de configuração:
sed -i 's/LOG_LEVEL=ERR/LOG_LEVEL=DBG/' /etc/modulo.conf
O parâmetro -i realiza a alteração diretamente no arquivo (in-place).
Comentando e Descomentando Configurações
Para desativar temporariamente um serviço systemd comentando sua linha de execução:
sed -i 's|^ExecStart=/usr/bin/meu_servico|# \0|' /etc/systemd/system/meu_servico.service
Aqui, \0 representa a string correspondida inteira, e o padrão ^ garante que a substituição ocorra no início da linha. Para reverter:
sed -i 's|^# ExecStart=/usr/bin/meu_servico|ExecStart=/usr/bin/meu_servico|' /etc/systemd/system/meu_servico.service
Segurança com sed -i
Por ser uma operação destrutiva, é crucial criar um backup antes:
cp /etc/arquivo.conf /etc/arquivo.conf.bak
sed -i 's/valor_antigo/valor_novo/' /etc/arquivo.conf
Alternativamente, use a forma sed -i.bak 's/.../...' file para criar um backup automático.
Fluxo de Trabalho Integrado
Consideremos um cenário onde um sensor I2C não está sendo detectado.
- Diagnóstico Inicial com
grep: Verificar logs por erros de comunicação.
dmesg | grep -i i2c | grep -i "error\|failed\|timeout" - Extração de Informações com
awk: Listar todos os dispositivos I2C registrados no sistema.
cat /sys/bus/i2c/devices/*/name | awk -F/ '{print $0}' - Localização de Configurações com
find: Encontrar o arquivo de configuração do dispositivo (device tree overlay).
find /boot -name "*.dtbo" -exec grep -l "sensor_x" {} \; - Modificação com
sed: Corrigir um endereço I2C errado no arquivo de configuração.
sed -i 's/reg = <0x48>/reg = <0x49>/' /boot/overlays/sensor-x.dtbo
Essa combinação permite um diagnóstico e correção rápidos, inteiramente a partir do terminal.
Recomendações para a Prática de Engenharia
- Crie Scripts Utilitários: Empacote comandos frequentes (como monitoramento de recursos) em scripts
.shreutilizáveis. - Verifique a Compatibilidade com o BusyBox: Teste as funcionalidades dos comanods no ambiente-alvo, pois algumas opções (como
grep -r) podem estar ausentes. - Prefira Tubulações Simples e Decompostas: Evite tubulações longas e complexas. Decomponha a lógica em etapas intermediárias, salvando saídas em arquivos temporários (
tmpfile) para facilitar a depuração do próprio script. - Registre Operações Críticas: Redirecione a saída de diagnósticos importantes para arquivos de log persistentes.