Wie funktioniert die automatische Vervollständigung von Bash?

9

Ich kann verstehen, dass die automatische Vervollständigung von Bash für Standarddienstprogramme funktioniert. Aber wie erfolgt die automatische Vervollständigung für benutzerdefinierte Programme wie Oracle SQL Loader?

Wenn Sie im folgenden Befehl die Tabulatortaste control=drücken, wird der Name der Steuerdatei automatisch vervollständigt:

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

Woher weiß es, dass es zu diesem Zeitpunkt die Steuerdatei ausfüllen muss und keine andere Datei?

Kshitiz Sharma
quelle
2
Die Vervollständigung der Parameter erfolgt mit Funktionen. Die meisten von ihnen sind in eingerichtet /etc/bash_completion.d. Sehen Sie auch /etc/bash_completionund sehen Sie sich an set, wie stark Ihre Umgebung gewachsen ist.
ott--
@ott Was soll ich an diesem Ort suchen? Ich kann nichts im Zusammenhang mit sqlldr sehen. Ich habe nur : gdbus-bash-completion.sh gvfs-bash-completion.sh pk-completion.bash yum.bash. Die Ausgabe von setist ebenso uninteressant.
Kshitiz Sharma
Es könnte auch in einem Skript von gemacht werden /etc/profile.d. Oder vielleicht dein .bash_profileoder .bashrcwurde modifiziert.
ott--
Wie unterscheiden sich diese Funktionen von normalen Funktionen? Und wie habe ich meine eigenen definiert, um die automatische Vervollständigung für ein benutzerdefiniertes Skript bereitzustellen? Könnten Sie in die richtige Richtung zeigen?
Kshitiz Sharma
1
@KshitizSharma, bash-completionlädt Vervollständigungen seitdem dynamisch 1.90. Versuchen Sie : sqlldr<space><tab><enter>. Geben Sie dann ein complete -p sqlldr.
Evgeny Vereshchagin

Antworten:

6

Bashs programmierbare Fertigstellung funktioniert, indem die Befehlszeile analysiert und herausgefunden wird, was abgeschlossen wird:

  1. Einige Kontexte werden speziell behandelt, z. B. wird das erste Wort in einem Befehl als Befehlsname vervollständigt, das folgende a $wird als Variablenname vervollständigt usw.
  2. Außerhalb dieser Kontexte versucht bash, das Argument eines Befehls zu vervollständigen, und die Einstellungen für den Befehl oder das Versagen (was normalerweise der Fall ist) für den Basisnamen des Befehls werden angewendet.

Beispielsweise vervollständigt bash nachher Befehlsnamen, die mit beginnen . Danach vervollständigt bash Variablennamen, die mit beginnen . Danach wendet bash die Abschlussregeln für den Befehl an . Abschlussregeln können eine Kategorie (Benutzer, Variable, Dateien usw.), ein Platzhaltermuster für Dateinamen oder ein auszuführendes Funktions- oder Codefragment angeben.sqllTabsqllsqlldr $aTabasqlldr Tabsqlldr

Abschlussregeln werden durch das completeeingebaute definiert . Bash verfolgt nicht, wann das completeeingebaute System aufgerufen wurde oder in welchem ​​Skript (falls vorhanden) es sich befand. Die meisten Distributionen liefern das Bash-Completion- Paket, das eine Reihe von Regeln für allgemeine Befehle enthält. Dies erfolgt in Form einer Reihe von Skriptdateien, die Aufrufe an enthalten complete, mit einem Skript, aus dem gelesen werden muss .bashrc(oder das /etc/bash.bashrcimplementiert wird), um alle diese Skripte zu laden. Dies wird normalerweise . /etc/bash_completionbenötigt, um die programmierbare Fertigstellung zu aktivieren und die verfügbaren Skripte zu laden.

Das Standardpaket enthält keine Unterstützung für sqlldr. Wenn Sie eine solche Unterstützung haben, muss diese von einer anderen Quelle stammen. Diese Quelle hat möglicherweise eine Datei in einem Verzeichnis wie gelöscht /etc/bash_completion.doder Anweisungen zum Einfügen von Code in Ihr Verzeichnis geliefert .bashrc. Sie können verwenden complete -p sqlldr, um die aktuellen Regeln für anzuzeigen sqlldr; Wie bereits erwähnt, können Sie hier nicht feststellen, woher diese Regeln geladen wurden.

Tcsh, zsh und fish haben ähnliche Mechanismen (jeder hat sich von tcsh inspirieren lassen), aber unterschiedliche integrierte Funktionen, Syntaxen und Funktionen.

Gilles 'SO - hör auf böse zu sein'
quelle
Ja, Sie können nicht finden, wo completeangerufen wurde. Sie können jedoch den Namen und die Zeilennummer der Quelldatei finden, in der die Abschlussfunktion definiert ist. complete -p sudo # outputs complete -F _sudo sudo, shopt -s extdebug, declare -F _sudo # outputs _sudo 3 /usr/share/bash-completion/completions/sudo. (Aber siehe meinen Kommentar zum dynamischen Laden von Abschlüssen und complete -p).
Evgeny Vereshchagin
and the settings for the basename of the command are applied. Nein. Sie können eine andere Compspecs für dateund haben /bin/date. Die Referenz lautet : Wenn das Befehlswort ein vollständiger Pfadname ist, wird zuerst nach einer Compspec für den vollständigen Pfadnamen gesucht. Wenn für den vollständigen Pfadnamen keine Compspec gefunden wird, wird versucht, eine Compspec für den Teil nach dem letzten Schrägstrich zu finden
Evgeny Vereshchagin