завершение bash _parse_help не работает? - PullRequest
2 голосов
/ 28 февраля 2012

Чтобы получить легкое завершение bash для ключей командной строки моих скриптов, я изучил функцию _parse_help в / etc / bash_completion (sid debian, bash v4.2-1, bash-creation v1: 1.99-3).

Мой скрипт генерирует справочное сообщение в том, что я считаю стандартным форматом GNU:

MYSCRIPT [OPTIONS]

Usage:
  -h, --help     Show this help message
  -o, --option   Some option

Затем я активирую завершение с помощью complete -F _parse_help ./myscript.

К сожалению, это делаетне дать желаемого результата.На первой вкладке ./myscript <TAB> (обратите внимание, только одно нажатие клавиши) появляется неформатированный список, содержащий --help и --option, а не сокращенные версии.Хуже того, завершение любого варианта завершается неудачно.На самом деле, просто набирая тире, _parse_help полностью прекращает генерировать выходные данные.

Все это выглядит очень испорченным, и я не могу найти много ссылок на него в Интернете.Возможно, эта функция считается устаревшей?Есть ли другой стандартный метод завершения командной строки, основанный на анализе вывода --help?

1 Ответ

5 голосов
/ 17 декабря 2012

Согласно справочному руководству bash -F function ожидает чтения списка слов из переменной COMPREPLY

Может показаться, что _parse_help не устанавливает эту обязательную переменную и поэтому не подходит в качестве функции для complete -F. Выходные данные, очевидно, отражены, как видно из выполнения функции.

$ _parse_help ./myscript 
-h
--help
-o
--option

@ gertjan То, что вы пытались сделать, может быть выполнено с использованием опции -W wordlist.

$ complete -W "$(_parse_help ./myscript)" ./myscript 
$ ./myscript -
--help    --option  -h        -o
$ ./myscript --
--help    --option
$ ./myscript --help

Завершение работает должным образом, и --h завершит --help или там, где было несколько аргументов, например, с "-", будет отображен только соответствующий параметр.

Если мы пытались использовать функцию, однако одного этого недостаточно, чтобы установить только COMPREPLY, как вы увидите из следующего примера.

ПРИМЕЧАНИЕ: COMPREPLY является массивом bash и требует скобок () при установке

$ function _myscript () { 
>     COMPREPLY=($(_parse_help ./myscript))
> }
$ complete -F _myscript ./myscript 
$ ./myscript -
--help    --option  -h        -o
$ ./myscript --
--help    --option  -h        -o
$ ./myscript --help
--help    --option  -h        -o  

Как видите, несмотря на то, что параметры отображаются, complete теперь ожидает, что мы выполним фильтрацию. Мы можем сделать это с помощью compgen, но сначала нам нужно определить, против чего будет фильтроваться текущий аргумент. Функция _get_comp_words_by_ref может помочь с этим, заполнив переменную $cur, как в нашем последнем примере.

Полная реализация с использованием функции с _parse_help для завершения bash.

$ function _myscript () {
>     _get_comp_words_by_ref cur
>     COMPREPLY=($(compgen -W "$(_parse_help ./myscript)" -- "$cur"))
> }
$ complete -F _myscript ./myscript 
$ ./myscript - 
--help    --option  -h        -o
$ ./myscript --
--help    --option
$ ./myscript --help

NJoy!

...