2015-03-10 3 views
3

У меня есть основная полная функция:Bash: Разрешить флаги раз

_my_complete() 
{ 
    local cur prev opts opts2; 
    COMPREPLY=(); 
    cur="${COMP_WORDS[COMP_CWORD]}"; 
    prev="${COMP_WORDS[COMP_CWORD-1]}"; 
    opts="foo bar"; 
    opts2="-f -s"; 
    case ${COMP_CWORD} in 
     1) 
      COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
     ;; 
     2 | 4) 
      COMPREPLY=($(compgen -W "${opts2}" -- ${cur})) 
     ;; 
    esac 
} 

Как ограничить завершение, чтобы принять -f или -s только один раз в командной строке?

Thanks

+3

Как вы знаете, все аргументы в '$ {COMP_WORDS [@]}', так что вы можете просто проверить, если '' -f' или -s' уже массив. – pynexj

+0

Да, но как и где я проверяю его и редактирую 'opts2'? –

ответ

1

Решено. Вдохновленный комментарием @whjm и это post

_my_complete() { 
     local cur prev opts opts2 subopts ; 
     COMPREPLY=(); 
     cur="${COMP_WORDS[COMP_CWORD]}"; 
     prev="${COMP_WORDS[COMP_CWORD-1]}"; 
     opts="foo bar"; 
     opts2="-f -s"; 
     subopts=(); 

     for i in ${opts2} 
     do 
       for j in "${COMP_WORDS[@]}" 
       do 
         if [[ "$i" == "$j" ]] 
         then 
           continue 2 
         fi 
       done 
       subopts+=("$i") 
     done 

     case ${COMP_CWORD} in 
      1) 
        COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
        ;; 
      2|4) 
        COMPREPLY=($(compgen -W "${subopts[*]}" -- ${cur})) 
        ;; 
     esac 
} 
+0

Есть более простой способ получить 'cur' и' prev'. Просто напишите 'cur = $ 2' и' prev = $ 3'. И '$ 1' - это сама команда. – pynexj

+0

Сложный способ был предложен несколькими примерами сайтов. Поэтому я застрял в этом. –

+1

'$ 1..3' всегда отлично работает для меня. Если вы четко понимаете разницу с '$ {COMP_WORDS [@]}', тогда вы точно знаете, когда использовать. Для меня достаточно * достаточно *. :) – pynexj

Смежные вопросы