我想在一个有潜在危险的bash脚本的顶部放一个快速的"你确定吗?"提示,以便确认,有什么最简单/最好的方法可以做到这一点?
read -p "Are you sure? "-n 1 -r
echo #(可选)移到新的一行
如果 [[ $REPLY =~ ^[Yy]$ ]]
那么
# 做危险的事情
fi
我采纳了levislevis85'的建议(谢谢!),并在read
中加入了n
选项,以接受一个字符而不需要按Enter。你可以使用其中的一个或两个。
另外,被否定的形式可能看起来像这样。
read -p "Are you sure? "-n 1 -r
echo # (可选)移到一个新行
如果[[ !$REPLY =~ ^[Yy]$ ]]
那么
[[ "$0" = "$BASH_SOURCE"]] && exit 1 || return 1 # 处理来自shell或函数的退出,但不退出互动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]$ ]]
。
使用case/esac.
read -p "Continue (y/n)?" choice
case "$choice" in
y|Y ) echo "yes";;
n|N ) echo "no";;
* ) echo "invalid";;
esac
优势。
可以使用"OR"。 条件更容易
可以使用字符范围,例如[yY][eE][sS]接受单词"yes",其中任何一个字符可以是小写或大写。
这样你就可以得到'y'。 '是'。 或'回车&39。
read -r -p "Are you sure? [Y/n]" response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
your-action-here
fi
如果你正在使用zsh,可以试试这个。
read "response?Are you sure ? [Y/n] "
response=${response:l} #tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
your-action-here
fi
这是我使用的函数。
function ask_yes_or_no() {
read -p "$1 ([y]es or [N]o): "
case $(echo $REPLY | tr '[A-Z]' '[a-z]') in
y|yes) echo "yes" ;;
*) echo "no" ;;
esac
}
并举例使用它。
if [[ "no" == $(ask_yes_or_no "Are you sure?") || \
"no" == $(ask_yes_or_no "Are you *really* sure?") ]]
then
echo "Skipped."
exit 0
fi
# Do something really dangerous...
希望你喜欢,<br/>。 欢呼吧!