如何在Linux shell脚本中提示是/否/取消输入?
我想在shell脚本中暂停输入,并提示用户进行选择。 标准的“是,否,或取消”类型问题。 我如何在典型的bash提示符下完成此操作?
  在shell提示下获取用户输入的最简单和最广泛的方法是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指出的方法是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的优秀答案。
一个通用问题至少有五个答案。
取决于
如果你想
1. POSIX通用解决方案
  你可以使用read命令,接下来是if ... then ... else : 
echo -n "Is this a good question (y/n)? "
read answer
# if echo "$answer" | grep -iq "^y" ;then
#(感谢Adam Katz的评论:这个测试更便携,避免一个分叉:)
if [ "$answer" != "${answer#[Yy]}" ] ;then
    echo Yes
else
    echo No
fi
POSIX,但单一的关键功能
但是如果你不希望用户必须点击返回,你可以这样写:
( 编辑:正如@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
注意:这是在sh,bash,ksh,dash和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
使用专用工具
  有许多工具是使用libncurses , libgtk , libqt或其他图形库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 ,对话框的宽度是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 yes | ja | si | oui  yes | ja | si | oui如果需要... 
符合单一关键功能
  在bash下,我们可以为read命令指定预期输入的长度: 
read -n 1 -p "Is this a good question (y/n)? " answer
  在bash下, 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
专用工具的一些技巧
  更复杂的对话框,超越简单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 "XXXn%dn%(%a %b %T)T progress: %dnXXXn" $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 "XXXn%dn%%a %%b %%T progress: %dnXXXn" $i $i`"
        sleep .0125
      done | $DIALOG --gauge "Filling the tank" 20 60 0
    $DIALOG --infobox "This is a simple info boxnnNo 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: $AnsYesNonInput: $AnsInputnSecret: $AnsPass"
    $DIALOG --msgbox "$outnAttribs: $AnsCkLstnNote: $AnsRadio" 20 60
  done
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
  这将在您的$HOME目录中创建一个.myscript.history文件,比您可以使用readline的历史命令(如Up,Down,Ctrl + r等)。 
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"
                        链接地址: http://www.djcxy.com/p/635.html
                        上一篇: How do I prompt for Yes/No/Cancel input in a Linux shell script?
