我想暂停shell脚本中的输入,并提示用户进行选择。标准的是、否或取消类型问题。如何在典型的bash提示符中完成此操作?
当前回答
仅单个按键
这里有一个更长但可重复使用的模块化方法:
返回0=yes和1=no无需按enter键-仅需一个字符可以按enter键接受默认选择可以禁用默认选项以强制选择适用于zsh和bash。
按enter键时默认为“否”
请注意,N是大写的。此处按enter键,接受默认值:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?
还要注意,[y/N]?已自动追加。默认的“no”被接受,因此不会有任何回音。
重新提示,直到给出有效响应:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *
按回车键时默认为“是”
请注意,Y是大写的:
$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *
上面,我刚刚按了回车键,所以命令运行了。
输入时无默认值-需要y或n
$ get_yes_keypress "Here you cannot press enter. Do you like this [y/n]? "
Here you cannot press enter. Do you like this [y/n]? k
Here you cannot press enter. Do you like this [y/n]?
Here you cannot press enter. Do you like this [y/n]? n
$ echo $?
1
这里,返回了1或false。请注意,使用此较低级别的函数,您需要提供自己的[y/n]?促使
Code
# Read a single char from /dev/tty, prompting with "$*"
# Note: pressing enter will return a null string. Perhaps a version terminated with X and then remove it in caller?
# See https://unix.stackexchange.com/a/367880/143394 for dealing with multi-byte, etc.
function get_keypress {
local REPLY IFS=
>/dev/tty printf '%s' "$*"
[[ $ZSH_VERSION ]] && read -rk1 # Use -u0 to read from STDIN
# See https://unix.stackexchange.com/q/383197/143394 regarding '\n' -> ''
[[ $BASH_VERSION ]] && </dev/tty read -rn1
printf '%s' "$REPLY"
}
# Get a y/n from the user, return yes=0, no=1 enter=$2
# Prompt using $1.
# If set, return $2 on pressing enter, useful for cancel or defualting
function get_yes_keypress {
local prompt="${1:-Are you sure [y/n]? }"
local enter_return=$2
local REPLY
# [[ ! $prompt ]] && prompt="[y/n]? "
while REPLY=$(get_keypress "$prompt"); do
[[ $REPLY ]] && printf '\n' # $REPLY blank if user presses enter
case "$REPLY" in
Y|y) return 0;;
N|n) return 1;;
'') [[ $enter_return ]] && return "$enter_return"
esac
done
}
# Credit: http://unix.stackexchange.com/a/14444/143394
# Prompt to confirm, defaulting to NO on <enter>
# Usage: confirm "Dangerous. Are you sure?" && rm *
function confirm {
local prompt="${*:-Are you sure} [y/N]? "
get_yes_keypress "$prompt" 1
}
# Prompt to confirm, defaulting to YES on <enter>
function confirm_yes {
local prompt="${*:-Are you sure} [Y/n]? "
get_yes_keypress "$prompt" 0
}
其他回答
Bash为此选择了。以下是如何在脚本中使用它:
select result in Yes No Cancel
do
echo $result
done
这是它使用的样子:
$ bash examplescript.sh
1) Yes
2) No
3) Cancel
#? 1
Yes
#? 2
No
#? 3
Cancel
#?
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"
受到@Mark和@Myrdin的回答的启发,我创建了一个通用提示的函数
uniprompt(){
while true; do
echo -e "$1\c"
read opt
array=($2)
case "${array[@]}" in *"$opt"*) eval "$3=$opt";return 0;; esac
echo -e "$opt is not a correct value\n"
done
}
这样使用:
unipromtp "Select an option: (a)-Do one (x)->Do two (f)->Do three : " "a x f" selection
echo "$selection"
inquire () {
echo -n "$1 [y/n]? "
read answer
finish="-1"
while [ "$finish" = '-1' ]
do
finish="1"
if [ "$answer" = '' ];
then
answer=""
else
case $answer in
y | Y | yes | YES ) answer="y";;
n | N | no | NO ) answer="n";;
*) finish="-1";
echo -n 'Invalid response -- please reenter:';
read answer;;
esac
fi
done
}
... other stuff
inquire "Install now?"
...
您可以使用内置的read命令;使用-p选项向用户提示问题。
从BASH4开始,您现在可以使用-i建议答案:
read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
echo $FILEPATH
(但请记住使用“readline”选项-e以允许使用箭头键进行行编辑)
如果你想要一个“是/否”的逻辑,你可以这样做:
read -e -p "
List the content of your home dir ? [Y/n] " YN
[[ $YN == "y" || $YN == "Y" || $YN == "" ]] && ls -la ~/
推荐文章
- Shell脚本删除超过n天的目录
- 使用sudo时未找到命令
- 如何防止rm报告文件未找到?
- 当有命令行参数时,如何使用GDB分析程序的核心转储文件?
- 如何检查shell脚本中是否存在命令?
- Bash:获取输出的第n列的最短方法
- 如何使用查找命令从列表中查找所有具有扩展名的文件?
- 如何获得一个变量值,如果变量名存储为字符串?
- RVM不是一个函数,用' RVM use…’不会起作用
- 如何强制从另一个SSH会话分离屏幕?
- 如何打破一个循环在Bash?
- 如何从终端机发送电子邮件?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- Linux Bash中双&和分号有什么区别?
- 如何合并2 JSON对象从2个文件使用jq?