Wprowadzenie do bash zakończenia: część 2


Original: https://www.debian-administration.org/article/317/An_introduction_to_bash_completion_part_2

Wysłany przez Steve sob 24 grudzień 2005 03:00
Tagi: bash, zakończenie polecenia

Wcześniej pokazaliśmy jak dodać podstawowe wykonania polecenia, za pomocą urządzeń, które już zostały dostarczone przez bash zakończenia procedury. W tej drugiej części, pokazujemy jak dodać całkowicie nowy zwyczaj zakończeniu polecenia.

W części pierwszej patrzyliśmy na dodanie hosta zakończenia do dowolnego polecenia przez wykonywanie:

complete -F _known_hosts xvncviewer

 

To wykorzystuje pełną polecenia powiedzieć bash, że funkcja _known_hosts powinny być używane do obsługi zakończeniu argumenty do xvncviewer.

Jeśli chcemy, aby dodać niestandardowe wypełnienia polecenia będziemy zamiast pisania własnych funkcji i bind, który na polecenie.
Prosty przykład

Przykładowo najpierw przyjrzymy dodając kilka prostych uzupełnień do binarnego foo. Ten hipotetyczny polecenia wymaga trzech argumentów:

--help
Pokazuje opcje pomocy dla foo i wychodzi.
--version
Pokazuje wersję polecenia foo i wychodzi.
--verbose
Działa pliczek z dodatkowych szczegółowości

Aby obsługiwać te argumenty, tworzymy nowy plik /etc/bash_completion.d/foo. Plik ten będzie automatycznie pochodzą (lub załadowane) gdy kod zakończenia bash jest załadowany.

Wewnątrz tego pliku Zapisz poniższy tekst:

_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

Aby przetestować go można teraz Źródło pliku:

[email protected]:~$ . /etc/bash_completion.d/foo
[email protected]:~$ foo --[TAB]
--help     --verbose  --version

 

Jeśli eksperymentu, zobaczysz, że to pomyślnie zakończy argumenty, zgodnie z oczekiwaniami. Wpisz “foo --h[TAB]” i pomocy argumentu jest zakończona. Naciśnij klawisz [TAB] kilka razy, a zobaczysz wszystkie opcje. (W tym przypadku nie ma faktycznie znaczenia jeśli nie masz plik binarny o nazwie foo zainstalowany na Twoim systemie.)

Więc teraz, że mamy coś pracy powinniśmy patrzeć na jak to naprawdę działa!

Jak działa zakończenia

Poprzedni przykład pokazał funkcję prosty waln¹æ, który został wywołany do obsługi realizacji polecenia.

Ta funkcja rozpoczyna poprzez zdefiniowanie niektórych zmiennych waluta jest bieżące słowo jest wpisany, poprzedni jest poprzednie słowo wpisane i zadecyduje, który jest naszą listę komend do wykonania.

Opcja zakończenia jest następnie przetwarzane przez użycie polecenia compgen przez ten wiersz:

COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )

 

Co to jest zestaw wartość $COMPREPLY na dane wyjściowe polecenia:

compgen -W "${opts}" -- ${cur}

 

Jeśli zastąpisz tych zmiennych z ich treści, zobaczysz, jak to działa:

compgen -W "--help --verbose --version" -- "userinput"

 

To polecenie próbuje powrócić mecz bieżące słowo “${cur}” z listy “--help --verbose --version“. Po uruchomieniu tego polecenia w powłoce, będziesz mógł eksperymentować z nim i zobaczyć jak to działa:

[email protected]:~$ compgen -W "--help --verbose --version" -- --
--help
--verbose
--version
[email protected]:~$ compgen -W "--help --verbose --version" -- --h 
--help

 

Tutaj po raz pierwszy zobaczyć co się dzieje, jeśli użytkownik wpisze po prostu “–“-wszystkie trzy opcje dopasowania więc są zwracane. W drugiej próbie użytkownik wprowadzi–h i to wystarczy, aby określić–pomoc jednoznacznie, tak że jest zwracany.

W naszej funkcji możemy po prostu zestaw “COMPREPLY” do tego wynik i powrót. Pozwala to bash zastąpić nasz słowo bieżącej produkcji. COMPREPLY jest specjalną zmienną, która ma szczególne znaczenie w bashu. Wewnątrz zakończenia procedur jest używany do określenia danych wyjściowych w próbie zakończenia.

Z basha Podręcznik możemy przeczytać opis COMPREPLY:

COMPREPLY

Zmiennej tablicy, z której Bash czyta możliwych uzupełnień wygenerowane przez funkcję powłoki, wywoływana przez obiekt programowalne dopełnianie

Możemy także zobaczyć, jak możemy znaleźć bieżące słowo za pomocą tablicy COMP_WORDS znaleźć bieżącego i poprzedniego wyrazu patrząc im się:

COMP_WORDS

Zmienną tablicową składający się z poszczególnych słów w bieżącym wierszu polecenia. Zmienna ta jest dostępna tylko w funkcji powłoki wywoływane przez obiekty programowalne dopełnianie.

COMP_CWORD

