协慌网

登录 贡献 社区

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

我想快速说一句 “您确定吗?” 在潜在危险的 bash 脚本顶部提示您进行确认时,最简单 / 最佳的方法是什么?

答案

read -p "Are you sure? " -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
    # do dangerous stuff
fi

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

此外,取反的形式可能如下所示:

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

但是,正如 Erich 指出的那样,在某些情况下,例如由于脚本在错误的 Shell 中运行导致的语法错误,取反的形式可能会使脚本继续出现 “危险的东西”。故障模式应支持最安全的结果,因此,仅应使用if

解释:

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

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

否定形式使用逻辑 “not” 运算符( ! )来匹配( =~ )任何不是 “Y” 或 “y” 的字符。在这种情况下,我认为另一种表达方式的可读性较差,无法明确表达其意图。但是,它是这样的: if [[ $REPLY =~ ^[^Yy]$ ]]

用例 / esac。

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

优势:

  1. 更整洁
  2. 可以更轻松地使用 “或” 条件
  3. 可以使用字符范围,例如 [yY] [eE] [sS] 接受单词 “是”,其中任何字符都可以小写或大写。

尝试read外壳程序:

read -p "Continue (y/n)?" CONT
if [ "$CONT" = "y" ]; then
  echo "yaaa";
else
  echo "booo";
fi