Ich arbeite derzeit an einem Shell-Skript namens makeyourself.sh
(verlinkt mit /usr/bin/mys
), das automatisch ein Debian-Paket aus der Quelle (über apt-get source -b $1
) installiert.
Daher habe ich beschlossen, eine Autovervollständigungsfunktion für den Paketnamen hinzuzufügen, der als erster Parameter angegeben wird: sudo mys panth<tab><tab>
sollte dann alle Pakete auflisten, die mit beginnen panth
— mein Versuch war wie folgt:
complete -C "apt-cache --no-generate pkgnames" mys
Aber es scheint nicht zu funktionieren: Wenn ich wie oben erwähnt die Tabulatortaste drücke, ändert at den Parameter in mys
, was mir zurückgibt sudo mys mys
.
Was mache ich falsch? Muss ich im Befehl die Stelle angeben, an der complete
der zu vervollständigende String eingefügt werden soll, etwa so {}
oder $1
?
Ich verwende ElementaryOS, eine Linux-Distribution basierend auf Ubuntu. Das Skript ist ein Standard-Shell-Skript *.sh, das den Standard verwendet#!/bin/bash
Antwort1
Wie Sie vermuten, erhält der Befehl einige Informationen darüber, was ausgeführt werden soll. Dies ist im Handbuch dokumentiert, jedoch nicht in derDokumentation der complete
eingebauten, müssen Sie lesen dieEinführungsabschnitt zur programmierbaren Vervollständigung.
jede Shell-Funktion oder jeder Befehl, der mit den Optionen
-F
und angegeben wurde-C
, wird aufgerufen. Wenn der Befehl oder die Funktion aufgerufen wird, werden den VariablenCOMP_LINE
,COMP_POINT
,COMP_KEY
, undCOMP_TYPE
Werte zugewiesen, wie oben beschrieben (sieheBash-Variablen). Wenn eine Shell-Funktion aufgerufen wird, werden auch die VariablenCOMP_WORDS
undCOMP_CWORD
gesetzt. Wenn die Funktion oder der Befehl aufgerufen wird, ist das erste Argument der Name des Befehls, dessen Argumente vervollständigt werden, das zweite Argument ist das zu vervollständigende Wort und das dritte Argument ist das Wort, das dem zu vervollständigenden Wort in der aktuellen Befehlszeile vorangeht. Es wird keine Filterung der generierten Vervollständigungen nach dem zu vervollständigenden Wort durchgeführt; die Funktion oder der Befehl hat bei der Generierung der Übereinstimmungen völlige Freiheit.
Der Befehl wird also mit drei Parametern aufgerufen:
- Der Befehlsname – so können Sie Vervollständigungen für ähnliche Befehle in einem Skript kombinieren.
- Das zu vervollständigende Wort – so können Sie die Ausgabe auf das Präfix beschränken, das sowieso gefiltert wird.
- Das vorherige Wort – nützlich beispielsweise zum Vervollständigen von Optionen.
Dieselben Parameter werden an Vervollständigungsfunktionen ( complete -F somefunction
) übergeben. Beachten Sie, dass es Ihre Aufgabe ist, die gewünschten Übereinstimmungen herauszufiltern, unabhängig davon, ob Sie eine Funktion oder einen Befehl verwenden.
Bei dem, was Sie versucht haben, wird letztendlich der folgende Befehl ausgeführt apt-cache --no-generate pkgnames mys '' mys
. Dieser druckt eine Liste von Paketnamen, die mit mys
( beginnen apt-cache pkgnames
, betrachtet aber nur den ersten Operanden). Das längste gemeinsame Präfix ist mys
, daher beginnt Bash mit der Vervollständigung mys
und erwartet, dass Sie den nächsten Buchstaben auswählen.
Da die Argumente an den Befehl angehängt werden (und nicht als Positionsparameter übergeben werden – das Argument wird -C
als Shell-Befehl analysiert), gibt es keine einfache Möglichkeit, sie zu analysieren. Die einfachste Lösung ist die Verwendung einer Wrapper-Funktion.
_mys () {
COMPREPLY=$(apt-cache --no-generate pkgnames "$2")
}
complete -F _mys mys