Comment fonctionne la complétion automatique Bash?

9

Je peux comprendre que la complétion automatique bash fonctionne pour les utilitaires standard. Mais comment fait-il la complétion automatique pour des programmes personnalisés comme Oracle SQL Loader?

Dans la commande suivante si vous tabulez après, control=elle se termine automatiquement au nom du fichier de contrôle:

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

Comment sait-il qu'il doit remplir le fichier de contrôle à ce stade et pas un autre fichier?

Kshitiz Sharma
la source
2
La complétion des paramètres se fait avec des fonctions. La plupart d'entre eux sont installés en /etc/bash_completion.d. Voyez également /etc/bash_completionet regardez la sortie de set, combien votre environnement a grandi.
ott--
@ott Que dois-je rechercher à cet endroit? Je n'arrive pas à voir quoi que ce soit lié à sqlldr. Tout ce que j'ai est la suivante : gdbus-bash-completion.sh gvfs-bash-completion.sh pk-completion.bash yum.bash. La sortie de setest tout aussi inintéressante.
Kshitiz Sharma
Cela pourrait également être fait dans un script de /etc/profile.d. Ou peut-être que votre .bash_profileou a .bashrcété modifié.
ott--
En quoi ces fonctions sont-elles différentes des fonctions normales. Et comment pourrais-je définir la mienne pour fournir la saisie automatique pour un script personnalisé? Pourriez-vous pointer dans la bonne direction?
Kshitiz Sharma
1
@KshitizSharma, bash-completioncharge les achèvements dynamiquement depuis 1.90. Essayez: sqlldr<space><tab><enter>. Tapez ensuite complete -p sqlldr.
Evgeny Vereshchagin

Réponses:

6

L' achèvement programmable de Bash fonctionne en analysant la ligne de commande et en déterminant ce qui est en cours d'achèvement:

  1. Certains contextes sont traités spécialement, par exemple le premier mot d'une commande est complété comme un nom de commande, ce qui suit un $est complété comme un nom de variable, etc.
  2. En dehors de ces contextes, bash tente de terminer l'argument d'une commande, et les paramètres de la commande ou à défaut (ce qui est généralement le cas) pour le nom de base de la commande sont appliqués.

Par exemple, après , bash termine les noms de commandes commençant par . Après , bash termine les noms de variables commençant par . Après , bash applique les règles d'achèvement de la commande . Les règles d'achèvement peuvent spécifier une catégorie (utilisateur, variable, fichiers, etc.), un modèle générique pour les noms de fichier ou une fonction ou un extrait de code à exécuter.sqllTabsqllsqlldr $aTabasqlldr Tabsqlldr

Les règles d'achèvement sont définies par la fonction completeintégrée. Bash ne garde aucune trace du moment où la commande completeintégrée a été appelée ni du script (le cas échéant) dans lequel elle se trouvait. La plupart des distributions livrent le paquet bash-complètement , qui fournit une série de règles pour les commandes courantes. Cela prend la forme d'une série de fichiers de script qui contiennent des appels à complete, avec un script qui doit être lu .bashrc(ou /etc/bash.bashrcs'il est implémenté) pour charger tous ces scripts: il . /etc/bash_completionest généralement nécessaire pour activer la complétion programmable et charger les scripts disponibles.

Le package standard n'inclut pas la prise en charge de sqlldr. Si vous disposez d'un tel support, il doit provenir d'une autre source. Cette source peut avoir déposé un fichier dans un répertoire comme /etc/bash_completion.dou peut avoir été accompagnée d'instructions pour inclure du code dans votre .bashrc. Vous pouvez utiliser complete -p sqlldrpour voir les règles actuelles pour sqlldr; comme mentionné précédemment, cela ne vous dira pas d'où ces règles ont été chargées.

Tcsh, zsh et fish ont des mécanismes quelque peu similaires (tout le monde s'inspire de tcsh) mais des structures, des syntaxes et des capacités différentes.

Gilles 'SO- arrête d'être méchant'
la source
oui, vous ne pouvez pas localiser l’ completeappel. Mais vous pouvez trouver le nom du fichier source et le numéro de ligne où la fonction d'achèvement est définie. complete -p sudo # outputs complete -F _sudo sudo, shopt -s extdebug, declare -F _sudo # outputs _sudo 3 /usr/share/bash-completion/completions/sudo. (Mais voir mon commentaire sur le chargement dynamique des achèvements et complete -p).
Evgeny Vereshchagin
and the settings for the basename of the command are applied. Non. Vous pouvez avoir un compspecs différent pour dateet /bin/date. La référence indique : Si le mot de commande est un nom de chemin complet, une spécification du nom de chemin complet est recherchée en premier. Si aucune spécification n'est trouvée pour le chemin d'accès complet, une tentative est faite pour trouver une spécification pour la portion suivant la barre oblique finale
Evgeny Vereshchagin