Когда я использую программу, подобную svn и я набираю в терминале Gnome:
svn updи ударил Tab он автоматически заполняется до:
svn updateМожно ли сделать что-то подобное в моем пользовательском скрипте bash?
Когда я использую программу, подобную svn и я набираю в терминале Gnome:
svn updи ударил Tab он автоматически заполняется до:
svn updateМожно ли сделать что-то подобное в моем пользовательском скрипте bash?
Вам нужно будет создать новый файл:
/etc/bash_completion.d/fooДля статического автозаполнения (--help / --verbose например) добавьте это:
_foo() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--help --verbose --version" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi}complete -F _foo fooCOMP_WORDS представляет собой массив, содержащий все отдельные слова в текущей командной строке.COMP_CWORD является индексом слова, содержащего текущую позицию курсора.COMPREPLY это переменная массива, из которой Bash считывает возможные завершения.И compgen команда возвращает массив элементов из --help, --verbose и --version соответствие текущему слову "${cur}":
compgen -W "--help --verbose --version" -- "<userinput>"
Вот полный учебник.
Давайте рассмотрим пример скрипта, который называется admin.sh к которому вы хотели бы, чтобы автозаполнение работало.
#!/bin/bashwhile [ $# -gt 0 ]; do arg=$1 case $arg in option_1) # do_option_1 ;; option_2) # do_option_2 ;; shortlist) echo option_1 option_2 shortlist ;; *) echo Wrong option ;; esac shiftdoneОбратите внимание на опцию shortlist. Вызов скрипта с этой опцией выведет все возможные параметры для этого скрипта.
И вот у вас есть сценарий автозаполнения:
_script(){ _script_commands=$(/path/to/your/script.sh shortlist) local cur COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=( $(compgen -W "${_script_commands}" -- ${cur}) ) return 0}complete -o nospace -F _script ./admin.shОбратите внимание, что последним аргументом для завершения является имя скрипта, к которому вы хотите добавить автозаполнение. Все, что вам нужно сделать, это добавить свой скрипт автозаполнения в bashrc как
source /path/to/your/autocomplete.shили скопируйте его в/etc/bash.completion.d
Вы можете использовать Программируемое Завершение. Взгляните на /etc/bash_completion и /etc/bash_completion.d/* для некоторых примеров.
Все завершения bash хранятся в /etc/bash_completion.d/. Так что, если вы создаете программное обеспечение с помощью bash_completion, было бы целесообразно, чтобы deb/make install поместил файл с именем программного обеспечения в этот каталог. Вот пример сценария завершения bash для Rsync:
# bash completion for rsynchave rsync &&_rsync(){ # TODO: _split_longopt local cur prev shell i userhost path COMPREPLY=() cur=`_get_cword` prev=${COMP_WORDS[COMP_CWORD-1]} _expand || return 0 case "$prev" in --@(config|password-file|include-from|exclude-from)) _filedir return 0 ;; -@(T|-temp-dir|-compare-dest)) _filedir -d return 0 ;; -@(e|-rsh)) COMPREPLY=( $( compgen -W 'rsh ssh' -- "$cur" ) ) return 0 ;; esac case "$cur" in -*) COMPREPLY=( $( compgen -W '-v -q -c -a -r -R -b -u -l -L -H \ -p -o -g -D -t -S -n -W -x -B -e -C -I -T -P \ -z -h -4 -6 --verbose --quiet --checksum \ --archive --recursive --relative --backup \ --backup-dir --suffix= --update --links \ --copy-links --copy-unsafe-links --safe-links \ --hard-links --perms --owner --group --devices\ --times --sparse --dry-run --whole-file \ --no-whole-file --one-file-system \ --block-size= --rsh= --rsync-path= \ --cvs-exclude --existing --ignore-existing \ --delete --delete-excluded --delete-after \ --ignore-errors --max-delete= --partial \ --force --numeric-ids --timeout= \ --ignore-times --size-only --modify-window= \ --temp-dir= --compare-dest= --compress \ --exclude= --exclude-from= --include= \ --include-from= --version --daemon --no-detach\ --address= --config= --port= --blocking-io \ --no-blocking-io --stats --progress \ --log-format= --password-file= --bwlimit= \ --write-batch= --read-batch= --help' -- "$cur" )) ;; *:*) # find which remote shell is used shell=ssh for (( i=1; i < COMP_CWORD; i++ )); do if [[ "${COMP_WORDS[i]}" == -@(e|-rsh) ]]; then shell=${COMP_WORDS[i+1]} break fi done if [[ "$shell" == ssh ]]; then # remove backslash escape from : cur=${cur/\\:/:} userhost=${cur%%?(\\):*} path=${cur#*:} # unescape spaces path=${path//\\\\\\\\ / } if [ -z "$path" ]; then # default to home dir of specified # user on remote host path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null) fi # escape spaces; remove executables, aliases, pipes # and sockets; add space at end of file names COMPREPLY=( $( ssh -o 'Batchmode yes' $userhost \ command ls -aF1d "$path*" 2>/dev/null | \ sed -e 's/ /\\\\\\\ /g' -e 's/[*@|=]$//g' \ -e 's/[^\/]$/& /g' ) ) fi ;; *) _known_hosts_real -c -a "$cur" _filedir ;; esac return 0} &&complete -F _rsync $nospace $filenames rsync# Local variables:# mode: shell-script# sh-basic-offset: 4# sh-indent-comment: t# indent-tabs-mode: nil# End:# ex: ts=4 sw=4 et filetype=shВероятно, было бы целесообразно просмотреть один из файлов завершения bash, который наиболее точно соответствует вашей программе. Одним из простейших примеров является rrdtool файл.
Если все, что вам нужно, - это простое автоматическое завершение на основе слов (так что никакого завершения подкоманды или чего-то еще), то complete команда имеет -W вариант, который просто делает правильные вещи.
Например, у меня есть следующие строки в моем .bashrc для автозаполнения программы, вызываемой юпитер:
# gleaned from `jupyter --help`_jupyter_options='console qtconsole notebook' # shortened for this answercomplete -W "${_jupyter_options}" 'jupyter'Сейчас jupyter <TAB> <TAB> автозаполнение для меня.
То доктора в gnu.org полезны.
Похоже, это действительно зависит от IFS переменная установлена правильно, но это не вызвало у меня никаких проблем.
Чтобы добавить завершение имени файла и завершение BASH по умолчанию, используйте -o вариант:
complete -W "${_jupyter_options}" -o bashdefault -o default 'jupyter'Чтобы использовать это в zsh, добавьте следующий код перед запуском complete командование в вашем ~/.zshrc:
# make zsh emulate bash if necessaryif [[ -n "$ZSH_VERSION" ]]; then autoload bashcompinit bashcompinitfi
Просто добавляю это сюда на случай, если это кому-нибудь поможет.
Помимо примеров, окончательным источником / ссылкой для получения дополнительной информации по этой теме является само руководство по bash (т.е. Введите man bash в терминале)
Поиск по заголовкам "Завершение" и "Программируемое завершение". (в текущей версии документации bash они отображаются в строках 2219 и 2332 соответственно), а также соответствующие встроенные ключевые слова bash, на которые ссылаются в этих разделах (например, compgen (строка 2627), complete (строка 2637) и т.д.)
при использовании скрипта в консоли
объясните “сценарий bash”, вы имеете в виду при редактировании сценария? что ты хочешь с этим делать?
Что касается места, куда поместить ваши дополнения, см. этот вопрос, а также комментарии к принятому ответу там.