# vboxmanage bash completion [SOLVED]

## gryf

Hej.

Piszę dopełnianie do komendy VBoxManage i zderzyłem się ze ścianą.

Otóż. Próbuję dopełnić komendę clonehd, która przyjmuje jako pierwszy parametr nazwę pliku, lub uuid. Jako że nazwa pliku jest nieco czytelniejsza niż  uuid, wyciągam sobie listę plików komendą VBoxManage, pakuję he do tablicy i… tu zaczynają się schody, bo to co dostaję obecnie to:

```
$ VBoxManage clonehd [tab]

haiku-alpha.vdi    devstack1.vdi      Wheeze.vdi         Debian stable.vdi

linux hehe.vdi     Ubuntu.vdi         Debian7.vdi        usb.vdi

$ VBoxManage clonehd /home

```

a chciałbym to:

```
$ VBoxManage clonehd [tab]

/home/gryf/.VirtualBox/HardDisks/haiku-alpha.vdi

/home/gryf/.VirtualBox/Machines/usb/usb.vdi

/home/gryf/.VirtualBox/Machines/Debian stable/Debian stable.vdi

/home/gryf/.VirtualBox/Machines/Wheeze/Wheeze.vdi

/home/gryf/.VirtualBox/Machines/Ubuntu/Ubuntu.vdi

/home/gryf/.VirtualBox/Machines/Debian7/Debian7.vdi

/home/gryf/.VirtualBox/Machines/devstack1/devstack1.vdi

/home/tmp/foo/linux hehe.vdi

$ VBoxManage clonehd /home

```

Najlepsze co zdołałem uzyskać to wybieranie pliku na "ślepo" - czyli zakładam, że użytkownik powinien wiedzieć gdzie znajdują sie pliki dysków maszyn wirtualnych. Kod, który obecnie załatwia mi dopełnienie:

```
_VBoxManage() {

    local cur prev opts vms vms cmd count item

    _hdcomp() {

        local cur=$1

        local hdds

        compopt -o default

        hdds=$(VBoxManage list hdds | \

            grep -A 1 'normal (base)' | \

            grep "Location:" | \

            sed 's/Location:\s\+//' | \

            tr '\n' '|' | \

            sed 's/|$//')

        IFS='|' read -ra hdds <<< "$hdds"

        for item in "${hdds[@]}"

        do

            [[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")

        done

    }

    COMPREPLY=()

    cur="${COMP_WORDS[COMP_CWORD]}"

    prev="${COMP_WORDS[COMP_CWORD-1]}"

    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 "${prev}" in

        ...

        ...

        ...

        showhdinfo|clonehd)

            _hdcomp ${cur}

            ;;

    esac

}

complete -o filenames -F _VBoxManage VBoxManage

```

Last edited by gryf on Sun Apr 12, 2015 6:07 pm; edited 1 time in total

----------

## gryf

Dotarłem do kompromisu który na razie mnie zadowala ;)

Wygląda to mniej więcej tak:

```

...

    _hdd_comp() {

        local cur=$1

        local hdds

        local item

        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 -o default -F _VBoxManage VBoxManage

```

Czyli, domyślne dopełnianie pozostaje domyślne ;) a nie filenames (bo tu akurat bardziej przeszkadza niż pomaga). Dwa, w funkcji  _hdd_comp dodaję cytowanie spacji. Wiem, że to się modelowo wyłoży na innych znakach (cudzysłowie, backslash, wszelkie gwiazdki, znaki zapytania itd), nie jest to jednak na tyle istotne (na razie) żebym się tym jakoś strasznie przejmował - spację w kontekście VirtualBoxa używam częściej niż innych znaków specjalnych.

----------

## gryf

Oto repozytoria skąd można pobrać gotowy skrypt (i może zgłosić jakiś błąd lub poprawkę :) :

https://bitbucket.org/gryf/vboxmanage-bash-completion

https://github.com/gryf/vboxmanage-bash-completion

----------

