Guia de tecnologias

Autocompletar em Bash e zsh: criar um script simples de conclusão

7 min read Desenvolvimento Atualizado 22 Sep 2025
Autocompletar Bash e zsh: criar um script
Autocompletar Bash e zsh: criar um script

TL;DR

Autocompletar economiza tempo e torna comandos personalizados mais descobríveis. Este artigo ensina como adicionar conclusão por Tab para scripts em zsh e Bash, cobre um exemplo passo a passo, mostra um script compatível com ambas as shells e oferece checklists, casos de teste e armadilhas comuns.

Importante: autocompletar é ativado pela shell do usuário (onde o Tab é pressionado), não pela linguagem do script.

Janela de terminal mostrando a página do manual do cliente de e-mail Mutt no Linux

O que é autocompletar

Autocompletar (completar) preenche automaticamente palavras ou caminhos com base no que você começou a digitar. Em shells, ele aparece quando você pressiona Tab. Define-se rápido:

  • Tab completion: interação que sugere ou completa comandos, opções, subcomandos e nomes de ficheiros quando o usuário pressiona Tab.

Este recurso existe no Unix desde os anos 80 e hoje é suportado por shells amplamente usados, como Bash e zsh.

Sugestões de autocompletar para o comando

Por que adicionar conclusão para seus scripts

  • Facilita descobrimento de subcomandos numa ferramenta caseira.
  • Reduz erros de digitação.
  • Melhora a experiência de colaboradores e usuários finais.

A seguir há um exemplo simples que mostra como implementar autocompletar para um utilitário fictício chamado todos.

Exemplo: comando simples todos

Este exemplo usa um script que guarda tarefas em um ficheiro. O script em si não é o foco; o objetivo é demonstrar apenas como oferecer sugestões de subcomandos.

Código de exemplo (zsh):

#!/usr/bin/env zsh  
  
FILE="$HOME/.local/state/todos/data"  
  
if [ "$#" -eq "1" ] && [ "$1" = "edit" ] ; then  
    "${EDITOR:-vi}" "$FILE"  
elif [ "$#" -eq "1" ] && [ "$1" = "help" ] ; then  
    echo "Usage: $(basename $0) [ edit | help ]"  
else  
    <"$FILE" grep -v ^~  
fi  

Se o ficheiro for executável e estiver no PATH, você terá estes comandos:

  • todos — mostrar conteúdo (linhas que não começam com ~)
  • todos help — mostrar ajuda
  • todos edit — abrir o ficheiro no editor

A conclusão ajuda a descobrir os subcomandos sem memorizar a sintaxe.

Como criar um script de conclusão em zsh

Em zsh a API é simples. Você registra uma função que usa compadd para listar as sugestões.

Exemplo mínimo para zsh:

_complete_todos() {  
    compadd help edit  
}  
  
autoload -Uz compinit  
compinit  
compdef _complete_todos todos  
  • compadd: adiciona sugestões ao sistema de conclusão da zsh.
  • compinit: inicializa o sistema de completions.
  • compdef: associa a função de conclusão ao comando todos.

Onde colocar o código: no seu .zshrc, num ficheiro carregado por .zshrc, ou usando fpath com um nome começando por underline (por exemplo _todos).

Teste rápido: carregue o bloco no shell atual e pressione Tab após digitar todos.

Diferenças no Bash

Bash usa uma abordagem distinta. Você escreve uma função que preenche a variável COMPREPLY com as sugestões. Bash não adivinha tanto — a função precisa considerar o estado atual da linha de comando.

Exemplo mínimo (inicial, ingênuo):

_complete_todos_bash() {  
    COMPREPLY=(help edit)  
}  
  
complete -F _complete_todos_bash todos  

Isso funciona, mas é permissivo demais: ao digitar “he” ele pode sugerir tanto help quanto edit. Para corrigir isso, use as variáveis que o Bash fornece:

  • COMP_WORDS: array com as palavras da linha de comando.
  • COMP_CWORD: índice da palavra sendo completada.

Uma função melhor usa compgen para filtrar sugestões baseadas no texto parcial:

_complete_todos_bash() {  
    COMPREPLY=( $( compgen -W "edit help" -- "${COMP_WORDS[$COMP_CWORD]}" ) )  
}  
  
