bash-creation - функция завершения, определенная при первом вызове команды
Я добавил новый псевдоним scp_using_rsync
, который использует rsync для копирования файлов через SSH с определенными параметрами. Я хотел связать завершение bash для scp с этим псевдонимом.
Это работает, когда я добавляю эту строку:
complete -o bashdefault -o default -o nospace -F _scp scp_using_rsync 2>/dev/null || complete -o default -o nospace -F _scp scp_using_rsync
Единственная проблема в том, что я замечаю, _scp
определяется в моей среде bash, только после того, как я попробую завершить табуляцию с помощью ssh / scp хотя бы один раз в этой оболочке. Так что, если я бегу напрямую scp_using_rsync
в новой оболочке я бы получил _scp
не найдена ошибка.
Выход из typeset -F
в новой оболочке до и после попытки завершения табуляции для команд ssh или scp ясно указывается, что следующие функции определяются после попытки завершения табуляции в первый раз:
$ diff ~/.scratch/file1 ~/.scratch/file2
224a225,227
> declare -f _scp
> declare -f _scp_local_files
> declare -f _scp_remote_files
226a230
> declare -f _sftp
230a235,240
> declare -f _ssh
> declare -f _ssh_ciphers
> declare -f _ssh_macs
> declare -f _ssh_options
> declare -f _ssh_suboption
> declare -f _ssh_suboption_check
Эти функции, кажется, определены в /usr/share/bash-completion/completions/ssh
в моей системе.
Это мои 2 взаимосвязанных вопроса:
- Как bash определяет, где автоматически выбирать определения и определять их при первой попытке завершения?
- Как я должен связать Bash-завершение для
scp_using_rsync
подобным образом завершить работу scp?
3 ответа
Bash 4.1
добавил новый -D
вариант для complete
, compgen
а также compopt
:
Новая опция complete/compgen/compopt -D для определения завершения по умолчанию: завершение, которое будет вызываться по команде, для которой не определено завершение. Если эта функция возвращает 124, снова выполняется попытка программируемого завершения, что позволяет пользователю динамически создавать набор завершений при попытке завершения, если функция завершения по умолчанию устанавливает отдельные функции завершения каждый раз, когда она вызывается.
Вот пример из руководства Bash:
_completion_loader()
{
. "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
}
complete -D -F _completion_loader
У меня была проблема с применением ответа whjm. Как заметил Tuxdude, там уже была функция _completion_loader
определено в моем дистрибутиве (Ubuntu 14.04). Функция была определена следующим образом:
_completion_loader ()
{
local compfile=./completions;
[[ $BASH_SOURCE == */* ]] && compfile="${BASH_SOURCE%/*}/completions";
compfile+="/${1##*/}";
[[ -f "$compfile" ]] && . "$compfile" &> /dev/null && return 124;
complete -F _minimal "$1" && return 124
}
Я хотел, чтобы все операции заканчивались в одном месте, поэтому я добавил файл в /usr/share/bash-completion/completions/
с именем команды, для которой я хотел бы добавить завершение. Для вашего случая вы можете добавить файл с именем scp_using_rsync
содержащий это:
cfile="${compfile%/*}/scp"
cmd="${1##*/}"
. "$cfile"
complete -F _scp $cmd
Это будет исходный файл, который определяет дополнения для scp
, в том числе _scp
функции, а затем добавьте завершение для вашей команды. Я чувствовал, что это более прямой и последовательный способ (хотя, конечно, чтобы сделать это, вы должны согласиться с изменением этого поведения для всех пользователей.)
Некоторые функции завершения загружаются динамически. Вы можете вручную загрузить их, чтобы они работали с псевдонимами. Например, вы можете добавить это к вашему ~/.bashrc
так что завершение будет работать с вашим псевдонимом.
_completion_loader docker