[linux] Linux 쉘 스크립트에서 예 / 아니오 / 취소 입력을 프롬프트하는 방법은 무엇입니까?

쉘 스크립트에서 입력을 일시 중지하고 사용자에게 선택을 요구합니다.
표준 Yes, No또는 Cancel유형 질문입니다.
일반적인 bash 프롬프트에서 어떻게 이것을 수행합니까?



답변

쉘 프롬프트에서 사용자 입력을 얻는 가장 단순하고 가장 널리 사용되는 방법은 read명령입니다. 사용법을 설명하는 가장 좋은 방법은 간단한 데모입니다.

while true; do
    read -p "Do you wish to install this program?" yn
    case $yn in
        [Yy]* ) make install; break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

또 다른 방법으로, 지적 으로 스티븐 Huwig은 , 배쉬의입니다 select명령. 다음은 동일한 예입니다 select.

echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
    case $yn in
        Yes ) make install; break;;
        No ) exit;;
    esac
done

으로 select당신이 입력을 소독 할 필요가 없습니다 – 그것은 가능한 선택 사항을 표시합니다, 당신은 당신의 선택에 해당하는 번호를 입력합니다. 또한 자동으로 루프되므로 while true잘못된 입력을 제공하는 경우 루프를 다시 시도 할 필요가 없습니다 .

또한, 레아 그리가 의 요청 언어 무신론자 만드는 방법 보여 그녀의 대답을 . 여러 언어를 더 잘 제공하기 위해 첫 번째 예를 적용하면 다음과 같습니다.

set -- $(locale LC_MESSAGES)
yesptrn="$1"; noptrn="$2"; yesword="$3"; noword="$4"

while true; do
    read -p "Install (${yesword} / ${noword})? " yn
    case $yn in
        ${yesptrn##^} ) make install; break;;
        ${noptrn##^} ) exit;;
        * ) echo "Answer ${yesword} / ${noword}.";;
    esac
done

분명히 다른 통신 문자열은 여기에서 번역되지 않은 채로 남아 있습니다 (설치, 답변). 더 완전한 완성 된 번역으로 해결해야하지만 부분 번역조차도 많은 경우에 도움이 될 것입니다.

마지막으로 F. Hauri훌륭한 답변 을 확인하십시오 .


답변

하나의 일반적인 질문에 대해 최소 5 개의 답변.

에 따라

  • 준수 : 일반 시스템이있는 열악한 시스템에서 작동 할 수 있음 환경
  • 특정 : 소위 bashisms 사용

그리고 원한다면

  • 간단한“인라인 ”질문 / 응답 (일반 솔루션)
  • 꽤 형식화 된 인터페이스 libgtk 또는 libqt를 사용하는 그래픽
  • 강력한 리드 라인 히스토리 기능 사용

1. POSIX 일반 솔루션

read다음 명령을 사용할 수 있습니다 if ... then ... else.

echo -n "Is this a good question (y/n)? "
read answer

# if echo "$answer" | grep -iq "^y" ;then

if [ "$answer" != "${answer#[Yy]}" ] ;then
    echo Yes
else
    echo No
fi

( Adam Katz의 의견에 감사드립니다 : 위의 테스트를 더 휴대하기 쉽고 포크 하나를 피하는 테스트로 대체했습니다.)

POSIX이지만 단일 키 기능

그러나 사용자가을 누르지 않게하려면 다음 Return과 같이 쓸 수 있습니다.

( 편집 : @JonathanLeffler가 올바르게 제안했듯이 stty의 구성을 저장 하는 것이 단순히 제자리잡는 것보다 낫습니다 .)

echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo ; answer=$(head -c 1) ; stty $old_stty_cfg # Careful playing with stty
if echo "$answer" | grep -iq "^y" ;then
    echo Yes
else
    echo No
fi

참고 : 이것은 아래에서 테스트되었습니다, , , !

동일하지만 명시 적으로 y또는 n:

#/bin/sh
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo
answer=$( while ! head -c 1 | grep -i '[ny]' ;do true ;done )
stty $old_stty_cfg
if echo "$answer" | grep -iq "^y" ;then
    echo Yes
else
    echo No
fi

전용 도구 사용

사용하여 구축 된 다양한 도구가 있습니다 libncurses, libgtk, libqt또는 다른 그래픽 라이브러리. 예를 들어, 사용 whiptail:

if whiptail --yesno "Is this a good question" 20 60 ;then
    echo Yes
else
    echo No
fi

시스템에 따라 whiptail다른 유사한 도구 로 교체해야 할 수도 있습니다 .

dialog --yesno "Is this a good question" 20 60 && echo Yes

gdialog --yesno "Is this a good question" 20 60 && echo Yes

kdialog --yesno "Is this a good question" 20 60 && echo Yes

여기서 20대화 상자의 높이는 줄 수이며 60대화 상자의 너비입니다. 이 도구들은 모두 거의 같은 구문을 가지고 있습니다 .

DIALOG=whiptail
if [ -x /usr/bin/gdialog ] ;then DIALOG=gdialog ; fi
if [ -x /usr/bin/xdialog ] ;then DIALOG=xdialog ; fi
...
$DIALOG --yesno ...

2. 배쉬 특정 솔루션

기본 인라인 방법

read -p "Is this a good question (y/n)? " answer
case ${answer:0:1} in
    y|Y )
        echo Yes
    ;;
    * )
        echo No
    ;;
