在Bash中,如何给任何命令或别名添加“你确定”?
在这个特殊情况下,我想在Bash中添加一个确认
你确定? [Y / N]
对于Mercurial的hg push ssh://username@www.example.com//somepath/morepath
,这实际上是一个别名。 有没有一个标准的命令可以添加到别名来实现它?
原因是hg push
和hg out
听起来可能相似,有时当我想要hgoutrepo
,我可能会偶然地inputhgpushrepo
(都是别名)。
更新:如果它可以像一个内置的命令与另一个命令,如: confirm && hg push ssh://...
那将是伟大的…只是一个命令,可以要求yes
或no
如果yes
,继续其余的。
这些是更加紧凑和多样的forms的Hamish的答案 。 他们处理任何大写和小写字母的混合物:
read -r -p "Are you sure? [y/N] " response case "$response" in [yY][eE][sS]|[yY]) do_something ;; *) do_something_else ;; esac
或者,对于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
注意:如果$response
是一个空string,它会给出一个错误。 要修复,只需添加引号: "$response"
。 – 在包含string的variables中总是使用双引号(例如:倾向于使用"$@"
而不是$@
)。
或者,Bash 4.x:
read -r -p "Are you sure? [y/N] " response response=${response,,} # tolower if [[ "$response" =~ ^(yes|y)$ ]] ...
编辑:
为了响应你的编辑,下面是你如何创build和使用基于我的答案中的第一个版本的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 }
要使用这个function:
confirm && hg push ssh://..
要么
confirm "Would you really like to do a push?" && hg push ssh://..
这里大概是你想要的片段。 让我来看看如何转发这些论点。
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
注意yes | command name here
yes | command name here
🙂
为了避免显式检查这些“是”的变体,可以使用正则expression式使用bash正则expression式运算符'=〜':
read -p "Are you sure you want to continue? <y/N> " prompt if [[ $prompt =~ [yY](es)* ]] then (etc...)
testing用户input是以“y”还是“Y”开头,后跟零个或多个“es”。
确认很容易绕过回车,我发现有用的是不断提示有效的input。
这是一个简单的function。 如果未收到Y | N,则“无效input”显示为红色,并且再次提示用户。
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 " \033[31m %s \n\033[0m" "invalid input" esac done } # example usage prompt_confirm "Overwrite File?" || exit 0
您可以通过传递参数来更改默认提示
这可能是一个黑客:
如在问题在Unix / Bash中,“xargs -p”是在运行任何命令之前提示进行确认的好方法?
我们可以使用xargs
来完成这个工作:
echo ssh://username@www.example.com//somepath/morepath | xargs -p hg push
当然,这将被设置为一个别名,如hgpushrepo
例:
$ 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 $
read -r -p "Are you sure? [Y/n]" response response=${response,,} # tolower if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then your-action-here fi
将以下内容添加到/ 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 }
在游戏后期,我创build了另一个以前答案的confirm
函数的变体:
confirm () { read -r -p "$(echo $@) ? [y/N] " YESNO if [ "$YESNO" != "y" ]; then echo >&2 "Aborting" exit 1 fi CMD="$1" shift while [ -n "$1" ]; do echo -en "$1\0" shift done | xargs -0 "$CMD" || exit $? }
要使用它:
confirm your_command
特征:
- 打印你的命令作为提示的一部分
- 通过使用NULL分隔符传递参数
- 保留你的命令的退出状态
错误:
-
echo -en
与bash
但可能在你的shell中失败 - 如果参数干扰
echo
或xargs
可能会失败 - 还有其他的bug,因为shell脚本很难
尝试,
#!/bin/bash pause () { REPLY=Y while [ "$REPLY" == "Y" ] || [ "$REPLY" != "y" ] do echo -e "\t\tPress 'y' to continue\t\t\tPress 'n' to quit" read -n1 -s case "$REPLY" in "n") exit ;; "N") echo "case sensitive!!" ;; "y") clear ;; "Y") echo "case sensitive!!" ;; * ) echo "$REPLY is Invalid Option" ;; esac done } pause echo "Hi"
那么,这是我的版本confirm
,从詹姆斯的一个修改:
function confirm() { local response local msg="${1:-Are you sure?} [y/N] "; shift read -r $* -p "$msg" response || echo case "$response" in [yY][eE][sS]|[yY]) return 0 ;; *) return 1 ;; esac }
这些变化是:
- 使用
local
来防止variables名称冲突 -
read
使用$2 $3 ...
来控制它的行为,所以你可以使用-n
和-t
- 如果
read
不成功,则echo
一个换行以获得美观 - 我
Git on Windows
只有bash-3.1
并且没有true
或false
,所以使用return
来代替。
这不完全是一个“要求是或否”,而只是一个黑客:别名hg push ...
不是hgpushrepo
而是hgpushrepoconfirmedpush
,当我可以拼出整个事情,左脑已经做出了逻辑select。
不一样,但无论如何这个想法是有效的。
#!/bin/bash i='y' while [ ${i:0:1} != n ] do # Command(s) read -p " Again? Y/n " i [[ ${#i} -eq 0 ]] && i='y' done
输出:
再次? Y / n N
再次? 是/是什么
再次? 是/否7
再次? Y / n&
再次? Y / n nsijf
$
现在只检查$ i的第一个字符。
下面的代码是结合了两件事情
-
shopt -s nocasematch将照顾不区分大小写
-
如果既接受input,也接受input的条件是,是,是,y。
shopt -s nocasematch
if [[sed-4.2.2。$ LINE =〜(yes | y)$]]
然后退出0
科幻
这是我的解决scheme,使用本地化的正则expression式。 所以在德语中,“j”的“j”也会被解释为是。
第一个参数是一个问题,如果第二个参数是“y”,那么会是默认答案,否则不会是默认答案。 如果答案是“是”,返回值是0,如果答案是“否”,返回值是1。
function shure(){ if [ $# -gt 1 ] && [[ "$2" =~ ^[yY]*$ ]] ; then arg="[Y/n]" reg=$(locale noexpr) default=(0 1) else arg="[y/N]" reg=$(locale yesexpr) default=(1 0) fi read -p "$1 ${arg}? : " answer [[ "$answer" =~ $reg ]] && return ${default[1]} || return ${default[0]} }
这是一个基本的用法
# basic example default is no shure "question message" && echo "answer yes" || echo "answer no" # print "question message [y/N]? : " # basic example default set to yes shure "question message" y && echo "answer yes" || echo "answer no" # print "question message [Y/n]? : "