关于bash:如何在Linuxshell脚本中提示yes/no/cancel输入?

How do I prompt for Yes/No/Cancel input in a Linux shell script?

我想暂停shell脚本中的输入,并提示用户选择。标准的"是、否或取消"类型的问题。如何在典型的bash提示中完成这一点?


在shell提示下获取用户输入的最简单和最广泛可用的方法是read命令。说明其用途的最佳方法是简单演示:

1
2
3
4
5
6
7
8
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

StevenHuwig指出的另一种方法是bash的select命令。下面是使用select的相同示例:

1
2
3
4
5
6
7
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的完美答案。


一个普通问题至少有五个答案。

取决于

  • 符合POSIX:可以在具有通用shell环境的差系统上工作
  • bash-specific:使用所谓的bashims

如果你想要

  • 简单的"在线"问题/答案(通用解决方案)
  • 使用libgtk或libqt的漂亮格式接口,如ncurses或更图形化的接口…
  • 使用强大的阅读线历史记录功能

1。POSIX通用解决方案

您可以使用read命令,然后使用if ... then ... else命令:

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

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

1
2
3
4
5
if ["$answer" !="${answer#[Yy]}" ] ;then
    echo Yes
else
    echo No
fi

(多亏了亚当·卡茨的评论:用一个更便携、避免使用一个分叉的测试替换了上面的测试。)

POSIX,但单键功能

但是如果您不希望用户必须点击return,您可以写:

(编辑:正如@jonathanlefler正确地建议的那样,保存stty的配置可能比简单地强迫他们保持清醒要好。)

1
2
3
4
5
6
7
8
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

注意:这是在sh、bash、ksh、dash和busybox下测试的!

相同,但明确等待yn

1
2
3
4
5
6
7
8
9
10
11
#/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

1
2
3
4
5
if whiptail --yesno"Is this a good question" 20 60 ;then
    echo Yes
else
    echo No
fi

根据您的系统,您可能需要用另一个类似的工具替换whiptail

1
2
3
4
5
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是对话框的宽度。这些工具都有几乎相同的语法。

1
2
3
4
5
DIALOG=whiptail
if [ -x /usr/bin/gdialog ] ;then DIALOG=gdialog ; fi
if [ -x /usr/bin/xdialog ] ;then DIALOG=xdialog ; fi
...
$DIALOG --yesno ...

2。bash特定的解决方案基本直线法

1
2
3
4
5
6
7
8
9
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命令指定预期输入的长度:

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

在bash下,read命令接受一个超时参数,这可能很有用。

1
2
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目的外,还有更复杂的对话框:

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

进度条:

1
2
3
4
5
6
7
8
9
10
dialog --gauge"Filling the tank" 20 60 0 < <(
    for i in {1..100};do
        printf"XXX\
%d\
%(%a %b %T)T progress: %d\
XXX\
"
$i -1 $i
        sleep .033
    done
)

小演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/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\
%d\
%%a %%b %%T progress: %d\
XXX\
" $i $i`
"

        sleep .0125
      done | $DIALOG --gauge"Filling the tank" 20 60 0
    $DIALOG --infobox"This is a simple info box\
\
No 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:\
Like: $AnsYesNo\
Input: $AnsInput\
Secret: $AnsPass"

    $DIALOG --msgbox"$out\
Attribs: $AnsCkLst\
Note: $AnsRadio"
20 60
  done

更多样本?看看使用whiptail选择USB设备和USB可移动存储选择器:usbkeycooser

5。使用readline的历史记录

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/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

这将在您的$HOME目录中创建一个文件.myscript.history,您无法使用readline的历史记录命令,如upbkbd、downctrl+r等。


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


您可以使用内置的read命令;使用-p选项提示用户问题。

由于bash4,现在可以使用-i来建议答案,所以用户只需按return就可以输入:

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

(但记住使用"readline"选项-e允许使用箭头键进行行编辑)

如果需要"是/否"逻辑,可以这样做:

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

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


Bash为此选择了。

1
2
3
4
select result in Yes No Cancel
do
    echo $result
done


1
2
3
4
5
6
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

以下是我整理的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/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

我是个初学者,所以拿着这个加一点盐,但它似乎有效。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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?"

...


你想要:

  • bash内置命令(即便携式)
  • 检查TTY
  • 默认答案
  • 超时
  • 彩色问题

片断

1
2
3
4
5
6
7
8
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,如果tty
  • read -n 1=>等待一个字符
  • $'\\e[1;32m ... \\e[0m '=>绿色打印(绿色很好,因为白色/黑色背景都可读)
  • [[ $do_xxxx =~ ^(y|Y|)$ ]]=>bash regex