esac

필요한 경우 case테스트 할 수 있도록 사용하는 것을 선호 yes | ja | si | oui합니다 …

라인하나의 키 기능

bash에서 read명령 에 대한 의도 된 입력 길이를 지정할 수 있습니다 .

read -n 1 -p "Is this a good question (y/n)? " answer

bash에서 readcommand는 시간 초과 매개 변수를 승인하는데 이는 유용 할 수 있습니다.

read -t 3 -n 1 -p "Is this a good question (y/n)? " answer
[ -z "$answer" ] && answer="Yes"  # if 'yes' have to be default choice

3. 전용 도구에 대한 몇 가지 요령

간단한 yes - no목적 이외의보다 정교한 대화 상자 :

dialog --menu "Is this a good question" 20 60 12 y Yes n No m Maybe

진행 표시 줄:

dialog --gauge "Filling the tank" 20 60 0 < <(
    for i in {1..100};do
        printf "XXX\n%d\n%(%a %b %T)T progress: %d\nXXX\n" $i -1 $i
        sleep .033
    done
) 

작은 데모 :

#!/bin/sh
while true ;do
    [ -x "$(which ${DIALOG%% *})" ] || DIALOG=dialog
    DIALOG=$($DIALOG --menu "Which tool for next run?" 20 60 12 2>&1 \
            whiptail       "dialog boxes from shell scripts" >/dev/tty \
            dialog         "dialog boxes from shell with ncurses" \
            gdialog        "dialog boxes from shell with Gtk" \
            kdialog        "dialog boxes from shell with Kde" ) || exit
    clear;echo "Choosed: $DIALOG."
    for i in `seq 1 100`;do
        date +"`printf "XXX\n%d\n%%a %%b %%T progress: %d\nXXX\n" $i $i`"
        sleep .0125
      done | $DIALOG --gauge "Filling the tank" 20 60 0
    $DIALOG --infobox "This is a simple info box\n\nNo action required" 20 60
    sleep 3
    if $DIALOG --yesno  "Do you like this demo?" 20 60 ;then
        AnsYesNo=Yes; else AnsYesNo=No; fi
    AnsInput=$($DIALOG --inputbox "A text:" 20 60 "Text here..." 2>&1 >/dev/tty)
    AnsPass=$($DIALOG --passwordbox "A secret:" 20 60 "First..." 2>&1 >/dev/tty)
    $DIALOG --textbox /etc/motd 20 60
    AnsCkLst=$($DIALOG --checklist "Check some..." 20 60 12 \
        Correct "This demo is useful"        off \
        Fun        "This demo is nice"        off \
        Strong        "This demo is complex"        on 2>&1 >/dev/tty)
    AnsRadio=$($DIALOG --radiolist "I will:" 20 60 12 \
        " -1" "Downgrade this answer"        off \
        "  0" "Not do anything"                on \
        " +1" "Upgrade this anser"        off 2>&1 >/dev/tty)
    out="Your answers:\nLike: $AnsYesNo\nInput: $AnsInput\nSecret: $AnsPass"
    $DIALOG --msgbox "$out\nAttribs: $AnsCkLst\nNote: $AnsRadio" 20 60
  done

더 많은 샘플? USB 장치USB 이동식 저장소 선택기 선택을 위해 whiptail 사용을 살펴보십시오 : USBKeyChooser

5. readline 기록 사용

예:

#!/bin/bash

set -i
HISTFILE=~/.myscript.history
history -c
history -r

myread() {
    read -e -p '> ' $1
    history -s ${!1}
}
trap 'history -a;exit' 0 1 2 3 6

while myread line;do
    case ${line%% *} in
        exit )  break ;;
        *    )  echo "Doing something with '$line'" ;;
      esac
  done

이것은 파일이 만들어집니다 .myscript.history당신에 $HOME당신이 같이 작성한 Readline의 역사 명령을 사용할 수있는 것보다, 디렉토리 Up, Down, Ctrl+ r등이 있습니다.


답변

echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"


답변

내장 된 읽기 명령을 사용할 수 있습니다 . 이 -p옵션을 사용하여 사용자에게 질문을하십시오.

BASH4부터는 이제 -i답변을 제안하는 데 사용할 수 있습니다 .

read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
echo $FILEPATH

(단 -e, 화살표 키로 줄을 편집 하려면 “readline”옵션을 사용해야합니다 )

“예 / 아니오”논리를 원하면 다음과 같이 할 수 있습니다.

read -e -p "
List the content of your home dir ? [Y/n] " YN

[[ $YN == "y" || $YN == "Y" || $YN == "" ]] && ls -la ~/


답변

Bash는 이 목적으로 선택 했습니다.

select result in Yes No Cancel
do
    echo $result
done


답변

read -p "Are you alright? (y/n) " RESP
if [ "$RESP" = "y" ]; then
  echo "Glad to hear it"
else
  echo "You need more bash programming"
fi


답변

다음은 제가 함께 정리 한 것입니다.

#!/bin/sh

promptyn () {
    while true; do
        read -p "$1 " yn
        case $yn in
            [Yy]* ) return 0;;
            [Nn]* ) return 1;;
            * ) echo "Please answer yes or no.";;
        esac
    done
}

if promptyn "is the sky blue?"; then
    echo "yes"
else
    echo "no"
fi

나는 초보자이므로 소금 한알로 이것을 가져 가면 효과가있는 것 같습니다.