Wenn ich wie ein Programm benutze svn
und Gnome Terminal eintippe:
svn upd
und drücke Tabes wird automatisch vervollständigt zu:
svn update
Kann ich so etwas in meinem benutzerdefinierten Bash-Skript tun?
Wenn ich wie ein Programm benutze svn
und Gnome Terminal eintippe:
svn upd
und drücke Tabes wird automatisch vervollständigt zu:
svn update
Kann ich so etwas in meinem benutzerdefinierten Bash-Skript tun?
Antworten:
Sie können die programmierbare Vervollständigung verwenden . Haben Blick auf /etc/bash_completion
und /etc/bash_completion.d/*
für einige Beispiele.
/usr/share/bash-completion/completions/<program>
The provided link has that already
- Heute vielleicht, aber morgen vielleicht nicht. Oder nächstes Jahr. Oder in einem Jahrzehnt. Was auch immer Sie vorschlagen, dass die Dokumentation immer noch relevant ist, Stack Overflow rät aus diesen Gründen von Nur-Link-Antworten ab.
Ich bin ein halbes Jahr zu spät, habe aber dasselbe gesucht und folgendes herausgefunden:
Sie müssen eine neue Datei erstellen:
/etc/bash_completion.d/foo
Für eine statische Autovervollständigung ( --help
/ --verbose
zum Beispiel) fügen Sie Folgendes hinzu:
_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 foo
COMP_WORDS
ist ein Array, das alle einzelnen Wörter in der aktuellen Befehlszeile enthält.COMP_CWORD
ist ein Index des Wortes, das die aktuelle Cursorposition enthält.COMPREPLY
ist eine Array-Variable, aus der Bash die möglichen Vervollständigungen liest.Und der compgen
Befehl gibt das Array von Elementen zurück, aus dem das aktuelle Wort stammt --help
, --verbose
und --version
stimmt mit diesem überein "${cur}"
:
compgen -W "--help --verbose --version" -- "<userinput>"
-
und" beginnen, ohne das Zielwort eingeben zu müssen, entfernen Sie einfach die Zeilen if [...] then
und fi
.
/etc/bash_completion.d/
. Ich bin nur hergekommen, weil ich irgendwo eine Antwort posten wollte, aber es stellte sich heraus, dass jemand die ganze Zeit drei Jahre voraus war :) Klares, präzises und vollständiges Beispiel, danke!
Alle Bash-Vervollständigungen werden in gespeichert /etc/bash_completion.d/
. Wenn Sie also Software mit bash_completion erstellen, lohnt es sich, die Datei deb / make install mit dem Namen der Software in diesem Verzeichnis abzulegen. Hier ist ein Beispiel für ein Bash-Abschlussskript für Rsync:
# bash completion for rsync
have 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
Es lohnt sich wahrscheinlich, eine der Bash-Abschlussdateien zu lesen, die Ihrem Programm am ehesten entspricht. Eines der einfachsten Beispiele ist die rrdtool
Datei.
source ~/.local/mycrazycompletion
in Ihren~/.bashrc
pkg-c
onfig --variable = completionsdir bash-completion` angegeben wurde, und dieses Verzeichnis ist die Empfehlung der oben verlinkten Bash Completion FAQ.
Hier ist ein komplettes Tutorial.
Nehmen wir ein Beispiel für ein Skript mit dem Namen admin.sh, an dem die automatische Vervollständigung ausgeführt werden soll.
#!/bin/bash
while [ $# -gt 0 ]; do
arg=$1
case $arg in
option_1)
# do_option_1
;;
option_2)
# do_option_1
;;
shortlist)
echo option_1 option_2 shortlist
;;
*)
echo Wrong option
;;
esac
shift
done
Optionsauswahlliste beachten. Wenn Sie das Skript mit dieser Option aufrufen, werden alle möglichen Optionen für dieses Skript ausgedruckt.
Und hier haben Sie das Autocomplete-Skript:
_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
Beachten Sie, dass das letzte zu vervollständigende Argument der Name des Skripts ist, zu dem Sie die automatische Vervollständigung hinzufügen möchten. Alles was Sie tun müssen, ist Ihr Autocomplete-Skript zu bashrc as hinzuzufügen
source /path/to/your/autocomplete.sh
oder kopieren Sie es nach /etc/bash.completion.d
prev
Variable? Sie scheinen es nicht zu benutzen.
-o nospace
Option?
Wenn Sie nur eine einfache wortbasierte automatische Vervollständigung wünschen (also keine Vervollständigung von Unterbefehlen oder ähnliches), verfügt der complete
Befehl über eine -W
Option, die genau das Richtige tut.
Zum Beispiel habe ich die folgenden Zeilen in meinem, .bashrc
um ein Programm namens jupyter automatisch zu vervollständigen :
# gleaned from `jupyter --help`
_jupyter_options='console qtconsole notebook' # shortened for this answer
complete -W "${_jupyter_options}" 'jupyter'
Jetzt wird es jupyter <TAB> <TAB>
für mich automatisch vervollständigt.
Die Dokumente auf gnu.org sind hilfreich.
Es scheint, dass die IFS
Variable richtig eingestellt ist, aber das hat mir keine Probleme bereitet.
Verwenden Sie die folgende -o
Option , um die Dateinamenvervollständigung und die Standard-BASH-Vervollständigung hinzuzufügen :
complete -W "${_jupyter_options}" -o bashdefault -o default 'jupyter'
Um dies in zsh zu verwenden, fügen Sie den folgenden Code hinzu, bevor Sie den complete
Befehl in Ihrem ausführen ~/.zshrc
:
# make zsh emulate bash if necessary
if [[ -n "$ZSH_VERSION" ]]; then
autoload bashcompinit
bashcompinit
fi
bash jupyter <TAB><TAB>
?