在Linux shell脚本中提示用户选择Yes/No/Cancel的方法

在Linux shell脚本中提示用户选择Yes/No/Cancel的方法

技术背景

在Linux shell脚本编写过程中,经常需要暂停脚本执行并向用户询问选择,如常见的Yes、No或Cancel类型的问题。以下将介绍多种实现这种交互的方法。

实现步骤

1. 使用read命令结合case语句

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

上述代码中,read -p用于提示用户输入,case语句根据用户输入进行不同的处理。

2. 使用Bash的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命令会显示可用选项,用户输入对应数字进行选择。

3. POSIX通用解决方案

1
2
3
4
5
6
7
8
9
#/bin/sh
printf 'Is this a good question (y/n)? '
read answer

if [ "$answer" != "${answer#[Yy]}" ] ;then
echo Yes
else
echo No
fi

此方法使用read命令读取用户输入,通过if语句判断用户输入是否以Yy开头。

4. 使用专用工具(如whiptail

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

whiptail可创建交互对话框,根据用户选择返回不同结果。

核心代码

函数封装实现Yes/No/Cancel选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#/bin/sh
askFor() {
__aF_yExpr="$(locale yesexpr)" __aF_nExpr="$(locale noexpr)"
printf '%s? ' "$*"
__aF_oStty=$(stty -g)
stty raw -echo
__aF_key=$( while ! head -c 1| grep -P "\e|$__aF_yExpr|$__aF_nExpr"; do :;done )
stty $__aF_oStty
if [ "$__aF_key" != "${__aF_key#${__aF_yExpr#^}}" ]; then
echo Yes
return 0
elif [ "$__aF_key" != "${__aF_key#${__aF_nExpr#^}}" ]; then
echo No
return 1
fi
echo Cancel
exit
}

askFor "Do you want to continue?"

上述代码封装了一个函数askFor,用于提示用户选择Yes、No或Cancel。

最佳实践

  • 输入验证:确保用户输入有效,避免因无效输入导致脚本出错。
  • 国际化支持:使用locale命令获取本地化的Yes和No表达式,使脚本支持多语言。
  • 代码复用:将提示逻辑封装成函数,方便在不同脚本中复用。

常见问题

  • 输入未显示:在某些情况下,如通过远程SSH会话执行脚本,read -p的提示文本可能不显示。可使用echo -nread组合解决。
  • stty配置问题:在使用stty修改终端配置时,要注意保存原始配置并在操作完成后恢复,避免影响后续操作。
  • 不同shell兼容性:某些方法可能只适用于特定的shell(如Bash),在编写脚本时要考虑兼容性。

在Linux shell脚本中提示用户选择Yes/No/Cancel的方法
https://119291.xyz/posts/2025-04-23.prompting-yes-no-cancel-in-linux-shell-script/
作者
ww
发布于
2025年4月23日
许可协议