使用read
命令:
echo Would you like to install? "(Y or N)"
read x
# now check if $x is "y"
if [ "$x" = "y" ]; then
# do something here!
fi
然后你还需要所有其他必需品。
#!/bin/bash
if (dialog --title "Message" --yesno "Want to do something risky?" 6 25)
# message box will have the size 25x6 characters
then
echo "Let's do something risky"
# do something risky
else
echo "Let's stay boring"
fi
--defaultno
参数,以确保默认选择“否”选项。 - WiMantis这个解决方案读取单个字符,并在“是”的响应上调用一个函数。
read -p "Are you sure? (y/n) " -n 1
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
do_something
fi
echo
以查看效果。 - Dennis使用 LC_MESSAGES
区域设置类别的条目,可以在 POSIX shell 中处理与区域设置相关的“是/否选择”; 该类别提供了现成的正则表达式模式来匹配输入,并提供本地化的“是/否”字符串。
#!/usr/bin/env sh
# Getting LC_MESSAGES values into variables
# shellcheck disable=SC2046 # Intended IFS splitting
IFS='
' set -- $(locale LC_MESSAGES)
yesexpr="$1"
noexpr="$2"
yesstr="$3"
nostr="$4"
messages_codeset="$5" # unused here, but kept as documentation
# Display Yes / No ? prompt into locale
echo "$yesstr / $nostr ?"
# Read answer
read -r yn
# Test answer
case "$yn" in
# match only work with the character class from the expression
${yesexpr##^}) echo "answer $yesstr" ;;
${noexpr##^}) echo "answer $nostr" ;;
esac
编辑:
如@Urhixidur在他的评论中所提到的:
不幸的是,POSIX仅规定了前两个(
yesexpr
和noexpr
)。在Ubuntu 16上,yesstr
和nostr
为空。
参见:https://www.ee.ryerson.ca/~courses/ele709/susv4/xrat/V4_xbd_chap07.html#tag_21_07_03_06
LC_MESSAGES
yesstr
和nostr
区域设置关键字,以及YESSTR
和NOSTR
langinfo项以前用于匹配用户肯定和否定响应。在POSIX.1-2008中,扩展的正则表达式yesexpr
、noexpr
、YESEXPR
和NOEXPR
已取代它们。应用程序应使用基于区域设置的通用消息传递功能来发出包含所需响应示例的提示消息。
或者使用Bash方式使用区域设置:
#!/usr/bin/env bash
IFS=$'\n' read -r -d '' yesexpr noexpr _ < <(locale LC_MESSAGES)
printf -v yes_or_no_regex "(%s)|(%s)" "$yesexpr" "$noexpr"
printf -v prompt $"Please answer Yes (%s) or No (%s): " "$yesexpr" "$noexpr"
declare -- answer=;
until [[ "$answer" =~ $yes_or_no_regex ]]; do
read -rp "$prompt" answer
done
if [[ -n "${BASH_REMATCH[1]}" ]]; then
echo $"You answered: Yes"
else
echo $"No, was your answer."
fi
使用本地环境提供的正则表达式来匹配答案。
要翻译剩余的信息,请使用 bash --dump-po-strings scriptname
输出用于本地化的po字符串:
#: scriptname:8
msgid "Please answer Yes (%s) or No (%s): "
msgstr ""
#: scriptname:17
msgid "You answered: Yes"
msgstr ""
#: scriptname:19
msgid "No, was your answer."
msgstr ""
yesexpr
和noexpr
的最佳方法是在Bash的特定正则表达式匹配中使用它,例如:if [[ "$yn" =~ $yesexpr ]]; then echo $"Answered yes"; else echo $"Answered no"; fi
。 - Léa Grislocal LC_MESSAGES
显示为 ^[+1yY] ^[-0nN] yes no UTF-8
。有趣的是,这些正则表达式接受了+/-和0/1。也许它们期望一个机器人来使用提示。 - foxesquelocal LC_MESSAGES
显示^[+1yY] ^[-0nN] yes no UTF-8
。有趣的是,这些正则表达式接受+/-和0/1。也许它们期望一个机器人使用提示符。 - undefined在我的情况下,我需要从一个已下载的脚本中读取,即:
curl -Ss https://example.com/installer.sh | sh
在这种情况下,read -r yn </dev/tty
这一行允许它读取输入。
printf "These files will be uploaded. Is this ok? (y/N) "
read -r yn </dev/tty
if [ "$yn" = "y" ]; then
# Yes
else
# No
fi
tty
输入,就像你所做的那样,也会对你有所帮助,并且还可以在输入错误时进行循环(想象一下缓冲区中有几个字符;你的方法将强制用户始终选择“否”)。 - Myrddin Emrys以下是一个更长的、可重复使用和模块化的方法:
0
=是 和 1
=否zsh
和bash
。请注意,N
要大写。这里按下了Enter键,接受了默认值:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?
还要注意,[y/N]?
已被自动添加。
默认情况下,“不”被接受,因此没有任何回显。
重新提示,直到给出有效的响应:
$ 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]?
提示。
# 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
}
Show dangerous command [y/N]? [y/n]?
和 Show dangerous command [Y/n]? [y/n]?
。 - Ilias Karim您可以在read
上使用默认的REPLY
,转换为小写并与一组变量进行比较。
脚本还支持ja
/si
/oui
read -rp "Do you want a demo? [y/n/c] "
[[ ${REPLY,,} =~ ^(c|cancel)$ ]] && { echo "Selected Cancel"; exit 1; }
if [[ ${REPLY,,} =~ ^(y|yes|j|ja|s|si|o|oui)$ ]]; then
echo "Positive"
fi
read -e -p "Enter your choice: " choice
-e
选项使用户可以使用箭头键编辑输入。
如果您想使用建议作为输入:
read -e -i "yes" -p "Enter your choice: " choice
-i
选项会打印一个提示性的输入。
对于这个问题,有很多好的答案,但从我所看到的来看,没有一个是我理想的,它应该:
以下是符合上述要求的版本:
read -n1 -p "Continue? (Y/n) " confirm
if ! echo $confirm | grep '^[Yy]\?$'; then
exit 1
fi
if 语句中删除!),或者添加一个 else ,以便在两个分支上运行代码。
一句话概括:
read -p "Continue? [Enter] → Yes, [Ctrl]+[C] → No."
[yn]
选项,则大写字母是默认值。即[Yn]
默认为“yes”,[yN]
默认为“no”。请参见https://ux.stackexchange.com/a/40445/43532 - Tyzoidread
命令进行提示。 - smac89bash
中暂停的规范方式。提供的结果可以轻松转移。 - Cadoiz