Indeks do ${COMP_WORDS} słowa zawierające bieżącej pozycji kursora. Zmienna ta jest dostępna tylko w funkcji powłoki wywoływane przez obiekty programowalne dopełnianie

Przykład złożony

Wiele poleceń jest bardziej skomplikowane, aby wypełnić i ma wiele opcji, które zależą od ich poprzednie.

Jako przykład odpowiednie statki Xen z polecenia o nazwie xm ma pewne podstawowe opcje:

 

  • xm list

Listę wszystkich uruchomionych instancji Xen

  • xm create ConfigName

Utworzenie nowej instancji Xen, używając pliku konfiguracyjnego w /etc/xen o nazwie ConfigName.

  • xm console Name

Połączyć konsolę z uruchomioną maszyną o nazwie “Nazwa”.

 

W ogóle polecenia jest “xm operacji argumenty”, gdzie “argumenty” zmienia się w zależności od początkowej operacji wybranych.

Konfigurowanie podstawowych zakończenia początkowej operacji mogą być obsługiwane w wiele takie same jak poprzedniego przykładu jedyną różnicą jest, że operacje nie zaczynają się od “-” prefiks. Jednak ukończenie argumentów wymaga specjalnej obsługi.

Jeśli ty żądać zwrotu pieniędzy mamy dostęp do poprzedni token na linii poleceń i przy użyciu, że możemy podjąć różne działania dla każdej operacji.

Przykładowy kod wygląda tak:

_xm() 
{
    local cur prev opts base
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    #
    #  The basic options we'll complete.
    #
    opts="console create list"


    #
    #  Complete the arguments to some of the basic commands.
    #
    case "${prev}" in
	console)
	    local running=$(for x in `xm list --long | grep \(name | grep -v Domain-0 | awk '{ print $2 }' | tr -d \)`; do echo ${x} ; done )
	    COMPREPLY=( $(compgen -W "${running}" -- ${cur}) )
            return 0
            ;;
        create)
	    local names=$(for x in `ls -1 /etc/xen/*.cfg`; do echo ${x/\/etc\/xen\//} ; done )
	    COMPREPLY=( $(compgen -W "${names}" -- ${cur}) )
            return 0
            ;;
        *)
        ;;
    esac

   COMPREPLY=($(compgen -W "${opts}" -- ${cur}))  
   return 0
}
complete -F _xm xm

 

Tutaj mamy instalacji wstępnej realizacji operacji, a następnie dodano obsługę specjalne dla dwóch operacji “tworzenia” i “konsoli”. W obu przypadkach możemy użyć compgen do wykonania danych wejściowych w oparciu o tekst, który jest dostarczany przez użytkownika, w porównaniu z dynamicznie utworzona lista.

“Konsoli” działania, które możemy wykonać w oparciu dane wyjściowe tego polecenia:

xm list --long | grep \(name | grep -v Domain-0 | awk '{ print $2 }' | tr -d \)

 

To daje nam listę bieżących systemów Xen.

Do tworzenia operacji, które możemy wykonać w oparciu dane wyjściowe tego polecenia:

for x in `ls -1 /etc/xen/*.cfg`; do echo ${x/\/etc\/xen\//} ; done

To ma listę katalogów w katalogu /etc/xen i wyświetla nazwy plików w .cfg. Na przykład:

[email protected]:~$ for x in `ls -1 /etc/xen/*.cfg`; do echo ${x/\/etc\/xen\//}; done
etch.cfg
root.cfg
sarge.cfg
steve.cfg
x.cfg
[email protected]:~$

Inne zakończenie

Za pomocą polecenia compgen pokazaliśmy, jak dopasować danych wejściowych użytkownika przeciwko poszczególnych ciągów, zarówno za pomocą ustalonego wyborów, jak i przy użyciu danych wyjściowych polecenia.

Jest to również możliwe dopasowanie nazwy katalogu, nazwy procesów i inne rzeczy. Zobacz Podręcznik bash pełny opis przez kolejny “bash człowieka”.

Końcowy przykład ilustruje kompletne pliki i nazw hostów w odpowiedzi na dwie opcje początkowe:

#
#  Completion for foo:
#
#  foo file [filename]
#  foo hostname [hostname]
#
_foo() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="file hostname"
 
    case "${prev}" in
	file)
	    COMPREPLY=( $(compgen -f ${cur}) )
            return 0
            ;;
        hostname)
	    COMPREPLY=( $(compgen -A hostname ${cur}) )
            return 0
            ;;
        *)
        ;;
    esac

    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
}
complete -F _foo foo

 

Przy użyciu tych przykładów teraz należy możliwość tworzenia własnych funkcji niestandardowych zakończenia. 95% czasu, tylko trzeba zakończyć z zestawu dostępnych opcji, czasów, które będziesz musiał zajmować się argumentem dynamiczne generowanie wiele jak to było polecenie xm.

Podział opcji na zbiór małych rur i ich testowanie spoza środowiska zakończenia (w łupinach) jest prawdopodobnie najlepszym rozwiązaniem, następnie raz masz wiersz polecenia pracy po prostu wklej go do swojej funkcji.

Dla odniesienia mój kod zakończenia xm można znaleźć online.