source

Linux 셸 스크립트에서 입력을 예/아니오/취소하려면 어떻게 해야 합니까?

ittop 2023. 6. 26. 23:09
반응형

Linux 셸 스크립트에서 입력을 예/아니오/취소하려면 어떻게 해야 합니까?

셸 스크립트의 입력을 일시 중지하고 사용자에게 선택을 요청합니다.
Yes,No또는Cancel타이프 문제
일반적인 bash 프롬프트에서 이 작업을 수행하려면 어떻게 해야 합니까?

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

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

스티븐 휴윅이 지적한 또 다른 방법은 바시의 명령입니다.다음은 다음과 같은 예입니다.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)
yesexpr="$1"; noexpr="$2"; yesword="$3"; noword="$4"

while true; do
    read -p "Install (${yesword} / ${noword})? " yn
    if [[ "$yn" =~ $yesexpr ]]; then make install; exit; fi
    if [[ "$yn" =~ $noexpr ]]; then exit; fi
    echo "Answer ${yesword} / ${noword}."
done

분명히 다른 통신 문자열은 여기에서 번역되지 않은 상태로 남아 있습니다(설치, 응답). 이는 보다 완전한 번역으로 처리되어야 하지만, 부분 번역이라도 많은 경우에 도움이 될 것입니다.

마지막으로 F훌륭한 답변을 확인해주시기 바랍니다. 하우리.

하나의 일반적인 질문에 대해 최소 5개의 답이 있습니다.

에 따라

  • 호환: 셸 환경이 있는 열악한 시스템에서 작동할 수 있음
  • 고유: 이른바 bashism 사용

그리고 당신이 원한다면,

  • 간단한 ''인라인'' 질문/답변(솔루션 포함)
  • 나 libgtk 또는 libqt를 사용한 그래픽과 같은 꽤 형식화된 인터페이스...
  • 강력한 읽기 줄 기록 기능 사용

POSIX 일반 솔루션

당신은 사용할 수 있습니다.read령명, 명령음이 나옵니다.if ... then ... else:

printf 'Is this a good question (y/n)? '
read answer
# if echo "$answer" | grep -iq "^y" ;then
if [ "$answer" != "${answer#[Yy]}" ] ;then # this grammar (the #[] operator) means that the variable $answer where any Y or y in 1st position will be dropped if they exist.
    echo Yes
else
    echo No
fi

(Adam Katz의 코멘트 덕분에: 위의 테스트를 휴대성이 더 좋고 포크 하나를 피할 수 있는 테스트로 대체합니다:)

POSIX, 단일 키 기능

그러나 사용자가 때리지 않으려면 다음과 같이 쓸 수 있습니다.

(편집:@Jonathan Leffler가 올바르게 제안했듯이 stty의 구성을 저장하는 이 단순히 제정신이 되도록 강제하는 것보다 나을 수 있습니다.)

printf '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 [ "$answer" != "${answer#[Yy]}" ];then
    echo Yes
else
    echo No
fi

참고: 이것은 sh, , , 에서 되었습니다!

동일하지만 명시적으로 또는 대기 중:

#/bin/sh
printf '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 [ "$answer" != "${answer#[Yy]}" ];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

시템에따교할수있다습니도야체해라스다있▁need니습▁▁replace▁to▁you▁may수,할도시를 교체해야 할 수도 있습니다.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 ...

Bash 관련 솔루션

기본 인라인 방식

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에서 bash에 할 수 있습니다.read명령:

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

아래, 쉬아래바,,read명령은 시간 초과 매개 변수를 허용하므로 유용할 수 있습니다.

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

시간 초과(카운트다운 포함

i=6 ;while ((i-->1)) &&
! read -sn 1 -t 1 -p $'\rIs this a good question (Y/n)? '$i$'..\e[3D' answer;do
  :;done ;[[ $answer == [nN] ]] && answer=No || answer=Yes ;echo "$answer "

전용 툴을 위한 몇 가지 요령

단순한 목적을 넘어 더욱 정교한 대화 상자:

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" ) || break
    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 사용: USB 키 선택기

읽기 줄의 기록 사용

예:

#!/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디렉터리는 , , 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화살표 키를 사용하여 선 편집 허용)

"예/아니오" 논리가 필요한 경우 다음과 같은 작업을 수행할 수 있습니다.

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

사용 방법은 다음과 같습니다.

$ bash examplescript.sh
1) Yes
2) No
3) Cancel
#? 1
Yes
#? 2
No
#? 3
Cancel
#?
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
inquire ()  {
  echo  -n "$1 [y/n]? "
  read answer
  finish="-1"
  while [ "$finish" = '-1' ]
  do
    finish="1"
    if [ "$answer" = '' ];
    then
      answer=""
    else
      case $answer in
        y | Y | yes | YES ) answer="y";;
        n | N | no | NO ) answer="n";;
        *) finish="-1";
           echo -n 'Invalid response -- please reenter:';
           read answer;;
       esac
    fi
  done
}

