Como o preenchimento automático do Bash funciona?

9

Entendo que o preenchimento automático do bash funciona para utilitários padrão. Mas como ele faz o preenchimento automático de programas personalizados como o Oracle SQL loader?

No comando a seguir, se você tabular depois control=, ele será preenchido automaticamente com o nome do arquivo de controle:

sqlldr kshitiz/oracle@XE control=data.ctl data=data.csv bad=data.bad log=data.log

Como ele sabe que precisa preencher o arquivo de controle naquele momento e não outro arquivo?

Kshitiz Sharma
fonte
2
A conclusão dos parâmetros é feita com funções. A maioria deles está instalada /etc/bash_completion.d. Veja também /etc/bash_completione dê uma olhada na saída de setquanto seu ambiente cresceu.
24--15
@ott O que devo procurar nesse local? Não consigo ver nada relacionado ao sqlldr. Tudo que eu tenho é: gdbus-bash-completion.sh gvfs-bash-completion.sh pk-completion.bash yum.bash. A saída de seté igualmente desinteressante.
Kshitiz Sharma
Também poderia ser feito em alguns scripts de /etc/profile.d. Ou talvez o seu .bash_profileou tenha .bashrcsido modificado.
24--15
Como essas funções diferem das funções normais. E como eu defini o meu próprio para fornecer preenchimento automático para um script personalizado? Você poderia apontar na direção certa?
Kshitiz Sharma
1
@KshitizSharma, bash-completioncarrega conclusões dinamicamente desde então 1.90. Tente: sqlldr<space><tab><enter>. Então digite complete -p sqlldr.
precisa

Respostas:

6

A conclusão programável do Bash funciona analisando a linha de comando e descobrindo o que está sendo concluído:

  1. Alguns contextos são tratados especialmente, por exemplo, a primeira palavra em um comando é concluída como um nome de comando, o que segue a $é concluída como um nome de variável, etc.
  2. Fora desses contextos, o bash tenta concluir o argumento de um comando e as configurações para o comando ou a falha (que geralmente é o caso) para o nome da base do comando são aplicadas.

Por exemplo, depois , o bash conclui os nomes dos comandos que começam com . Depois , o bash completa os nomes de variáveis ​​que começam com . Depois , o bash aplica as regras de conclusão para o comando . As regras de conclusão podem especificar uma categoria (usuário, variável, arquivos etc.), um padrão curinga para nomes de arquivo ou uma função ou trecho de código a ser executado.sqllTabsqllsqlldr $aTabasqlldr Tabsqlldr

As regras de conclusão são definidas pelo completebuiltin. O Bash não controla quando o completebuiltin foi chamado ou em qual script (se houver) ele estava. A maioria das distribuições envia o pacote bash-complete , que fornece uma série de regras para comandos comuns. Isso assume a forma de uma série de arquivos de script que contêm chamadas para complete, com um script que deve ser lido .bashrc(ou /etc/bash.bashrcse implementado) para carregar todos esses scripts: normalmente . /etc/bash_completioné necessário para ativar a conclusão programável e carregar os scripts disponíveis.

O pacote padrão não inclui suporte para sqlldr. Se você tiver esse suporte, ele deve ser de uma fonte diferente. Essa fonte pode ter descartado um arquivo em um diretório como /etc/bash_completion.dou pode ter fornecido instruções para incluir algum código no seu .bashrc. Você pode usar complete -p sqlldrpara ver as regras atuais para sqlldr; como mencionado anteriormente, isso não informará de onde essas regras foram carregadas.

O tcsh, o zsh e o fish têm mecanismos semelhantes (todos se inspiraram no tcsh), mas com diferentes componentes, sintaxes e recursos.

Gilles 'SO- parar de ser mau'
fonte
Sim, você não pode localizar onde completefoi chamado. Mas você pode encontrar o nome do arquivo de origem e o número da linha em que a função de conclusão está definida. complete -p sudo # outputs complete -F _sudo sudo, shopt -s extdebug, declare -F _sudo # outputs _sudo 3 /usr/share/bash-completion/completions/sudo. (Mas veja meu comentário sobre conclusões dinâmicas carregando e complete -p).
Evgeny Vereshchagin
and the settings for the basename of the command are applied. Não. Você pode ter diferentes compspecs para datee /bin/date. A referência diz : Se a palavra de comando for um nome de caminho completo, primeiro será procurado um compspec para o nome de caminho completo. Se nenhum compspec for encontrado para o nome do caminho completo, é feita uma tentativa de encontrar um compspec para a parte após a barra final
Evgeny Vereshchagin