# bash command-line completion for virtualbox # # This version of bash completion was born due to the need of fast and easy # access to the maze of commands and parameters VBoxManage provides. Based on # Sebastian[1] script I've managed to improve it and adapt to newest stable # version available in Gentoo Portage. # # [1] Sebastian T. Hafner # # # [x] adoptstate # [x] bandwidthctl # [ ] clonehd # [ ] clonevm # [ ] closemedium # [ ] controlvm # [ ] convertfromraw # [ ] createhd # [ ] createvm # [ ] debugvm # [ ] dhcpserver # [ ] discardstate # [ ] export # [ ] extpack # [ ] getextradata # [ ] guestcontrol # [ ] guestproperty # [ ] hostonlyif # [ ] import # [ ] list # [ ] metrics # [ ] modifyhd # [ ] modifyvm - a LOT options missing # [ ] natnetwork # [ ] registervm # [ ] setextradata # [ ] setproperty # [ ] sharedfolder # [ ] showhdinfo # [ ] showvminfo # [ ] snapshot # [ ] startvm # [ ] storageattach - no all options yet # [ ] storagectl # [ ] unregistervm # [ ] usbfilter _VBoxManage() { local cur prev opts vms vms cmd subcommand count item tmp name index # Generate registered hard disk files. # NOTE: This function may introduce some quirks, if there is a space or # other characters which usually are treated as IFS - like space. Pipe # character used in disk filename will ruin this completions. _hdd_comp() { local cur=$1 local hdds hdds=$(VBoxManage list hdds | \ grep -A 1 'normal (base)' | \ grep "Location:" | \ sed 's/Location:\s\+//' | \ sed 's/\s/\\ /g' | \ tr '\n' '|' | \ sed 's/|$//') IFS='|' read -ra hdds <<< "$hdds" for item in "${hdds[@]}" do [[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item") done } # Complete registered VM names. # Issues are the same as in above function. _vms_comp() { local cur=$1 local vms compopt -o filenames vms=$(VBoxManage list vms | \ awk -F ' {' '{ print $1 }' | \ tr '\n' '|' | \ sed 's/|$//' | \ sed 's/"//g') IFS='|' read -ra vms <<< "$vms" for item in "${vms[@]}" do [[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item") done } _list_comp() { local cur=$1 local list list=$(VBoxManage list | \ grep '|' | \ sed 's/\[.*\]//g'| \ sed 's/VBoxManage list//' | \ tr "\\n" " " | \ sed 's/$/\n/' | \ sed 's/\s\+//g' | \ sed 's/|/ /g') COMPREPLY=( $(compgen -W "$list" -- ${cur}) ) } # Check the COMP_WORDS looking for name of the vm. If name contain space or # is enclosed in quotes, glue name together in variable name. Variable index # will hold the last index of COMP_WORDS array which contain the end of the # name. _find_item_name() { local idx=$1 name="" while true do name="${NAME}${COMP_WORDS[$idx]}" [[ ${COMP_WORDS[$idx]} = *'"' ]] && break if [[ ${COMP_WORDS[$idx]} = '"'* || ${COMP_WORDS[$idx]} = *'\ ' ]] then idx=$((++idx)) continue fi break done index=$idx } _bandwidthctl_comp() { local rules cur=$1 _find_item_name 2 rules=$(VBoxManage bandwidthctl "${name//\\/}" \ list --machinereadable | \ awk -F ',' '{print $1}' | \ awk -F '=' '{print $2}' | \ tr '\n' '|' | \ sed 's/|$//' | \ sed 's/\s/\\ /g') IFS='|' read -ra rules <<< "$rules" for item in "${rules[@]}" do [[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item") done } _snapshot_comp() { local snap cur=$1 _find_item_name 2 snap=$(VBoxManage snapshot "${name//\\/}" \ list | \ awk -F ': ' '{print $2}' | \ sed 's/ (.*//' | \ tr '\n' '|' | \ sed 's/|$//' | \ sed 's/\s/\\ /g') IFS='|' read -ra snap <<< "$snap" for item in "${snap[@]}" do [[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item") done } COMP_WORDBREAKS=${COMP_WORDBREAKS//|/} # remove pipe from comp word breaks COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" lastbutone="${COMP_WORDS[COMP_CWORD-2]}" if [[ COMP_CWORD -ge 2 ]]; then cmd="${COMP_WORDS[1]}" if [[ $cmd == "-q" ]]; then cmd="${COMP_WORDS[2]}" fi fi # all possible commands for the VBoxManage opts=$(VBoxManage -q help | \ egrep -o "^\s\s[a-z]+ " | \ grep -v VBoxManage | \ awk '{print $1}'| \ sort | \ uniq) if [[ ${cur} == "-q" || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi case "${cmd}" in adoptstate) _vms_comp ${cur} ;; bandwidthctl) if [[ ${prev} == ${cmd} ]]; then _vms_comp ${cur} else _find_item_name 2 subcommand=${COMP_WORDS[$((index+1))]} if [[ " add set remove list " == *" $subcommand "* ]]; then case "${subcommand}" in add) tmp="" for i in --type --limit; do [[ " ${COMP_WORDS[@]} " == *" $i "* ]] && continue tmp="$tmp $i" done COMPREPLY=( $(compgen -W "$tmp" -- ${cur}) ) ;; set) if [[ ${prev} == "set" ]]; then _bandwidthctl_comp ${cur} else [[ " ${COMP_WORDS[@]} " != *" --limit "* ]] && \ COMPREPLY=( $(compgen -W "--limit" -- \ ${cur}) ) fi ;; remove) if [[ ${prev} == "remove" ]]; then _bandwidthctl_comp ${cur} fi ;; list) if [[ ${prev} == "list" ]]; then COMPREPLY=( $(compgen -W "--machinereadable" \ -- ${cur}) ) fi ;; esac case "${prev}" in --type) COMPREPLY=( $(compgen -W "disk network" -- ${cur}) ) ;; esac else [[ ${#COMPREPLY[@]} -eq 0 ]] && \ COMPREPLY=( $(compgen -W "add set remove list" \ -- ${cur}) ) fi fi ;; clonehd) ;; clonevm) ;; closemedium) ;; controlvm) ;; convertfromraw) ;; createhd) ;; createvm) ;; debugvm) ;; dhcpserver) ;; discardstate) ;; "export") ;; extpack) ;; getextradata) ;; guestcontrol) ;; guestproperty) ;; hostonlyif) ;; import) ;; list) ;; metrics) ;; modifyhd) ;; modifyvm) ;; natnetwork) ;; registervm) ;; setextradata) ;; setproperty) ;; sharedfolder) ;; showhdinfo) ;; showvminfo) ;; snapshot) ;; startvm) ;; storageattach) ;; storagectl) ;; unregistervm) ;; usbfilter) ;; esac } complete -o default -F _VBoxManage VBoxManage # vim: set ft=sh tw=80 sw=4 et :