... other stuff

inquire "Install now?"

...

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

#!/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

저는 초보자라서 이걸 소금에 절여 먹지만, 효과가 있을 것 같습니다.

원하는 항목:

  • Bash 내장 명령(즉, 휴대용)
  • TTY 확인
  • 기본 응답
  • 시간 초과
  • 유색문제

스니펫

do_xxxx=y                      # In batch mode => Default is Yes
[[ -t 0 ]] &&                  # If TTY => Prompt the question
read -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx  # Store the answer in $do_xxxx
if [[ $do_xxxx =~ ^(y|Y|)$ ]]  # Do if 'y' or 'Y' or empty
then
    xxxx
fi

설명

  • [[ -t 0 ]] && read ...=> => 통화명령read TTYTTY 면라
  • read -n 1=>요=> 1글자만 기다려요 ㅠㅠ
  • $'\e[1;32m ... \e[0m '=>=> 녹로으인쇄색인쇄
    배경 에서 읽을 수 있기
  • [[ $do_xxxx =~ ^(y|Y|)$ ]]=>=> bash regex

시간 초과 => 기본 대답은 아니오입니다.

do_xxxx=y
[[ -t 0 ]] && {                   # Timeout 5 seconds (read -t 5)
read -t 5 -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx ||  # read 'fails' on timeout
do_xxxx=n ; }                     # Timeout => answer No
if [[ $do_xxxx =~ ^(y|Y|)$ ]]
then
    xxxx
fi

줄 수를 최소화하는 가장 쉬운 방법은 다음과 같습니다.

read -p "<Your Friendly Message here> : y/n/cancel" CONDITION;

if [ "$CONDITION" == "y" ]; then
   # do something here!
fi

if예: 이 변수를 처리하는 방법은 사용자에게 달려 있습니다.

을 합니다.read명령:

echo Would you like to install? "(Y or N)"

read x

# now check if $x is "y"
if [ "$x" = "y" ]; then
    # do something here!
fi

그리고 당신이 필요로 하는 다른 모든 것들.

이 솔루션은 단일 문자를 읽고 예 응답 시 함수를 호출합니다.

read -p "Are you sure? (y/n) " -n 1
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    do_something      
fi

커서와 같은 입력 상자를 가져오려면 다음과 같은 명령 대화 상자를 사용합니다.

#!/bin/bash
if (dialog --title "Message" --yesno "Want to do something risky?" 6 25)
# message box will have the size 25x6 characters
then 
    echo "Let's do something risky"
    # do something risky
else 
    echo "Let's stay boring"
fi

대화 상자 패키지는 적어도 SUSE 리눅스와 함께 기본적으로 설치됩니다.모양:

의 "Yes / choice" 셸에서 인식 " / No choice"를할 수 .LC_MESSAGES로케일 범주, 스위치는 입력과 일치하도록 미리 만들어진 ReGEx 패턴 및 현지화된 예 아니요 문자열을 제공합니다.

#!/usr/bin/env sh

# Getting LC_MESSAGES values into variables
# shellcheck disable=SC2046 # Intended IFS splitting
IFS='
' set -- $(locale LC_MESSAGES)

yesexpr="$1"
noexpr="$2"
yesstr="$3"
nostr="$4"
messages_codeset="$5" # unused here, but kept as documentation

# Display Yes / No ? prompt into locale
echo "$yesstr / $nostr ?"

# Read answer
read -r yn

