web-dev-qa-db-ja.com

LinuxシェルスクリプトでYes/No/Cancel入力を求める方法は?

シェルスクリプトで入力を一時停止し、ユーザーに選択を促します。標準の「はい、いいえ、またはキャンセル」タイプの質問。典型的なbashプロンプトでこれを達成するにはどうすればいいですか?

1257
Myrddin Emrys

シェルプロンプトでユーザー入力を取得するための最も簡単で広く利用可能な方法は 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

Steven Huwigが指摘しているもう1つの方法は、Bashの 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ループが再試行する必要はありません。

また、 すばらしい答え F. Hauriによる/をチェックしてください。

1414
Myrddin Emrys

1つの一般的な質問に対して少なくとも5つの答えがあります。

応じて

  • posix 準拠:一般的な環境で貧弱なシステムでも動作する可能性があります Shell 環境
  • bash specific:いわゆる bashismsを使う

そしてあなたが望むなら

  • 単純な「インライン」の質問/回答(一般的な解決策)
  • ncurses やlibgtkやlibqtを使ったグラフィカルな...のような、きれいにフォーマットされたインタフェース.
  • 強力なreadline履歴機能を使う

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

(Thanks to Adam Katz's comment :上記のテストをより移植性が高く、フォークを避けたものに置き換えました:)

POSIX、しかし単一の重要な機能

しかし、あなたがユーザーに命中させたくないのなら Return、あなたは書くことができます:

編集:@JonathanLefflerが正しく示唆しているように、 Saving sttyの設定は単に sane に強制するよりも良いかもしれません。

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

注:これは shbashkshdash の下でテストされました。 = and busybox

同じですが、明示的に待っています 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

専用ツールを使う

libncurseslibgtklibqtまたは他のグラフィカルライブラリを使用して構築された多くのツールがあります。たとえば、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. bash特有の解決策

基本 インライン メソッド

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

私は必要に応じてyes | ja | si | ouiをテストできるようにcaseを使用することを好みます...

インライン with 単一キー feature

Bashの下では、readコマンドの目的の入力の長さを指定できます。

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

Bashの下では、readコマンドは timeout パラメータを受け入れますが、これは役に立ちます。

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

専用ツール のためのいくつかのトリック

単純な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

もっとサンプル?ご覧ください SBデバイスを選択するためにwhiptailを使用する and SBリムーバブルストレージセレクター: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

これはreadlineのhistoryコマンドを使うことができるよりもあなたの.myscript.historyディレクトリにファイル$HOMEを作成するでしょう。 Up、 Down、 Ctrl+r その他。

450
F. Hauri
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"
340
Pistos

組み込みの read コマンドを使用できます。 -pオプションを使ってユーザーに質問を促します。

BASH4以降、-iを使用して回答を提案できるようになったので、ユーザーはreturnを押して入力するだけです。

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

(ただし、矢印キーで行を編集できるようにするには、必ず "readline"オプション-eを使用してください)

「はい/いいえ」のロジックが必要な場合は、次のようにします。

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

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

この目的のためにBashは select を持っています。

select result in Yes No Cancel
do
    echo $result
done
101
Steven Huwig
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
54
serg

これが私がまとめたものです。

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

私は初心者なので、これを一粒の塩と一緒に飲んでください、しかしそれはうまくいくようです。

31
mpen
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?"

...
28
SumoRunner

あなたが欲しい:

  • 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 ... => TTYの場合はコマンドreadを呼び出す
  • read -n 1 => 1文字待つ
  • $'\e[1;32m ... \e[0m ' =>緑色で印刷
    (白/黒の両方の背景で読み取り可能なので、緑色は問題ありません)
  • [[ $do_xxxx =~ ^(y|Y|)$ ]] => bash正規表現

タイムアウト=>デフォルトの答えはいいえ

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
25
olibre

これを最小の行数で達成する最も簡単な方法は次のとおりです。

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

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

ifはほんの一例です。この変数の扱い方はあなた次第です。

21
Apurv Nerlekar

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

それからあなたが必要とする他のすべてのもの

17
ThatLinuxGuy

この解決策は単一の文字を読み取り、yesという応答で関数を呼び出します。

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

-eオプションを使用すると、ユーザーは矢印キーを使用して入力を編集できます。

あなたが入力として提案を使用したい場合:

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

-iオプションは示唆的な入力を表示します。

12
Jahid

そのような古い投稿に投稿して申し訳ありません。数週間前、私は同様の問題に直面していました。私の場合は、オンラインのインストーラースクリプト内でも機能するソリューションが必要でした。例:curl -Ss https://raw.github.com/_____/installer.sh | bash

read yesno < /dev/ttyを使うことは私にとってはうまくいきます:

echo -n "These files will be uploaded. Is this ok? (y/n) "
read yesno < /dev/tty

if [ "x$yesno" = "xy" ];then

   # Yes
else

   # No
fi

これが誰かに役立つことを願っています。

9
xyz

Nice ncursesのような入力ボックスを得るには、 dialog のようにコマンドを使います。

#!/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 Linuxとともにインストールされます。

8
Thorsten Staerk

シングルキープレスのみ

これはもっと長くて再利用可能なモジュール式のアプローチです。

  • 0 = yesおよび1 = noを返します
  • Enterキーを押す必要はありません - 1文字だけ
  • 押すことができます enter デフォルトの選択を受け入れる
  • デフォルトの選択を無効にして選択を強制することができます
  • zshbashの両方で機能します。

Enterキーを押すと、デフォルトで "no"になります。

Nは大文字であることに注意してください。ここでenterを押して、デフォルトを受け入れます。

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

[y/N]?は自動的に追加されたことにも注意してください。デフォルトの "no"が受け入れられるので、何もエコーされません。

有効な回答が与えられるまで再入力:

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

Enterを押すと、デフォルトで "yes"になります。

Yは大文字になっていることに注意してください。

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

上で、私はちょうどエンターを押したので、コマンドは走りました。

デフォルトなし enter - yまたは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またはfalseが返されました。この低レベルの関数ではあなた自身の[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
}
6
Tom Hale

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
6
Walter A

私は誰もそのような単純なユーザ入力のために複数行のエコーメニューを示す答えを投稿していないことに気づいたので、ここに私の行くところです:

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

この方法は、誰かが便利で時間を節約できることを期待して投稿されました。

4
Yokai

複数選択バージョン:

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に設定します。

4
Ernest A

@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"
4
poxtron

これを行う簡単な方法の1つは、xargs -pまたはgnu parallel --interactiveです。

私はxargsの振る舞いがもう少し好きです。なぜならそれは他の対話的なunixコマンドのようにプロンプ​​トの直後に各コマンドを実行するからです。 (あなたが望んだものを通り過ぎた後、あなたはCtrl-Cを押すことができます。)

例えば。、

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

私はあなたをお勧めします ダイアログを使用します ...

Linux実習生:ダイアログを使ったBashシェルスクリプトの改善

Dialogコマンドを使用すると、シェルスクリプトでウィンドウボックスをよりインタラクティブに使用できるようになります。

それはシンプルで使いやすいです、gdialogと呼ばれるgnomeバージョンもあります。これはまったく同じパラメータを取りますが、X上ではGUIスタイルを示します。

3

より一般的なものになります:

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
}
3