complete -F _complete_todos_bash todos  

compgen -W “lista” – “prefixo” retorna as palavras que começam com o prefixo.

Script universal: suportando zsh e Bash

Para compartilhar um script com colegas, detecte a shell e registre a função apropriada. Aqui está um exemplo que funciona em ambas as shells:

SUBCOMMANDS=(help edit halt)  
  
_complete_todos_zsh() {  
    compadd $SUBCOMMANDS  
}  
  
_complete_todos_bash() {  
    COMPREPLY=( $( compgen -W "${SUBCOMMANDS[*]}" -- "${COMP_WORDS[$COMP_CWORD]}" ) )  
}  
  
if [ -n "${ZSH_VERSION:-}" ]; then  
    autoload -Uz compinit  
    compinit  
    compdef _complete_todos_zsh todos  
elif [ -n "${BASH_VERSION:-}" ]; then  
    complete -F _complete_todos_bash todos  
fi  

Dicas de distribuição:

  • Salve num ficheiro, por exemplo completion.sh.
  • No .bashrc e/ou .zshrc: . /path/to/completion.sh
  • Para zsh, considere colocar o ficheiro em fpath como _todos para integração automática.

Boas práticas e considerações

  • Use arrays/deslocamentos para evitar problemas com palavras com espaços.
  • Projete autocompletar para ser idempotente e rápida; não faça chamadas de rede bloqueantes.
  • Se as sugestões dependem do ambiente (por exemplo ficheiros presentes), calcule-as dinamicamente.
  • Não exponha segredos; evite inserir valores sensíveis nas listas de sugestões.

Quando a conclusão falha (exemplos e causas comuns)

  • O ficheiro não é carregado pelo .bashrc/.zshrc: verifique sourcing.
  • O comando não está no PATH: a associação dependa do nome do comando no PATH.
  • Conflito com outras definições: outra função de completion pode ter precedência.
  • Problemas de escape: strings com espaços precisam de tratamento correto.
  • Performance: gerar milhares de sugestões pode bloquear a shell.

Abordagens alternativas

  • Usar utilitários como argparse-completions ou argcomplete (para Python) que geram automaticamente completions a partir da definição de argumentos.
  • Gerar scripts de completion durante a instalação (make install) e colocá-los em /etc/bash_completion.d/ ou diretórios equivalentes para zsh.
  • Para projetos mais complexos, manter um subcomando –completion que gera output estruturado lido pelo handler de completion.

Mental model (heurística rápida)

  • Pense em três camadas: lista fonte (onde as possíveis palavras vêm), filtro (prefixo e contexto) e registro (associar a função ao comando).
  • Priorize filtros simples e rápidos; apenas liste tudo quando for aceitável em termos de desempenho.

Checklist por papel

  • Desenvolvedor:
    • Implementar função de completion mínima.
    • Tratar espaços e caracteres especiais.
    • Fornecer suporte a Bash e zsh quando necessário.
  • Mantenedor do pacote:
    • Colocar ficheiro de completion em diretório padrão da distro.
    • Adicionar step de instalação que registre a completion.
  • Usuário final:
    • Verificar se .bashrc/.zshrc faz source do script.
    • Reabrir a shell ou executar source manualmente.

Casos de teste e critérios de aceitação

  • Ao digitar “todos ”, devem aparecer todas as subcomandos registradas.
  • Ao digitar “todos he”, somente “help” deve ser sugerido.
  • O script não deve travar a shell ao listar 1000+ sugestões (critério de performance dependente do ambiente).
  • O script deve funcionar quando os ficheiros estiverem com espaços no nome.

Mini metodologia para implementar completions robustas

  1. Liste as fontes de sugestões (subcomandos, ficheiros, comandos externos).
  2. Escreva uma função de completition mínima que retorne um conjunto estático.
  3. Adicione filtragem baseada no prefixo do usuário.
  4. Teste em ambientes com diferentes shells.
  5. Simule grandes conjuntos de sugestões para testar performance.
  6. Consolide o script para suportar Bash e zsh se for necessário compartilhar.

Exemplo avançado: completar argumentos condicionais

