쉼표로 구분 된 값에 대한 대쉬 완료


16

쉼표로 구분 된 매개 변수 목록에 대한 완료 규칙을 작성하고 싶습니다. 예를 들어 서버 이름 목록을 수신하는 명령이 있습니다.

myscript -s name1,name2,name3

이 시점에서 나는 다음과 같이 완성했습니다.

_myscript () {
  local cur prev opts

  _get_comp_words_by_ref cur prev

  opts='-s'

  servers='name1 name2 name3'

  if [[ ${cur} == -* ]] ; then
    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  else
    case "${prev}" in
      -s)
        if [[ "$cur" == *,* ]]; then
          local realcur prefix
          realcur=${cur##*,}
          prefix=${cur%,*}
          COMPREPLY=( $(compgen -W "${servers}" -P "${prefix}," -- ${realcur}) )
        else
          COMPREPLY=( $(compgen -W "${servers}" -- ${cur}) )
        fi
        ;;
      *)
        # do nothing
        ;;
    esac
  fi
}

그러나 적어도 두 가지 문제가 있습니다.

  1. 현재 값에 대한 제안에는 접두사에있는 모든 이전 값이 포함됩니다.
  2. 중복 값은 고려하지 않습니다.

그러한 경우에 대한 모범 사례는 무엇입니까? bash-completions에 csv-lists에 대한 번들 함수가 있습니까?


3
쉼표로 구분 된 값을 다음과 같이 반복 가능한 목록으로 분할 할 수 있습니다. IFS=, LIST=("$VARIABLE")여기서 $ VARIABLE에는 쉼표로 구분 된 값이 포함됩니다.
Michael Ehrenreich

2
@MichaelEhrenreich의 좋은 생각이지만을 인용해서는 안되며 $VARIABLE그렇지 않으면 단어 분리가 발생하지 않습니다. 그냥 사용하십시오 IFS=, LIST=($VARIABLE).
Guss

답변:


6

bash는 COMPREPLY디스플레이 에서 직접 값을 사용하고 사용자의 텍스트를 대체 하기 때문에 설명하는 문제를 해결할 수있는 방법이 없습니다. 원하는 것을 얻으려면 먼저 가능한 추가 사항을 생성해야합니다 (추가 bash가 표시 할 서버 이름, 접두어가없는 경우) bash가 사용자 텍스트를 가장 긴 비 충돌 문자열로 바꾸려고 할 때 접두사가있는 텍스트를 생성하려면 스크립트를 다시 호출해야합니다-및 bash 그에 대한 시설이 없습니다.

내가 올릴 수있는 최선의 방법 COMPREPLY은 전체 접두사 ( COMPREPLY=( "${prefix},"$(compgen -W "${servers[@]}" -- ${realcur}) )) 가있는 첫 번째 단어 만 생성 되도록하는 것입니다. 따라서 가능한 완성이 하나만 있으면 자동으로 올바르게 완료되지만 가능한 완성이 둘 이상인 경우 bash는 지금까지 입력 한 내용을 제거하지 않습니다 (첫 번째 단어 COMPREPLY에는 전체 접두사가 있고 현재 입력 된 텍스트와 일치하므로 bash가 사용자의 텍스트를 대체하도록 선택하므로)-접두어없이 옵션을 표시합니다. 접두사가 이미 포함 된 한 단어에 대해서는 다음과 같이 출력됩니다.

$ command -s banana,a
ananas     apricot    banana,apple

"apple"은 "b"로 시작하는 접두사를 전달하므로 매우 혼란스러운 완료 옵션에서 마지막으로 정렬됩니다. 그래서 나는 그것을하지 않는 것이 좋습니다.

중복에 대해-중복을 표시하지 않으려면 $prefix그 부분으로 들어가서 (easy IFS="," prefix_parts=($prefix):) 반복하고 반복 $servers하지 말고 아직 나열되지 않은 이름 만 남겨 두십시오 . 입력하기가 지루하므로 여기에 표시하지 않지만 비교적 사소하므로 관리 할 수 ​​있다고 확신합니다. :-).

요약하면, 적어도 bash가 완료를 도울 것으로 예상되는 경우 입력 옵션에 쉼표로 구분 된 값을 사용해야한다고 생각하지 않습니다.

command -s <server> [<server> [..]]다음과 같은 옵션 형식을 지원할 수 있습니다. 그런 다음 -s옵션 바로 뒤에있는 항목 이외의 항목을 완성 하려면 옵션 (과 일치하는 문자열)을 찾을 때까지 "-s"인 경우 $COMP_WORDS배열을 통해 다시 검색하십시오. 서버 이름 완성을 수행해야합니다.$COMP_CWORD-*

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.