Автоопределение возможных аргументов в сценарии оболочки для завершения
Вот сценарий оболочки, который делает некоторые вещи в соответствии с тем, с каким параметром он был вызван:
if [ $1 = "-add" ]
then
...
elif [ $1 = "-remove" ]
...
else
...
fi
Скрипт является исполняемым (ссылка на него была создана в /usr/bin
каталог). Итак, я могу вызвать его из оболочки, указав имя ссылки, добавленной в /usr/bin
,
Что я хочу, так это автоматическое определение возможных аргументов скрипта (в моем случае они -add
, -remove
во время звонка. Это означает, что когда я наберу команду, связанную с вызовом скрипта, то наберу -re
и нажмите кнопку вкладки, это предложит, что это -remove
и автозаполните это для меня.
Как аргументы должны быть определены, чтобы достичь этого?
Пытался создать псевдонимы в файле конфигурации оболочки или несколько ссылок в /usr/bin
каталог для всех возможных входов, и он работал нормально, но я не думаю, что это лучшее решение для этого.
2 ответа
Хотя это требует некоторой настройки вне вашего скрипта, добавить опции автозаполнения довольно просто.
Вот простой пример файла ~/.bash_completion, который добавляет автозаполнение --add и --remove для команды yourscript. В реальном случае вы, вероятно, захотите сгенерировать параметры, напрямую запросив скрипт; они жестко запрограммированы здесь для простоты.
_yourscript_complete()
{
# list of options for your script
local options="--add --remove"
# current word being completed (provided by stock bash completion)
local current_word="${COMP_WORDS[COMP_CWORD]}"
# create list of possible matches and store to ${COMREPLY[@}}
COMPREPLY=($(compgen -W "${options}" -- "$current_word"))
}
complete -F _yourscript_complete yourscript
Обратите внимание, что ~/.bash_completion создается только во время входа в систему, поэтому вам нужно будет создать другую оболочку входа в систему, чтобы увидеть изменения в действии. Возможно, вам также потребуется включить поиск файлов пользователя bash_completion в вашей системе.
Результат:
$ yourscript --<tab><tab>
--add --remove
Кажется, что завершение bash/zsh - это мощный инструмент, который может управлять вводом данных в оболочку так, как вы хотите.
В одном из других ответов были представлены некоторые пояснения о том, как это работает в bash.
Я пользователь zsh, так что, думаю, было бы не лишним показать, как я справился с этой задачей:
Настройка
.zshrc
файл:добавление папки для ваших функций автозаполнения:
fpath=(~/.zsh-completions $fpath)
включение zsh tab-complete system:
autoload -U compinit & compinit
Примечание: надстрочные строки должны быть добавлены к
~/.zshrc
файл.Добавление функции для вашего скрипта:
После настройки файла.zshrc перезапустите zsh и введите
scriptname
в нем функция compinit() выведет список всех файлов с$fpath
и найти тот, у которого первая строка совпадает#compdef scriptname
,Итак, новый файл
_scriptname
который будет содержать функцию для нашего скрипта должен быть добавлен в~/.zsh-completions
каталог. Чтобы позволить compinit() найти этот файл наscriptname
набрав, как упоминалось выше, его первая строка должна быть:#compdef scriptname
,Пусть аргументы танцуют
Для zsh есть много примеров функций завершения в
/usr/share/zsh/functions/Completion
каталог. Найдя подходящий там, вы можете настроить вход оболочки в соответствии со своими вкусами. Для автоматического определения атрибутов (в моем случае они-add
а также-remove
)_attributes()
функция в_scriptname
Файл может быть установлен следующим образом:_arguments -s \ '(-a --add)'{-a,--add}'[adding a new item to the basket]' \ '(-r --remove)'{-r,--remove}'[removing an item from the basket]'
В конце концов, после перезапуска Zsh снова, автоопределение для scriptname
работает как показано ниже:
scriptname -<TAB> => scriptname - --add -a -- adding a new item to the basket --remove -r -- removing an item from the basket scriptname --a<TAB> => scriptname --add scriptname --r<TAB> => scriptname --remove