Imagine que o subcomando “deploy” aceita um ambiente (staging|prod). A conclusão deve sugerir ambientes apenas quando o primeiro argumento for deploy.

Estratégia:

  • Olhe para COMP_CWORD/COMP_WORDS (Bash) ou use widgets/contextos em zsh.
  • Baseie decisões no conteúdo das palavras anteriores.

Pseudocódigo (Bash):

# se a primeira palavra for 'deploy', sugerir ambientes
if [ "${COMP_WORDS[1]}" = "deploy" ]; then
  COMPREPLY=( $( compgen -W "staging prod" -- "${COMP_WORDS[$COMP_CWORD]}" ) )
fi

No zsh, você faria lógica similar dentro da função de completion, usando compadd para o conjunto apropriado.

Segurança e privacidade

  • Não exponha IDs ou caminhos sensíveis nas sugestões.
  • Não gere listas que revelam informações restritas (por exemplo nomes de ficheiros internos) sem verificar permissões.
  • Considere trabalhar com permissões reduzidas se o comando que gera sugestões precisa ler dados sensíveis.

Compatibilidade e migração

  • Zsh tem compadd e compdef; Bash usa complete e COMPREPLY.
  • Para distribuição em sistemas diversos, documente a necessidade de sourcing e os caminhos de instalação.
  • Em distribuições que usam bash-completion, prefira instalar o ficheiro em /etc/bash_completion.d/ para ativação automática.

Guia de implantação (SOP rápido)

  1. Coloque completion.sh no repositório em scripts/completion.sh.
  2. No instalador (Makefile ou setup), copie para /usr/local/share/mytool/completion.sh.
  3. No postinstall, adicione instrução para que o utilizador faça source no .bashrc/.zshrc, ou copie as definições para /etc/bash_completion.d/ e os equivalentes de zsh.
  4. Teste em um sistema limpo.

Exemplos de snippets e cheatsheet

  • Registrar para Bash:
complete -F _myfunc mycmd
  • Registrar para zsh (após compinit):
compdef _myfunc mycmd
  • Usar compgen para filtrar:
compgen -W "one two three" -- "prefix"

Resumo

Adicionar autocompletar aos seus scripts melhora usabilidade e reduz erros. Zsh oferece helpers mais diretos (compadd), enquanto Bash exige um pouco mais de código (COMPREPLY e compgen). Se precisar distribuir para múltiplas shells, detecte a shell e registre as funções adequadas. Teste os casos de prefixo, espaços e performance.

Perguntas frequentes

Como carrego o script sem reiniciar a shell?

Use source /path/to/completion.sh ou . /path/to/completion.sh.

Posso completar ficheiros e subcomandos ao mesmo tempo?

Sim. Gere a lista combinada ou implemente lógica condicional que avalie a posição do cursor.

Devo instalar o script globalmente?

Se for parte de uma ferramenta usada por muitos utilizadores, instale em diretórios padrão (/etc/bash_completion.d/ ou diretórios de completions do zsh).

Anexos úteis

  • Checklist de lançamento

    • Script testado em zsh
    • Script testado em Bash
    • Documentação de instalação adicionada
    • Política de privacidade verificada (nenhuma informação sensível sugerida)
  • Critérios finais de aceitação

    • Completar subcomandos básicos conforme esperado.
    • Filtragem por prefixo funcionando em Bash.
    • Sem regressões em shells dos colaboradores.
Autor
Edição

Materiais semelhantes

Reduzir array RAID degradado com mdadm e LVM
Linux

Reduzir array RAID degradado com mdadm e LVM

Consertar som ausente em Stories do Instagram no iPhone
Tutoriais

Consertar som ausente em Stories do Instagram no iPhone

Rastrear e evitar números de telefone falsos
Segurança e Privacidade

Rastrear e evitar números de telefone falsos

Autocompletar Bash e zsh: criar um script
Desenvolvimento

Autocompletar Bash e zsh: criar um script

Formulários no Numbers para iPad e iPhone
Tutoriais

Formulários no Numbers para iPad e iPhone

Gerenciador de senhas para estudantes — guia prático
Segurança

Gerenciador de senhas para estudantes — guia prático