Comandos Shell Essenciais para Engenheiros de Sistemas Embarcados

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 -r em 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.

  1. Diagnóstico Inicial com grep: Verificar logs por erros de comunicação.
    dmesg | grep -i i2c | grep -i "error\|failed\|timeout"
  2. 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}'
  3. 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" {} \;
  4. 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 .sh reutilizá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.

Tags: shell grep awk find sed

Publicado em 6-2 06:38 por Thomas