bash comletion - требуется помощь:


bliznezz аватар

bliznezz - Posted on 08 Декабрь 2009

есть такая СУБД Sybase ASE.
в её состав входит несколько утилиток, в т.ч. isql (не ODBC-шый, а свой)

он хочет параметры такие:

# isql [-b] [-e] [-F] [-p] [-n] [-v] [-X] [-Y] [-Q]
# [-a display_charset] [-A packet_size] [-c cmdend] [-D database]
# [-E editor [-h header [-H hostname [-i inputfile]
# [-I interfaces_file] [-J client_charset] [-K keytab_file]
# [-l login_timeout] [-m errorlevel] [-M labelname labelvalue]
# [-o outputfile] [-P password] [-R remote_server_principal]
# [-s col_separator] [-S server_name] [-t timeout] [-U username]
# [-V [security_options]] [-w column_width] [-z localename]
# [-Z security_mechanism]

но меня интересуют автодополнение по: параметрам: -S -i -o -w
-S -список серверов, берется из файла интерфейсов:

server1
    master tcp ether 192.168.1.1 4100
    query tcp ether 192.168.1.1 4100
 
server2
    query tcp ether 192.168.1.2 5000
    query tcp ether 192.168.1.3 5000

вот такой строкой получаю список из файла:

egrep -v '(master\ |query\ |tcp\ ether)' $SYBASE/interfaces |  sed -e 's| ||g;s|\t||g' | grep -v "^$"
_isql_cmpl_servers ()
{
cur='_get_cword'
local servers=$(egrep -v '(master\ |query\ |tcp\ ether)' $SYBASE/interfaces |  sed -e 's| ||g;s|\t||g' | grep -v "^$")
COMPREPLY=( $(compgen -W '$(for i in $servers ; do echo "$i" ; done )' -- $cur ) )
}

далее: -i -o - это должны быть файлы на файловой системе.

-w - число, кратное 80 + два значения: 1000 и 2000(ширина экрана)
список можно получить echo "`seq 80 80 720` 1000 2000"

вооооот, теперь вопрос, как мне написать скрипт процедуры, который

isql <tab><tab> - выдаст список интересующих меня опций
isql -S<tab><tab> - список серверов
isql -Sblabla <tab><tab> - выдаст дальнейший список опций
isql -Sblabla -i<tab><tab>  - подстановка файлов с расширениями sql и без расширений.
isql -Sblabla -iinput.sql -o<tab><tab>  - подстановка файлов
isql -Sblabla -iinput.sql -ooutput.log -w<tab><tab>  - подстановка из списков чисел.

ну или хотя-бы расскажите принципы, на примере первых двух подстановок из списка.

Написать полноценную поддержку у такой сложной команды не очень-то просто. Для начала только еще замечу, что список серверов из файла указанного формата наверное лучше получать просто через grep -v '^[ \t]' "$SYBASE/interfaces". Далее, _get_cword() - это функция описанная в /etc/bash_completion и поэтому кавычки вокруг нее должны быть обратными, cur=`_get_cword`. Требование дополнять опции, в частности имена файлов, вплотную к буквам опций несколько необычно и создает дополнительные трудности. Если допустимо вводить -i input.sql -o output.log вместо -iinput.sql -ooutput.log, то лучше использовать этот формат.

Ну вот в качестве информации к размышлению:

# Put this file in /etc/bash_completion.d/ directory
 
have isql &&
_isql()
{
        local cur options
 
        COMPREPLY=()
        options='-b -e -F -p -n -v -X -Y -Q -a -A -c -D -E -h -H -i \
                 -I -J -K -l -m -M -o -P -R -s -S -t -U -V -w -z -Z'
        cur=`_get_cword`
        case $cur in
        -i*)
           local pattern tmp files=()
           pattern=${cur#-i}
           while read -r tmp; do
                [[ -n "$tmp" ]] && files[${#files[@]}]="-i$tmp"
           done < <( compgen -f -- "$(quote_readline "$pattern")" )
           COMPREPLY=("${files[@]}")
           ;;
 
        -o*)
           local pattern tmp files=()
           pattern=${cur#-o}
           while read -r tmp; do
                [[ -n "$tmp" ]] && files[${#files[@]}]="-o$tmp"
           done < <( compgen -f -- "$(quote_readline "$pattern")" )
           COMPREPLY=("${files[@]}")
           ;;
 
        -S*)
           local pattern tmp servers=''
           pattern=${cur#-S}
           while read tmp; do
                [[ -n "$tmp" ]] && servers="-S$tmp $servers"
           done < <( /bin/grep -v '^[ \t]' "$SYBASE/interfaces" )
           COMPREPLY=( $(compgen -W "$servers" -- $cur) )
           ;;      
 
        -w*)
           COMPREPLY=( $(compgen -W '-w80 -w160 -w240 -w320 -w400 -w480 -w560 -w640 -w720 \
                                    -w1000 -w2000' -- $cur) )
           ;;
 
        *)
           COMPREPLY=( $(compgen -W "$options" -- $cur) )
           ;;
        esac
 
        return 0
 
}
[ "have" ] && complete -F _isql isql

не смог остановится? Ж:-)
когда у меня уже руки дойдут в bash нормально въехать

Отправить комментарий

Google Friend Connect (leave a quick comment)
loading...
Содержание этого поля является приватным и не предназначено к показу.