# Test answer
case "$yn" in
# match only work with the character class from the expression
  ${yesexpr##^}) echo "answer $yesstr" ;;
  ${noexpr##^}) echo "answer $nostr" ;;
esac

편집: @Urhixidur논평에서 언급했듯이:

안타깝게도 POSIX는 처음 두 개(예: expr 및 no expr)만 지정합니다.Ubuntu 16에서는 yesstr과 nostr이 비어 있습니다.

참조: https://www.ee.ryerson.ca/ ~코스/ele709/susv4/xrat/V4_xbd_chap07.html #tag_21_07_03_06

LC_MESSAGS

및 로케일 키워드 및YESSTR그리고.NOSTRlanginfo 항목은 이전에 사용자 긍정 및 부정 응답을 일치시키는 데 사용되었습니다.POSIX.1-2008에서 , ,YESEXPR,그리고.NOEXPR확장된 정규식이 이를 대체했습니다.응용프로그램은 일반적인 로케일 기반 메시징 기능을 사용하여 원하는 샘플 응답이 포함된 메시지를 발송해야 합니다.

또는 Bash 방식으로 로케일을 사용합니다.

#!/usr/bin/env bash

IFS=$'\n' read -r -d '' yesexpr noexpr _ < <(locale LC_MESSAGES)

printf -v yes_or_no_regex "(%s)|(%s)" "$yesexpr" "$noexpr"

printf -v prompt $"Please answer Yes (%s) or No (%s): " "$yesexpr" "$noexpr"

declare -- answer=;

until [[ "$answer" =~ $yes_or_no_regex ]]; do
  read -rp "$prompt" answer
done

if [[ -n "${BASH_REMATCH[1]}" ]]; then
  echo $"You answered: Yes"
else
  echo $"No, was your answer."
fi

답변은 로케일 환경에서 제공한 정규식을 사용하여 일치합니다.

메시지를 하려면 나지메시변환다사용다니합음을면려하를머지다,▁to를 사용합니다.bash --dump-po-strings scriptname로컬라이제이션을 위한 포인팅을 출력하려면:

#: scriptname:8
msgid "Please answer Yes (%s) or No (%s): "
msgstr ""
#: scriptname:17
msgid "You answered: Yes"
msgstr ""
#: scriptname:19
msgid "No, was your answer."
msgstr ""

제 경우에는 다운로드된 스크립트를 읽어야 했습니다.

curl -Ss https://example.com/installer.sh | sh

read -r yn </dev/tty이 경우 입력을 읽을 수 있도록 허용했습니다.

printf "These files will be uploaded. Is this ok? (y/N) "
read -r yn </dev/tty

if [ "$yn" = "y" ]; then
   
   # Yes
else
   
   # No
fi

단일 키만 누름

다음은 더 길지만 재사용 가능한 모듈식 접근 방식입니다.

  • 온다아를 반환합니다.0 = 네그고리고1=아니오
  • Enter 키를 누를 필요가 없습니다. 단 한 글자만 입력하면 됩니다.
  • 를 눌러 기본 선택을 수락할 수 있습니다.
  • 기본 선택을 사용하지 않도록 설정하여 선택을 강제할 수 있습니다.
  • 두 가지 모두에 적합zsh그리고.bash.

Enter 키를 누를 때 "아니오"로 기본 설정

로 고는 다음과 .N대문자입니다.기본값을 그대로 사용하여 다음과 같이 입력합니다.

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?

참고로,[y/N]?자동으로 추가되었습니다.기본 "아니오"가 허용되므로 아무 것도 반향되지 않습니다.

유효한 응답이 제공될 때까지 다시 확인합니다.

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *

Enter 키를 누를 때 "예"로 기본 설정

로 고는 다음과 .Y자본화됨:

$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *

위에서 방금 Enter 키를 눌러 명령이 실행되었습니다.

에 기본값 없음 - requiredy또는n

$ get_yes_keypress "Here you cannot press enter. Do you like this [y/n]? "
Here you cannot press enter. Do you like this [y/n]? k
Here you cannot press enter. Do you like this [y/n]?
Here you cannot press enter. Do you like this [y/n]? n
$ echo $?
1

여기서,1또는 거짓이 반환되었습니다.의 기능을만의 기능을 사용할 수 있습니다.[y/n]?신속한.

코드

# Read a single char from /dev/tty, prompting with "$*"
# Note: pressing enter will return a null string. Perhaps a version terminated with X and then remove it in caller?
# See https://unix.stackexchange.com/a/367880/143394 for dealing with multi-byte, etc.
function get_keypress {
  local REPLY IFS=
  >/dev/tty printf '%s' "$*"
  [[ $ZSH_VERSION ]] && read -rk1  # Use -u0 to read from STDIN
  # See https://unix.stackexchange.com/q/383197/143394 regarding '\n' -> ''
  [[ $BASH_VERSION ]] && </dev/tty read -rn1
  printf '%s' "$REPLY"
}

# Get a y/n from the user, return yes=0, no=1 enter=$2
# Prompt using $1.
# If set, return $2 on pressing enter, useful for cancel or defualting
function get_yes_keypress {
  local prompt="${1:-Are you sure [y/n]? }"
  local enter_return=$2
  local REPLY
  # [[ ! $prompt ]] && prompt="[y/n]? "
  while REPLY=$(get_keypress "$prompt"); do
    [[ $REPLY ]] && printf '\n' # $REPLY blank if user presses enter
    case "$REPLY" in
      Y|y)  return 0;;
      N|n)  return 1;;
      '')   [[ $enter_return ]] && return "$enter_return"
    esac
  done
}

