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

Are you sure? [Y/n]

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

原因是hgpush和hgout听起来很相似,有时当我想要hgoutrepo时,我可能会意外地键入hgpushrepo(两者都是别名)。

更新:如果可以像内置命令一样使用另一个命令,比如:confirm && hg push ssh://…那太好了……只是一个命令,可以询问“是”或“否”,如果是则继续其余的操作。


当前回答

不需要按enter

这里有一个更长的,但可重用的模块化方法:

返回0=yes和1=no 不需要按enter键-只需一个字符 可以按enter键接受默认选择吗 可以禁用默认选择来强制选择吗 适用于zsh和bash。

按enter键时默认为“no”

注意,N是大写的。此处按下enter键,接受默认值:

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?

还要注意,[y/N]?被自动追加。 默认的“no”被接受,所以什么都不回显。

重新提示,直到给出有效的响应:

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *

按enter键时默认为“yes”

注意,Y是大写的:

$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *

上面,我只是按了回车键,命令就运行了。

输入- require 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

这里返回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=$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
}

其他回答

这可能有点太短了,但对于我自己的私人使用,它工作得很好

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

read -n 1只读取一个字符。不需要按回车键。如果不是“n”或“n”,则假定是“Y”。按回车键也意味着Y。

(至于真正的问题:使它成为一个bash脚本,并更改您的别名指向该脚本,而不是之前所指向的内容)

为了避免显式检查'yes'的这些变体,你可以使用bash正则表达式操作符'=~'和一个正则表达式:

read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt =~ [yY](es)* ]]
then
(etc...)

它测试用户输入是否以“y”或“y”开头,后面是0个或多个“es”。

Try,

 #!/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"

使用回车符可以很容易地绕过确认,并且我发现连续提示有效输入很有用。

这里有一个函数可以简化。如果没有接收到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 " \033[31m %s \n\033[0m" "invalid input"
    esac 
  done  
}

# example usage
prompt_confirm "Overwrite File?" || exit 0

您可以通过传递参数来更改默认提示符

这是我的解决方案,使用本地化正则表达式。所以在德语中,“Ja”的“j”也会被解释为“是”。

第一个参数是问题,如果第二个参数是y,那么yes将是默认答案,否则no将是默认答案。如果答案是“是”,则返回值为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]? : "