如何在bash脚本中提示用户进行确认?

我想把一个快速的“你确定吗?”提示确认在一个潜在的危险bash脚本的顶部,什么是最简单/最好的方法来做到这一点?

482102 次浏览

qnd:使用

read VARNAMEecho $VARNAME

对于没有readline支持的单行响应。然后根据需要测试$VARNAME。

read -p "Are you sure? " -n 1 -recho    # (optional) move to a new lineif [[ $REPLY =~ ^[Yy]$ ]]then# do dangerous stufffi

我结合了levislevis85的建议(谢谢!)并在read中添加了-n选项,以接受一个字符而无需按输入。您可以使用其中一个或两个。

另外,否定形式可能看起来像这样:

read -p "Are you sure? " -n 1 -recho    # (optional) move to a new lineif [[ ! $REPLY =~ ^[Yy]$ ]]then[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shellfi

但是,正如Erich所指出的,在某些情况下,例如脚本在错误的shell中运行引起的语法错误,否定形式可能会允许脚本继续“危险的东西”。失败模式应该有利于最安全的结果,因此应该只使用第一个非否定的if

说明:

read命令输出提示符(-p "prompt"),然后接受一个字符(-n 1)并按字面意思接受反斜杠(-r)(否则read会将反斜杠视为转义并等待第二个字符)。如果您不提供这样的名称,read存储结果的默认变量是$REPLYread -p "my prompt" -n 1 -r my_var

if语句使用正则表达式来检查$REPLY中的字符是否匹配(=~)大写或小写“Y”。此处使用的正则表达式表示“以(^)开头并仅由括号表达式([Yy])和结尾($)中的字符列表之一组成的字符串”。锚点(^$)阻止匹配更长的字符串。在这种情况下,它们有助于加强read命令中设置的单字符限制。

否定形式使用逻辑“not”运算符(!)来匹配(=~)任何不是“Y”或“y”的字符。表达这一点的另一种方式可读性较差,并且在我看来在本例中没有清楚地表达意图。然而,这就是它的样子:if [[ $REPLY =~ ^[^Yy]$ ]]

echo are you sure?read xif [ "$x" = "yes" ]then# do the dangerous stufffi

尝试read shell内置:

read -p "Continue (y/n)?" CONTif [ "$CONT" = "y" ]; thenecho "yaaa";elseecho "booo";fi
#!/bin/bashecho Please, enter your nameread NAMEecho "Hi $NAME!"if [ "x$NAME" = "xyes" ] ; then# do somethingfi

我是一个简短的脚本,可以在bash中阅读并回传结果。

这是我在其他地方找到的,有没有更好的版本?

read -p "Are you sure you wish to continue?"if [ "$REPLY" != "yes" ]; thenexitfi

用例/esac。

read -p "Continue (y/n)?" choicecase "$choice" iny|Y ) echo "yes";;n|N ) echo "no";;* ) echo "invalid";;esac

优势:

  1. 整洁
  2. 可以更容易地使用“OR”条件
  3. 可以使用字符范围,例如[yY][eE][sS]来接受单词“yes”,其中任何字符都可以是小写或大写。
[[ -f ./${sname} ]] && read -p "File exists. Are you sure? " -n 1
[[ ! $REPLY =~ ^[Yy]$ ]] && exit 1

在函数中使用它来查找现有文件并在覆盖前提示。

这样你就会得到'y''yes'或'into'

 read -r -p "Are you sure? [Y/n]" responseresponse=${response,,} # tolowerif [[ $response =~ ^(y| ) ]] || [[ -z $response ]]; thenyour-action-herefi

如果您使用的是zsh,请尝试以下操作:

read "response?Are you sure ? [Y/n] "response=${response:l} #tolowerif [[ $response =~ ^(y| ) ]] || [[ -z $response ]]; thenyour-action-herefi

这是我使用的函数:

function ask_yes_or_no() {read -p "$1 ([y]es or [N]o): "case $(echo $REPLY | tr '[A-Z]' '[a-z]') iny|yes) echo "yes" ;;*)     echo "no" ;;esac}

举一个使用它的例子:

if [[ "no" == $(ask_yes_or_no "Are you sure?") || \"no" == $(ask_yes_or_no "Are you *really* sure?") ]]thenecho "Skipped."exit 0fi
# Do something really dangerous...
  • 输出总是“是”或“否”
  • 默认为“否”
  • 除了“y”或“yes”之外的所有内容都返回“no”,因此对于危险的bash脚本来说非常安全
  • 并且不区分大小写,“Y”,“Yes”或“YES”作为“yes”工作。

希望你喜欢
干杯!