# Credit: http://unix.stackexchange.com/a/14444/143394
# Prompt to confirm, defaulting to NO on <enter>
# Usage: confirm "Dangerous. Are you sure?" && rm *
function confirm {
  local prompt="${*:-Are you sure} [y/N]? "
  get_yes_keypress "$prompt" 1
}    

# Prompt to confirm, defaulting to YES on <enter>
function confirm_yes {
  local prompt="${*:-Are you sure} [Y/n]? "
  get_yes_keypress "$prompt" 0
}

인 기을사수있을 사용할 수 .REPLY에서.read소문자로 변환하고 식이 있는 변수 집합과 비교합니다.
이스트또지다니합원을 지원합니다.ja/si/oui

read -rp "Do you want a demo? [y/n/c] "

[[ ${REPLY,,} =~ ^(c|cancel)$ ]] && { echo "Selected Cancel"; exit 1; }

if [[ ${REPLY,,} =~ ^(y|yes|j|ja|s|si|o|oui)$ ]]; then
   echo "Positive"
fi
read -e -p "Enter your choice: " choice

-e옵션을 사용하면 화살표 키를 사용하여 입력을 편집할 수 있습니다.

제안을 입력으로 사용하려는 경우:

read -e -i "yes" -p "Enter your choice: " choice

-i inputoption을 합니다.

이 질문에 대한 많은 좋은 대답들이 있지만, 제가 볼 수 있는 바로는 그 중 어떤 것도 제 이상형이 아닙니다.

  1. 단순하게, 단지 몇 줄의 셸.
  2. 단일 y/n 키 누르기 작업(Enter를 누를 필요 없음)
  3. Enter 키를 누르면 yes로 기본 설정됩니다.
  4. 대문자 Y/N으로도 작업 가능

다음은 이러한 속성을 가진 제 버전입니다.

read -n1 -p "Continue? (Y/n) " confirm

if ! echo $confirm | grep '^[Yy]\?$'; then
  exit 1
fi

은 "예할 수 . (단, "예" "예"만 제거하면 됩니다.)!에 시대에if 또는 또)를 합니다.else두 분기 모두에서 코드를 실행하려는 경우.

한 줄:

read -p "Continue? [Enter] → Yes, [Ctrl]+[C] → No."

이것은 "아니오"와 "취소"가 동일한 결과를 가지고 있다고 가정하기 때문에 다르게 취급할 이유가 없습니다.

이렇게 간단한 사용자 입력에 대해 여러 줄의 에코 메뉴를 보여주는 답변을 게시한 사람이 없다는 것을 알게 되었습니다. 그래서 제가 해보겠습니다.

#!/bin/bash

function ask_user() {    

echo -e "
#~~~~~~~~~~~~#
| 1.) Yes    |
| 2.) No     |
| 3.) Quit   |
#~~~~~~~~~~~~#\n"

read -e -p "Select 1: " choice

if [ "$choice" == "1" ]; then

    do_something

elif [ "$choice" == "2" ]; then

    do_something_else

elif [ "$choice" == "3" ]; then

    clear && exit 0

else

    echo "Please select 1, 2, or 3." && sleep 3
    clear && ask_user

fi
}

ask_user

이 방법은 누군가가 그것이 유용하고 시간을 절약할 수 있다는 희망으로 게시되었습니다.

확인합니다.

read -p "Continue? (y/n): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1

객관식 버전:

ask () {                        # $1=question $2=options
    # set REPLY
    # options: x=..|y=..
    while $(true); do
        printf '%s [%s] ' "$1" "$2"
        stty cbreak
        REPLY=$(dd if=/dev/tty bs=1 count=1 2> /dev/null)
        stty -cbreak
        test "$REPLY" != "$(printf '\n')" && printf '\n'
        (
            IFS='|'
            for o in $2; do
                if [ "$REPLY" = "${o%%=*}" ]; then
                    printf '\n'
                    break
                fi
            done
        ) | grep ^ > /dev/null && return
    done
}

예:

$ ask 'continue?' 'y=yes|n=no|m=maybe'
continue? [y=yes|n=no|m=maybe] g
continue? [y=yes|n=no|m=maybe] k
continue? [y=yes|n=no|m=maybe] y
$