超时=>默认答案为否

1
2
3
4
5
6
7
8
9
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


用最少的行数实现这一点的最简单方法如下:

1
2
3
4
5
read -p"<Your Friendly Message here> : y/n/cancel" CONDITION;

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

if只是一个例子:如何处理这个变量取决于您。


使用read命令:

1
2
3
4
5
6
7
8
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

然后所有你需要的东西


此解决方案读取单个字符并在Yes响应上调用函数。

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


1
read -e -p"Enter your choice:" choice

-e选项允许用户使用箭头键编辑输入。

如果要使用建议作为输入:

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

-i选项打印提示性输入。


很抱歉在这么旧的帖子上发帖。几周前,我也遇到了类似的问题,在我的例子中,我需要一个在在线安装程序脚本中也有效的解决方案,例如:curl -Ss https://raw.github.com/_____/installer.sh | bash

使用read yesno < /dev/tty对我来说很好:

1
2
3
4
5
6
7
8
9
10
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

希望这能帮助别人。


要获得像inputbox这样的好的ncurse,请使用如下的命令对话框:

1
2
3
4
5
6
7
8
9
#!/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上安装对话框包。


仅限单按键

这里有一个较长但可重用的模块化方法:

  • 返回0是,1
  • 不需要按Enter键-只需要一个字符
  • 可以按enter接受默认选项
  • 可以禁用默认选项以强制选择
  • 适用于zshbash

按Enter时默认为"否"

注意,N是大写的。在此按Enter,接受默认值:

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

另请注意,[y/N]?是自动附加的。默认的"否"被接受,因此没有任何响应。

重新提示直到给出有效响应:

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

按Enter时默认为"是"

注意,Y是资本化的:

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

上面,我刚按下Enter,命令就运行了。

enter无违约-需要YN

1
2
3
4
5
6
$ 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]?提示。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 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 '\
' -> ''
  [[ $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 '
\
' # $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
}


您可以在read上使用默认的REPLY,将其转换为小写,并与表达式中的一组变量进行比较。脚本还支持ja/si/oui

1
2
3
4
5
6
7
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

多选版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 '\
')"
&& printf '\
'

        (
            IFS='|'
            for o in $2; do
                if ["$REPLY" ="${o%%=*}" ]; then
                    printf '\
'

                    break
                fi
            done
        ) | grep ^ > /dev/null && return
    done
}

例子:

1
2
3
4
5
$ 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
$

它将把REPLY设置为y(在脚本中)。


我注意到,没有人发布一个答案,显示了这样简单的用户输入的多行回音菜单,所以下面是我的步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash

function ask_user() {    

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


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

这个方法被贴出来,希望有人能发现它有用,节省时间。


受@mark和@myrddin答案的启发,我创建了一个通用提示的函数

1
2
3
4
5
6
7
8
9
10
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\
"

    done
}

这样使用:

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

一个简单的方法是使用xargs -p或gnu parallel --interactive

我对此比较喜欢xargs的行为,因为它像其他交互的unix命令一样在提示后立即执行每个命令,而不是收集在末尾运行的yes。(您可以在完成所需的任务后按ctrl-c。)

例如。,

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


更一般的是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
}

我建议你使用对话…

Linux Apprentice: Improve Bash Shell Scripts Using Dialog

The dialog command enables the use of window boxes in shell scripts to make their use more interactive.

它简单易用,还有一个GNOME版本叫做gDialog,它使用完全相同的参数,但在X上显示了它的GUI样式。


1
2
3
4
5
6
7
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!'


作为单行命令的朋友,我使用了以下命令:

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

写的很长,它的工作原理如下:

1
2
3
4
5
6
7
8
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语句,使用case语句是一种很好的方法。一种while循环,它将case块重新封装起来,利用布尔条件可以实现,以便对程序进行更大的控制,并满足许多其它要求。在满足所有条件后,可以使用break,它将控制权传递回程序的主要部分。当然,为了满足其他条件,也可以在控制结构中添加条件语句:case语句和可能的while循环。

使用case语句来满足您的请求的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#! /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

回应他人:

您不需要在bash4中指定case,只需使用",,"将var变为小写。另外,我非常不喜欢把代码放在读取块内,得到结果并在读取块IMO之外处理它。还包括退出IMO的"q"。最后,为什么键入"yes"只使用-n1并按下y。

示例:用户可以按Y/N和Q退出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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"\
Answer = $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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/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
}

用法

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

用干净的用户输入确认功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/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
}

用法

1
2
3
4
5
if @confirm 'Confirm?' ; then
  echo"Yes"
else
  echo"No"
fi