この特定のケースでは、確認のためにBashに追加したいと思います
本気ですか? [Y/n]
mercurialのhg Push ssh://[email protected]//somepath/morepath
の場合、これは実際にはエイリアスです。それを達成するためにエイリアスに追加できる標準コマンドはありますか?
理由は、hg Push
とhg out
が似たように聞こえ、時々hgoutrepo
が必要なときに、誤ってhgpushrepo
と入力することがあるためです(両方ともエイリアスです)。
更新:別のコマンドを備えた組み込みコマンドのようなものである可能性がある場合:confirm && hg Push ssh://...
それは素晴らしいでしょう...ただyes
またはno
を要求して続行できるコマンドyes
の場合は残り。
これらは、よりコンパクトで汎用性の高い形式の 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://..
おおよそ次のスニペットが必要です。引数を転送する方法を見つけましょう。
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」のバリアントを明示的にチェックしないようにするには、bash正規表現演算子「=〜」を正規表現で使用できます。
read -p "Are you sure you want to continue? <y/N> " Prompt
if [[ $Prompt =~ [yY](es)* ]]
then
(etc...)
ユーザー入力が「y」または「Y」で始まり、その後にゼロ個以上の「es」が続くかどうかをテストします。
確認はキャリッジリターンで簡単にバイパスされ、有効な入力のプロンプトを継続的に表示すると便利です。
これを簡単にする関数を次に示します。 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
引数を渡すことでデフォルトのプロンプトを変更できます
これはハックかもしれません:
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
以下を/ 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
}
さて、ここに、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
}
これらの変更は次のとおりです。
local
を使用して、変数名が衝突しないようにしますread
は$2 $3 ...
を使用してアクションを制御するため、-n
および-t
を使用できますread
が正常に終了しない場合、echo
は美容のための改行Git on Windows
にはbash-3.1
のみがあり、true
またはfalse
がないため、代わりにreturn
を使用します。もちろん、これはbash-4.4(Git for Windowsの現在のもの)との互換性もあります。ゲームに遅れましたが、以前の回答の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
特徴:
バグ:
echo -en
はbash
で動作しますが、シェルで失敗する可能性がありますecho
またはxargs
に干渉すると失敗する可能性があります試して、
#!/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"
より長いが、再利用可能なモジュール式のアプローチは次のとおりです。
0
= yesおよび1
= noを返しますzsh
とbash
の両方で機能します。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 *
Y
は大文字であることに注意してください。
$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *
上記では、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
}
これは少し短すぎるかもしれませんが、私自身の個人的な使用のために、それは素晴らしい作品
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スクリプトを作成し、以前に指していたものではなく、そのスクリプトを指すようにエイリアスを変更します)
これは、ローカライズされた正規表現を使用する私のソリューションです。したがって、ドイツ語でも「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]? : "
以下のコードは2つのことを組み合わせています
大文字と小文字を区別しないshopt -s nocasematch
そして、両方の入力を受け入れる条件の場合、yes、Yes、YES、yのいずれかを渡します。
shopt -s nocasematch
if [[sed-4.2.2。$ LINE =〜(yes | y)$]]
その後、終了0
fi
これは正確に「はいまたはいいえを要求する」のではなく、単なるハックです。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の最初の文字のみをチェックします。