날이 저물 것입니다REPLYy(스크립트 실행).

@Mark와 @Myrddin의 답변에서 영감을 받아 범용 프롬프트를 위해 이 기능을 만들었습니다.

uniprompt(){
    while true; do
        echo -e "$1\c"
        read opt
        array=($2)
        case "${array[@]}" in  *"$opt"*) eval "$3=$opt";return 0;; esac
        echo -e "$opt is not a correct value\n"
    done
}

다음과 같이 사용합니다.

unipromtp "Select an option: (a)-Do one (x)->Do two (f)->Do three : " "a x f" selection
echo "$selection"

대화상자를 사용하는 것이 좋습니다...

리눅스 어프렌티스:대화상자를 사용하여 Bash Shell 스크립트 개선

dialog 명령을 사용하면 셸 스크립트에서 창 상자를 사용하여 대화형으로 사용할 수 있습니다.

간단하고 사용하기 쉬우며, 정확히 동일한 매개 변수를 사용하지만 X에서 GUI 스타일을 보여주는 gdialog라는 gnome 버전도 있습니다.

더 일반적인 것은 다음과 같습니다.

function menu(){
    title="Question time"
    prompt="Select:"
    options=("Yes" "No" "Maybe")
    echo "$title"
    PS3="$prompt"
    select opt in "${options[@]}" "Quit/Cancel"; do
        case "$REPLY" in
            1 ) echo "You picked $opt which is option $REPLY";;
            2 ) echo "You picked $opt which is option $REPLY";;
            3 ) echo "You picked $opt which is option $REPLY";;
            $(( ${#options[@]}+1 )) ) clear; echo "Goodbye!"; exit;;
            *) echo "Invalid option. Try another one.";continue;;
         esac
     done
     return
}
yn() {
  if [[ 'y' == `read -s -n 1 -p "[y/n]: " Y; echo $Y` ]];
  then eval $1;
  else eval $2;
  fi }
yn 'echo yes' 'echo no'
yn 'echo absent no function works too!'

한 가지 은 이를위간방은법한단을 사용하는 입니다.xargs -p orgnuparallel --interactive.

마지막에 실행할 yes를 수집하는 것보다 프롬프트 직후에 각 명령을 실행하기 때문에 xargs의 동작이 조금 더 좋습니다. (원하는 명령을 통과한 후 Ctrl-C를 사용할 수 있습니다.)

예.,

echo *.xml | xargs -p -n 1 -J {} mv {} backup/

한 줄 명령의 친구로서 다음을 사용했습니다.

while [ -z $prompt ]; do read -p "Continue (y/n)?" choice;case "$choice" in y|Y ) prompt=true; break;; n|N ) exit 0;; esac; done; prompt=;

긴 형식으로 작성되어 다음과 같이 작동합니다.

while [ -z $prompt ];
  do read -p "Continue (y/n)?" choice;
  case "$choice" in
    y|Y ) prompt=true; break;;
    n|N ) exit 0;;
  esac;
done;
prompt=;

나는 그것을 사용했습니다.case그러한 시나리오에서 진술서를 두 번 사용하는 것이 그것을 진행하는 좋은 방법입니다.while프루, 그은캡니다됩슐화것▁the를 합니다.case프로그램을 더 많이 제어하고 다른 많은 요구 사항을 충족하기 위해 부울 조건을 활용하는 블록을 구현할 수 있습니다.에, 모든조충후족된이건후,▁a▁after▁the모된itions충,break제어권을 프로그램의 주요 부분으로 다시 전달하는 데 사용할 수 있습니다.또한, 다른 조건을 충족하기 위해, 물론 제어 구조와 함께 다음과 같은 조건문을 추가할 수 있습니다.case과 가능성이 있는 것while 루우프

사용 case하기 위한 .

#! /bin/sh 

# For potential users of BSD, or other systems who do not
# have a bash binary located in /bin the script will be directed to
# a bourne-shell, e.g. /bin/sh

# NOTE: It would seem best for handling user entry errors or
# exceptions, to put the decision required by the input 
# of the prompt in a case statement (case control structure), 

echo Would you like us to perform the option: "(Y|N)"

read inPut

case $inPut in
    # echoing a command encapsulated by 
    # backticks (``) executes the command
    "Y") echo `Do something crazy`
    ;;
    # depending on the scenario, execute the other option
    # or leave as default
    "N") echo `execute another option`
    ;;
esac

exit

언급URL : https://stackoverflow.com/questions/226703/how-do-i-prompt-for-yes-no-cancel-input-in-a-linux-shell-script

반응형