web-dev-qa-db-ja.com

Bashで、「Are you sure [Y / n]」をコマンドまたはエイリアスに追加する方法は?

この特定のケースでは、確認のためにBashに追加したいと思います

本気ですか? [Y/n] 

mercurialのhg Push ssh://[email protected]//somepath/morepathの場合、これは実際にはエイリアスです。それを達成するためにエイリアスに追加できる標準コマンドはありますか?

理由は、hg Pushhg outが似たように聞こえ、時々hgoutrepoが必要なときに、誤ってhgpushrepoと入力することがあるためです(両方ともエイリアスです)。

更新:別のコマンドを備えた組み込みコマンドのようなものである可能性がある場合:confirm && hg Push ssh://...それは素晴らしいでしょう...ただyesまたはnoを要求して続行できるコマンドyesの場合は残り。

199

これらは、よりコンパクトで汎用性の高い形式の Hamish'sanswer です。大文字と小文字の混合を処理します:

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が空の文字列の場合、エラーが発生します。修正するには、引用符を追加します:"$response"。 –文字列を含む変数では常に二重引用符を使用します(例:"$@"ではなく$@を使用することをお勧めします)。

または、Bash 4.x:

read -r -p "Are you sure? [y/N] " response
response=${response,,}    # tolower
if [[ "$response" =~ ^(yes|y)$ ]]
...

編集:

編集に応じて、私の回答の最初のバージョンに基づいてconfirmコマンドを作成して使用する方法を次に示します(他の2つでも同様に機能します)。

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
}

この機能を使用するには:

confirm && hg Push ssh://..

または

confirm "Would you really like to do a push?" && hg Push ssh://..
292

おおよそ次のスニペットが必要です。引数を転送する方法を見つけましょう。

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に注意してください:)

19
Hamish Grubijan

これらの「yes」のバリアントを明示的にチェックしないようにするには、bash正規表現演算子「=〜」を正規表現で使用できます。

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

ユーザー入力が「y」または「Y」で始まり、その後にゼロ個以上の「es」が続くかどうかをテストします。

11
user389850

確認はキャリッジリターンで簡単にバイパスされ、有効な入力のプロンプトを継続的に表示すると便利です。

これを簡単にする関数を次に示します。 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

引数を渡すことでデフォルトのプロンプトを変更できます

10
briceburg

これはハックかもしれません:

nix/Bashでは、「xargs -p」はコマンドを実行する前に確認を求める良い方法ですか?

xargsを使用してジョブを実行できます。

echo ssh://[email protected]//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
3
SergioAraujo

以下を/ etc/bashrcファイルに追加します。このスクリプトは、「confirm」と呼ばれるエイリアスの代わりに常駐の「関数」を追加します。


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
}
3
MattyV

さて、ここに、Jamesのものから変更されたconfirmの私のバージョンがあります:

function confirm() {
  local response 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を使用して、変数名が衝突しないようにします
  2. read$2 $3 ...を使用してアクションを制御するため、-nおよび-tを使用できます
  3. readが正常に終了しない場合、echoは美容のための改行
  4. Git on Windowsにはbash-3.1のみがあり、trueまたはfalseがないため、代わりにreturnを使用します。もちろん、これはbash-4.4(Git for Windowsの現在のもの)との互換性もあります。
  5. iPythonスタイルの「(y/[n])」を使用して、「n」がデフォルトであることを明確に示します。
2
Dahan Gong

ゲームに遅れましたが、以前の回答の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で動作しますが、シェルで失敗する可能性があります
  • 引数がechoまたはxargsに干渉すると失敗する可能性があります
  • シェルスクリプトの作成は難しいため、他にも膨大なバグ
1
thomas.me

試して、

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

Enterキーを押す必要はありません

より長いが、再利用可能なモジュール式のアプローチは次のとおりです。

  • 0 = yesおよび1 = noを返します
  • Enterキーを押す必要はありません-1文字だけです
  • 押すことができます enter デフォルトの選択を受け入れる
  • デフォルトの選択を無効にして選択を強制できます
  • zshbashの両方で機能します。

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 *

上記では、Enterキーを押したので、コマンドが実行されました。

デフォルトなし 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

ここでは、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
}
1
Tom Hale

これは少し短すぎるかもしれませんが、私自身の個人的な使用のために、それは素晴らしい作品

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は1文字だけを読み取ります。 Enterキーを押す必要はありません。 「n」または「N」ではない場合、「Y」と見なされます。 Enterキーを押すだけでもYを意味します。

(実際の質問に関しては、bashスクリプトを作成し、以前に指していたものではなく、そのスクリプトを指すようにエイリアスを変更します)

1
commonpike

これは、ローカライズされた正規表現を使用する私のソリューションです。したがって、ドイツ語でも「Ja」の「j」は「はい」と解釈されます。

最初の引数は質問です。2番目の引数が「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]? : "
0
David Boho

以下のコードは2つのことを組み合わせています

  1. 大文字と小文字を区別しないshopt -s nocasematch

  2. そして、両方の入力を受け入れる条件の場合、yes、Yes、YES、yのいずれかを渡します。

    shopt -s nocasematch

    if [[sed-4.2.2。$ LINE =〜(yes | y)$]]

    その後、終了0

    fi

0
Shyam Gupta

これは正確に「はいまたはいいえを要求する」のではなく、単なるハックです。hg Push ...hgpushrepoではなくhgpushrepoconfirmedpushにエイリアスします。

同じではありませんが、とにかく動作するアイデア。

#!/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
再び? Y/n何でも
再び? Y/n 7
再び? Y/n&
再び? Y/n nsijf
$

現在、$ i readの最初の文字のみをチェックします。

0
anonimous