Quando uso un programma simile svn
e digito Gnome Terminal:
svn upd
e premi Tabè completato automaticamente per:
svn update
È possibile fare qualcosa del genere nel mio script bash personalizzato?
Quando uso un programma simile svn
e digito Gnome Terminal:
svn upd
e premi Tabè completato automaticamente per:
svn update
È possibile fare qualcosa del genere nel mio script bash personalizzato?
Risposte:
È possibile utilizzare il completamento programmabile . Dai un'occhiata /etc/bash_completion
e /etc/bash_completion.d/*
per alcuni esempi.
/usr/share/bash-completion/completions/<program>
The provided link has that already
- potrebbe essere oggi, ma potrebbe non domani. O l'anno prossimo. O tra un decennio. Qualunque cosa tu possa suggerire sulla documentazione ancora pertinente, Stack Overflow scoraggia le risposte di solo collegamento per questi motivi.
Sono in ritardo di sei mesi ma stavo cercando la stessa cosa e ho trovato questo:
Dovrai creare un nuovo file:
/etc/bash_completion.d/foo
Per un completamento automatico statico ( --help
/ --verbose
ad esempio) aggiungi questo:
_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
è un array che contiene tutte le singole parole nella riga di comando corrente.COMP_CWORD
è un indice della parola contenente la posizione corrente del cursore.COMPREPLY
è una variabile di matrice da cui Bash legge i possibili completamenti.E il compgen
comando restituisce la matrice di elementi --help
, --verbose
e --version
corrispondenti la parola corrente "${cur}"
:
compgen -W "--help --verbose --version" -- "<userinput>"
-
e mostrarli senza dover iniziare a digitare la parola target, basta rimuovere le righe if [...] then
e fi
.
/etc/bash_completion.d/
. Sono venuto qui solo perché volevo pubblicare una risposta da qualche parte, ma si è scoperto che qualcuno era avanti di tre anni :) Esempio chiaro, conciso e completo, grazie!
Tutti i completamenti di bash sono memorizzati in /etc/bash_completion.d/
. Quindi, se stai creando software con bash_completion, varrebbe la pena che il deb / make install rilasci un file con il nome del software in quella directory. Ecco un esempio di script di completamento bash per 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
Sarebbe probabilmente utile rivedere uno dei file di completamento di bash che si avvicinano maggiormente al tuo programma. Uno degli esempi più semplici è il rrdtool
file.
source ~/.local/mycrazycompletion
tuo~/.bashrc
pkg-c
onfig --variable = completionsdir bash-completamento` e quella directory è la raccomandazione data dalle Domande frequenti sul completamento di Bash collegate sopra.
Ecco un tutorial completo.
Consente di avere un esempio di script chiamato admin.sh in cui si desidera far funzionare il completamento automatico.
#!/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
Lista delle opzioni nota. La chiamata allo script con questa opzione stamperà tutte le opzioni possibili per questo script.
E qui hai lo script di completamento automatico:
_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
Si noti che l'ultimo argomento da completare è il nome dello script a cui si desidera aggiungere il completamento automatico. Tutto quello che devi fare è aggiungere il tuo script di completamento automatico a bashrc come
source /path/to/your/autocomplete.sh
o copiarlo su /etc/bash.completion.d
prev
variabile? Sembra che non lo usi.
-o nospace
opzione?
Se tutto ciò che desideri è un semplice completamento automatico basato su parole (quindi nessun completamento dei sottocomandi o altro), il complete
comando ha -W
un'opzione che fa proprio la cosa giusta.
Ad esempio, ho le seguenti righe nel mio .bashrc
per completare automaticamente un programma chiamato jupyter :
# gleaned from `jupyter --help`
_jupyter_options='console qtconsole notebook' # shortened for this answer
complete -W "${_jupyter_options}" 'jupyter'
Ora si jupyter <TAB> <TAB>
completa automaticamente per me.
I documenti su gnu.org sono utili.
Sembra fare affidamento sul fatto che la IFS
variabile sia impostata correttamente, ma ciò non ha causato problemi per me.
Per aggiungere il completamento del nome file e il completamento BASH predefinito, utilizzare l' -o
opzione:
complete -W "${_jupyter_options}" -o bashdefault -o default 'jupyter'
Per usarlo in zsh, aggiungi il seguente codice prima di eseguire il complete
comando nel tuo ~/.zshrc
:
# make zsh emulate bash if necessary
if [[ -n "$ZSH_VERSION" ]]; then
autoload bashcompinit
bashcompinit
fi
bash jupyter <TAB><TAB>
?