我想暂停shell脚本中的输入,并提示用户进行选择,例如标准的“是”、“否”或“取消”类型的问题。在典型的bash提示符下,如何实现这一点?
#!/bin/bash
function ask_user() {
echo -e "
#~~~~~~~~~~~~#
| 1.) Yes |
| 2.) No |
| 3.) Quit |
#~~~~~~~~~~~~#\n"
read -e -p "Select 1: " choice
if [ "$choice" == "1" ]; then
do_something
elif [ "$choice" == "2" ]; then
do_something_else
elif [ "$choice" == "3" ]; then
clear && exit 0
else
echo "Please select 1, 2, or 3." && sleep 3
clear && ask_user
fi
}
ask_user
请检查这个
read -p "Continue? (y/n): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1
受到@Mark和@Myrddin的答案启发,我创建了一个通用提示功能。
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"
多项选择版本:
ask () { # $1=question $2=options
# set REPLY
# options: x=..|y=..
while $(true); do
printf '%s [%s] ' "$1" "$2"
stty cbreak
REPLY=$(dd if=/dev/tty bs=1 count=1 2> /dev/null)
stty -cbreak
test "$REPLY" != "$(printf '\n')" && printf '\n'
(
IFS='|'
for o in $2; do
if [ "$REPLY" = "${o%%=*}" ]; then
printf '\n'
break
fi
done
) | grep ^ > /dev/null && return
done
}
例子:
$ ask 'continue?' 'y=yes|n=no|m=maybe'
continue? [y=yes|n=no|m=maybe] g
continue? [y=yes|n=no|m=maybe] k
continue? [y=yes|n=no|m=maybe] y
$
REPLY
设置为y
。Linux学徒:使用Dialog改进Bash Shell脚本
Dialog命令使得在shell脚本中使用窗口更加交互式。
它简单易用,还有一个名为gdialog的gnome版本,可以使用相同的参数,但在X上以GUI样式显示。
function menu(){
title="Question time"
prompt="Select:"
options=("Yes" "No" "Maybe")
echo "$title"
PS3="$prompt"
select opt in "${options[@]}" "Quit/Cancel"; do
case "$REPLY" in
1 ) echo "You picked $opt which is option $REPLY";;
2 ) echo "You picked $opt which is option $REPLY";;
3 ) echo "You picked $opt which is option $REPLY";;
$(( ${#options[@]}+1 )) ) clear; echo "Goodbye!"; exit;;
*) echo "Invalid option. Try another one.";continue;;
esac
done
return
}
最简单的解决方案是这个没有巧妙技巧的一行代码:
read -p "press enter ..." y
这让人想起了经典的DOS系统的提示“按任意键继续”,不过这里只等待回车键,而非任何键。
确实,它没有为您提供三个选项:是、否、取消;但在像简单脚本中接受控制-C作为"否"或"取消"时,它是很有用的,例如:
#!/bin/sh
echo Backup this project
read -p "press enter ..." y
rsync -tavz . /media/hard_to_remember_path/backup/projects/yourproject/
sh
,需要使用命令行参数y
,并且可以选择使用它来接收用户在按下回车键之前键入的答案,就像这样:echo You entered $y
bash
,您可以省略最后一个参数直接使用:read -p "press enter ..."
read -p "press enter ..." y
中不需要 y
。 - rychwhile [ -z $prompt ]; do read -p "Continue (y/n)?" choice;case "$choice" in y|Y ) prompt=true; break;; n|N ) exit 0;; esac; done; prompt=;
如果要进行长篇写作,它的工作方式如下:
while [ -z $prompt ];
do read -p "Continue (y/n)?" choice;
case "$choice" in
y|Y ) prompt=true; break;;
n|N ) exit 0;;
esac;
done;
prompt=;
以下是我通常在脚本/函数中需要的内容:
while true; do
read -p "Continue [Y/n]? " -n 1 -r -e yn
case "${yn:-Y}" in
[YyZzOoJj]* ) echo; break ;;
[Nn]* ) [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 ;; # handle exits from shell or function but don't exit interactive shell
* ) echo "Please answer yes or no.";;
esac
done
echo "and off we go!"
#!/usr/bin/env bash
@confirm() {
local message="$*"
local result=''
echo -n "> $message (Yes/No/Cancel) " >&2
while [ -z "$result" ] ; do
read -s -n 1 choice
case "$choice" in
y|Y ) result='Y' ;;
n|N ) result='N' ;;
c|C ) result='C' ;;
esac
done
echo $result
}
case $(@confirm 'Confirm?') in
Y ) echo "Yes" ;;
N ) echo "No" ;;
C ) echo "Cancel" ;;
esac
#!/usr/bin/env bash
@confirm() {
local message="$*"
local result=3
echo -n "> $message (y/n) " >&2
while [[ $result -gt 1 ]] ; do
read -s -n 1 choice
case "$choice" in
y|Y ) result=0 ;;
n|N ) result=1 ;;
esac
done
return $result
}
if @confirm 'Confirm?' ; then
echo "Yes"
else
echo "No"
fi
[yn]
选项,则大写字母是默认值。即[Yn]
默认为“yes”,[yN]
默认为“no”。请参见https://ux.stackexchange.com/a/40445/43532 - Tyzoidread
命令进行提示。 - smac89bash
中暂停的规范方式。提供的结果可以轻松转移。 - Cadoiz