在Bash中,如何给任何命令或别名添加“你确定”?

在这个特殊情况下,我想在Bash中添加一个确认

你确定?  [Y / N]

对于Mercurial的hg push ssh://username@www.example.com//somepath/morepath ,这实际上是一个别名。 有没有一个标准的命令可以添加到别名来实现它?

原因是hg pushhg out听起来可能相似,有时当我想要hgoutrepo ,我可能会偶然地inputhgpushrepo (都是别名)。

更新:如果它可以像一个内置的命令与另一个命令,如: confirm && hg push ssh://...那将是伟大的…只是一个命令,可以要求yesno如果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 -enbash但可能在你的shell中失败
  • 如果参数干扰echoxargs可能会失败
  • 还有其他的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 } 

这些变化是:

  1. 使用local来防止variables名称冲突
  2. read使用$2 $3 ...来控制它的行为,所以你可以使用-n-t
  3. 如果read不成功,则echo一个换行以获得美观
  4. Git on Windows只有bash-3.1并且没有truefalse ,所以使用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的第一个字符。

下面的代码是结合了两件事情

  1. shopt -s nocasematch将照顾不区分大小写

  2. 如果既接受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]? : "