Добавить автозаполнение для пользовательского скрипта

В настоящее время я работаю над сценарием оболочки, который я назвал makeyourself.sh (связанным с /usr/bin/mys ), который автоматически устанавливает пакет debian из исходного кода (через apt-get source -b $1 ).

Поэтому я решил добавить функцию автозаполнения для имени пакета, который указан в качестве первого параметра: sudo mys panth<tab><tab> должен затем перечислить каждый пакет, начинающийся с panth – моя попытка была следующей:

 complete -C "apt-cache --no-generate pkgnames" mys 

Но, похоже, это не работает: когда я нажимаю клавишу табуляции, как упоминалось выше, при изменении параметра на mys , который возвращает мне sudo mys mys .

Что я делаю не так? Должен ли я указывать местоположение в команде, где complete должен вставить строку, которая должна быть заполнена, например {} или $1 ?

Я использую ElementaryOS, дистрибутив Linux на основе Ubuntu. Скрипт представляет собой стандартный скрипт оболочки * .sh, который использует стандартный #!/bin/bash

Как вы подозреваете, команда получает некоторую информацию о том, что нужно завершить. Это задокументировано в руководстве, но не в документации complete встроенного устройства , вам необходимо прочитать вводный раздел о программируемом завершении .

вызывается любая функция оболочки или команда, заданная параметрами -F и -C . Когда вызывается команда или функция, COMP_LINE , COMP_POINT , COMP_KEY и COMP_TYPE присваиваются значениям, как описано выше (см. Bash Variables ). Если вызывается COMP_WORDS COMP_CWORD , также устанавливаются переменные COMP_WORDS и COMP_CWORD . Когда функция или команда вызывается, первым аргументом является имя команды, аргументы которой завершаются, второй аргумент – это завершаемое слово, а третий аргумент – слово, предшествующее слову, которое завершается в текущей командной строке. Выполняется фильтрация сгенерированных завершений в отношении выполняемого слова; функция или команда имеют полную свободу в создании матчей.

Таким образом, команда вызывается с тремя параметрами:

  • Имя команды – поэтому вы можете комбинировать доработки для похожих команд в одном скрипте.
  • Слово, которое будет завершено, чтобы вы могли ограничить вывод префиксом, который будет фильтроваться в любом случае.
  • Предыдущее слово – полезно, например, для завершения настроек.

Те же параметры передаются в функции завершения ( complete -F somefunction функция complete -F somefunction ). Обратите внимание, что независимо от того, используете ли вы функцию или команду, ваша задача заключается в фильтрации желаемых совпадений.

С помощью того, что вы пытались, команда, которая заканчивается тем, что выполняется, – apt-cache --no-generate pkgnames mys '' mys . Это выводит список имен пакетов, начинающихся с mys ( apt-cache pkgnames смотрит только на первый операнд). Самый длинный общий префикс – mys , поэтому bash начинает mys и ожидает, что вы выберете следующую букву.

Учитывая, что аргументы добавляются к команде (не передаются как позиционные параметры – аргумент -C анализируется как команда оболочки), нет простого способа их анализа. Самое простое решение – использовать функцию обертки.

 _mys () { COMPREPLY=$(apt-cache --no-generate pkgnames "$2") } complete -F _mys mys