在 Bash 中,如何将“Are you sure [Y/n]”添加到任何命令或别名?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3231804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Bash, how to add "Are you sure [Y/n]" to any command or alias?
提问by nonopolarity
In this particular case, I'd like to add a confirm in Bash for
在这种特殊情况下,我想在 Bash 中添加一个确认
Are you sure? [Y/n]
for Mercurial's hg push ssh://[email protected]//somepath/morepath
, which is actually an alias. Is there a standard command that can be added to the alias to achieve it?
对于 Mercurial 的hg push ssh://[email protected]//somepath/morepath
,它实际上是一个别名。是否有标准命令可以添加到别名中以实现它?
The reason is that hg push
and hg out
can sound similar and sometimes when I want hgoutrepo
, I may accidentlly type hgpushrepo
(both are aliases).
原因是hg push
和hg out
听起来很相似,有时当我想要时hgoutrepo
,我可能会不小心输入hgpushrepo
(两者都是别名)。
Update:if it can be something like a built-in command with another command, such as: confirm && hg push ssh://...
that'd be great... just a command that can ask for a yes
or no
and continue with the rest if yes
.
更新:如果它可以是带有另一个命令的内置命令,例如:confirm && hg push ssh://...
那就太好了......只是一个可以要求 a yes
orno
并继续其余 if 的命令yes
。
回答by Paused until further notice.
These are more compact and versatile forms of Hamish'sanswer. They handle any mixture of upper and lower case letters:
这些是Hamish'sanswer 的更紧凑和更通用的形式。它们处理大小写字母的任何混合:
read -r -p "Are you sure? [y/N] " response
case "$response" in
[yY][eE][sS]|[yY])
do_something
;;
*)
do_something_else
;;
esac
Or, for Bash >= version 3.2:
或者,对于 Bash >= 3.2 版:
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]
then
do_something
else
do_something_else
fi
Note: If $response
is an empty string, it will give an error. To fix, simply add quotation marks: "$response"
. – Always use double quotes in variables containing strings (e.g.: prefer to use "$@"
instead $@
).
注意:如果$response
是空字符串,则会报错。要修复,只需添加引号:"$response"
. -始终包含字符串变量用双引号(如:喜欢使用"$@"
代替$@
)。
Or, Bash 4.x:
或者,Bash 4.x:
read -r -p "Are you sure? [y/N] " response
response=${response,,} # tolower
if [[ "$response" =~ ^(yes|y)$ ]]
...
Edit:
编辑:
In response to your edit, here's how you'd create and use a confirm
command based on the first version in my answer (it would work similarly with the other two):
为了响应您的编辑,以下是您将如何confirm
根据我的答案中的第一个版本创建和使用命令(它与其他两个版本类似):
confirm() {
# call with a prompt string or use a default
read -r -p "${1:-Are you sure? [y/N]} " response
case "$response" in
[yY][eE][sS]|[yY])
true
;;
*)
false
;;
esac
}
To use this function:
要使用此功能:
confirm && hg push ssh://..
or
或者
confirm "Would you really like to do a push?" && hg push ssh://..
回答by Hamish Grubijan
Here is roughly a snippet that you want. Let me find out how to forward the arguments.
这是您想要的大致片段。让我找出如何转发论点。
read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]
then
# http://stackoverflow.com/questions/1537673/how-do-i-forward-parameters-to-other-command-in-bash-script
else
exit 0
fi
Watch out for yes | command name here
:)
当心yes | command name here
:)
回答by briceburg
Confirmations are easily bypassed with carriage returns, and I find it useful to continually prompt for valid input.
回车很容易绕过确认,我发现不断提示输入有效信息很有用。
Here's a function to make this easy. "invalid input" appears in red if Y|N is not received, and the user is prompted again.
这是一个使这变得容易的函数。如果没有收到Y|N,“无效输入”显示为红色,再次提示用户。
prompt_confirm() {
while true; do
read -r -n 1 -p "${1:-Continue?} [y/n]: " REPLY
case $REPLY in
[yY]) echo ; return 0 ;;
[nN]) echo ; return 1 ;;
*) printf " 3[31m %s \n3[0m" "invalid input"
esac
done
}
# example usage
prompt_confirm "Overwrite File?" || exit 0
You can change the default prompt by passing an argument
您可以通过传递参数来更改默认提示
回答by user389850
To avoid explicitly checking for these variants of 'yes' you could use the bash regular expression operator '=~' with a regular expression:
为了避免显式检查 'yes' 的这些变体,您可以将 bash 正则表达式运算符 '=~' 与正则表达式一起使用:
read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt =~ [yY](es)* ]]
then
(etc...)
That tests whether the user input starts with 'y' or 'Y' and is followed by zero or more 'es's.
这将测试用户输入是否以“y”或“Y”开头,并后跟零个或多个“es”。
回答by nonopolarity
This may be a hack:
这可能是一个黑客:
as in question In Unix / Bash, is "xargs -p" a good way to prompt for confirmation before running any command?
如问题在Unix / Bash中,“xargs -p”是在运行任何命令之前提示确认的好方法吗?
we can using xargs
to do the job:
我们可以xargs
用来完成这项工作:
echo ssh://[email protected]//somepath/morepath | xargs -p hg push
of course, this will be set as an alias, like hgpushrepo
当然,这将被设置为别名,例如 hgpushrepo
Example:
例子:
$ echo foo | xargs -p ls -l
ls -l foo?...y
-rw-r--r-- 1 mikelee staff 0 Nov 23 10:38 foo
$ echo foo | xargs -p ls -l
ls -l foo?...n
$
回答by MattyV
Add the following to your /etc/bashrc file. This script adds a resident "function" instead of an alias called "confirm".
将以下内容添加到您的 /etc/bashrc 文件中。该脚本添加了一个常驻“函数”,而不是一个名为“确认”的别名。
function confirm( )
{
#alert the user what they are about to do.
echo "About to $@....";
#confirm with the user
read -r -p "Are you sure? [Y/n]" response
case "$response" in
[yY][eE][sS]|[yY])
#if yes, then execute the passed parameters
"$@"
;;
*)
#Otherwise exit...
echo "ciao..."
exit
;;
esac
}
回答by commonpike
This may be a little too short, but for my own private use, it works great
这可能有点太短了,但对于我自己的私人使用来说,效果很好
read -n 1 -p "Push master upstream? [Y/n] " reply;
if [ "$reply" != "" ]; then echo; fi
if [ "$reply" = "${reply#[Nn]}" ]; then
git push upstream master
fi
The read -n 1
just reads one character. No need to hit enter. If it's not a 'n' or 'N', it is assumed to be a 'Y'. Just pressing enter means Y too.
该read -n 1
只读取一个字符。无需按回车键。如果它不是“n”或“N”,则假定它是“Y”。只需按 Enter 也意味着 Y。
(as for the real question: make that a bash script and change your alias to point to that script instead of what is was pointing to before)
(至于真正的问题:将其设为 bash 脚本并将别名更改为指向该脚本而不是之前指向的内容)
回答by SergioAraujo
read -r -p "Are you sure? [Y/n]" response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
your-action-here
fi
回答by Tom Hale
No pressing enter required
无需按回车键
Here's a longer, but reusable and modular approach:
这是一个更长但可重用的模块化方法:
- Returns
0
=yes and1
=no - No pressing enter required - just a single character
- Can press enterto accept the default choice
- Can disable default choice to force a selection
- Works for both
zsh
andbash
.
- 返回
0
=yes 和1
=no - 无需按 Enter - 只需一个字符
- 可以按enter接受默认选择
- 可以禁用默认选择以强制选择
- 适用于
zsh
和bash
。
Defaulting to "no" when pressing enter
按 Enter 时默认为“no”
Note that the N
is capitalsed. Here enter is pressed, accepting the default:
请注意,N
是大写的。这里按下回车,接受默认值:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?
Also note, that [y/N]?
was automatically appended.
The default "no" is accepted, so nothing is echoed.
另请注意,这[y/N]?
是自动附加的。接受默认的“no”,所以没有回显。
Re-prompt until a valid response is given:
重新提示直到给出有效响应:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *
Defaulting to "yes" when pressing enter
按回车时默认为“是”
Note that the Y
is capitalised:
请注意,Y
大写:
$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *
Above, I just pressed enter, so the command ran.
在上面,我只是按了 Enter,所以命令就运行了。
No default on enter- require y
or n
没有默认值enter- 需要y
或n
$ get_yes_keypress "Here you cannot press enter. Do you like this"
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
Here, 1
or false was returned. Note no capitalisation in [y/n]?
在这里,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=
# Prompt using .
# If set, return on pressing enter, useful for cancel or defualting
function get_yes_keypress {
local prompt="${1:-Are you sure} [y/n]? "
local enter_return=
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
}
回答by jasonleonhard
This version allows you to have more than one case y
or Y
, n
or N
此版本允许您拥有多个 casey
或Y
,n
或N
Optionally: Repeat the question until an approve question is provided
Optionally: Ignore any other answer
Optionally: Exit the terminal if you want
confirm() { echo -n "Continue? y or n? " read REPLY case $REPLY in [Yy]) echo 'yup y' ;; # you can change what you do here for instance [Nn]) break ;; # exit case statement gracefully # Here are a few optional options to choose between # Any other answer: # 1. Repeat the question *) confirm ;; # 2. ignore # *) ;; # 3. Exit terminal # *) exit ;; esac # REPLY='' }
可选:重复问题,直到提供批准问题
可选:忽略任何其他答案
可选:如果需要,退出终端
confirm() { echo -n "Continue? y or n? " read REPLY case $REPLY in [Yy]) echo 'yup y' ;; # you can change what you do here for instance [Nn]) break ;; # exit case statement gracefully # Here are a few optional options to choose between # Any other answer: # 1. Repeat the question *) confirm ;; # 2. ignore # *) ;; # 3. Exit terminal # *) exit ;; esac # REPLY='' }
Notice this too: On the last line of this function clear the REPLY variable. Otherwise if you echo $REPLY
you will see it is still set until you open or close your terminal or set it again.
还要注意这一点:在此函数的最后一行清除 REPLY 变量。否则,如果您echo $REPLY
会看到它仍然设置,直到您打开或关闭终端或再次设置它。