1行のコマンドの友達として、私は次のものを使いました。

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=;

書かれたlongform、それはこのように動作します:

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=;
2
ccDict

そのようなシナリオでcaseステートメントを2、3回使用しましたが、caseステートメントを使用するのが良い方法です。 whileブロックをカプセル化し、ブール条件を利用するcaseループは、プログラムをさらに制御し、他の多くの要件を満たすために実装できます。すべての条件が満たされた後、プログラムの主要部分に制御を戻す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
2
oOpSgEo
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!'
2
jlettvin

他の人たちに反応して:

BASH4では、大文字小文字を指定する必要はありません。varを小文字にするために ','を使用するだけです。また、読み取りブロックの内側にコードを入れて結果を取得し、読み取りブロックのIMOの外側でそれを処理することを強く嫌います。 IMOを終了するための 'q'も含みます。最後に、なぜ 'yes'とタイプするかは、単に-n1を使ってyを押すだけです。

例:ユーザーはy/nを押してqを押すだけで終了することもできます。

ans=''
while true; do
    read -p "So is MikeQ the greatest or what (y/n/q) ?" -n1 ans
    case ${ans,,} in
        y|n|q) break;;
        *) echo "Answer y for yes / n for no  or q for quit.";;
    esac
done

echo -e "\nAnswer = $ans"

if [[ "${ans,,}" == "q" ]] ; then
        echo "OK Quitting, we will assume that he is"
        exit 0
fi

if [[ "${ans,,}" == "y" ]] ; then
        echo "MikeQ is the greatest!!"
else
        echo "No? MikeQ is not the greatest?"
fi
1
Mike Q

はい/いいえ/キャンセル

関数

#!/usr/bin/env bash
@confirm() {
  local message="$*"
  local result=''

  echo -n "> $message (Yes/No/Cancel) " >&2

  while [ -z "$result" ] ; do
    read -s -n 1 choice
    case "$choice" in
      y|Y ) result='Y' ;;
      n|N ) result='N' ;;
      c|C ) result='C' ;;
    esac
  done

  echo $result
}

使用法

case $(@confirm 'Confirm?') in
  Y ) echo "Yes" ;;
  N ) echo "No" ;;
  C ) echo "Cancel" ;;
esac

クリーンなユーザー入力で確認

関数

#!/usr/bin/env bash
@confirm() {
  local message="$*"
  local result=3

  echo -n "> $message (y/n) " >&2

  while [[ $result -gt 1 ]] ; do
    read -s -n 1 choice
    case "$choice" in
      y|Y ) result=0 ;;
      n|N ) result=1 ;;
    esac
  done

  return $result
}

使用法

if @confirm 'Confirm?' ; then
  echo "Yes"
else
  echo "No"
fi
1
Eduardo Cuomo