2016-11-06 5 views
1

bashselect을 사용하여 두 개의 기존 항목 사이에 새 선택 항목을 추가 할 때 옵션 번호가 자동으로 조정되는 선택 대화 상자를 만듭니다. 선택 : 목록에없는 문자 입력 허용

select choice in command1 command2 command3; do 
    $choice 
    break 
done 

자체에서 실행되는 명령과는 다른 무언가를 표시하려면, 나는 나는이 방법을 좋아하지 않는 것은, 인 연관 배열

declare -A choices=(
    [Option 1]=command1 
    [Option 2]=command2 
    [Option 3]=command3 
) 
select choice in "${!choices[@]}" exit ; do 
    [[ $choice == exit ]] && break 
    ${choices[$choice]} 
done 

를 선언 들었다 그 옵션 exit은 번호가 매겨진 선택 항목으로 표시됩니다. 나는 유효한 입력으로, 1, 2 또는 3 외에,

PS3="Select the desired option (q to quit): " 

처럼 뭔가를 달성하고 selectq을 받아 들일 수 있도록 할 것입니다.

연관 배열은 입력이 인덱스로 사용된다는 사실에 문제가있어서 중첩 된 case으로 전환했습니다. 입력이기 때문에이 방법은 또한 q

PS3="Select the desired option (q to quit): " 
select choice in "Option 1" "Option 2" "Option 3"; do 
    case $choice in 
     "Option 1") command1a 
        command1b 
        break;; 
     "Option 2") command2a 
        command2b 
        break;; 
     "Option 3") command3a 
        command3b 
        break;; 
     q)   echo "Bye!" 
        break;; 
    esac 
done 

지금이 아닌 숫자 (또는 범위 초과) 입력에 대한 문제가 없는지 더 하나의 명령보다 저장하기 위해 별도의 함수를 선언해야하지만하지 않습니다 여전히 인식되지 않습니다. default 경우에 해당하며, 정의한 경우 *)을 실행하거나 그렇지 않은 경우 다시 묻습니다.

내가하려는 일을 성취 할 수있는 방법이 있습니까?

답변

1

$REPLY 변수 만 사용하십시오 (내용을 확인하십시오).

예 :

declare -A choices=(
    [Show the date]=show_date 
    [Print calendar]=print_cal 
    [Say hello]=say_hello 
) 

show_date() { 
    date 
} 
print_cal() { 
    cal 
} 
say_hello() { 
    echo "Hello $USER" 
} 

PS3="Select the desired option (q to quit): " 
select choice in "${!choices[@]}" 
do 
    case "$choice" in 
    '') # handling the invalid entry - e.g. the "q" 
     # in a case of an invalid entry, the $choice is en empty(!) string 
     # checking the content of the entered line can be done using the $REPLY 
     case "$REPLY" in 
      q|Q) echo "Bye, bye - quitting...."; exit;; 
      *) echo "INVALID choice <$REPLY> - try again";; 
     esac 
     ;; 
    *) 
     #valid user input 
     ${choices[$choice]} 
     ;; 
    esac 
done 

또는 짧은,하지만 유연하지

declare -A choices=(
    [Show the date]=show_date 
    [Print calendar]=print_cal 
    [Say hello]=say_hello 
) 

show_date() { 
    date 
} 
print_cal() { 
    cal 
} 
say_hello() { 
    echo "Hello $USER" 
} 

PS3="Select the desired option (q to quit): " 
select choice in "${!choices[@]}" 
do 
    case "$REPLY" in 
    q|Q) echo "Bye, bye - quitting...."; exit;; 
    1|2|3) ${choices[$choice]} ;; 
    *) echo "INVALID choice <$REPLY> - try again";; 
    esac 
done 
+0

이 최고입니다! 너는 최고야! 나는 많은 것을 배웠다. 마지막으로 한 가지가 남아 있습니다 :'$ REPLY'를 직접 처리하는 방법이 "유연하지 않다"고 말할 때 당신은 무엇을 의미합니까? 수동으로 유효한 입력에 해당하는 모든 숫자를 수동으로 지정해야하기 때문입니까? –

관련 문제