シェルスクリプトでの入力を一時停止し、ユーザーに選択を求めます。
標準Yes
、No
またはCancel
タイプの質問。
典型的なbashプロンプトでこれを行うにはどうすればよいですか?
シェルスクリプトでの入力を一時停止し、ユーザーに選択を求めます。
標準Yes
、No
またはCancel
タイプの質問。
典型的なbashプロンプトでこれを行うにはどうすればよいですか?
回答:
シェルプロンプトでユーザー入力を取得する最も簡単で最も広く利用可能な方法は、read
コマンドです。その使用法を説明する最良の方法は簡単なデモです:
while true; do
read -p "Do you wish to install this program?" yn
case $yn in
[Yy]* ) make install; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
Steven Huwigによって指摘された別の方法は、Bashのコマンドです。以下は、同じ例です。select
select
echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
case $yn in
Yes ) make install; break;;
No ) exit;;
esac
done
ではselect
、あなたが入力をサニタイズする必要はありません-それは、利用可能な選択肢が表示され、あなたはあなたの選択に対応する番号を入力します。また、自動的にループするため、while true
無効な入力があった場合にループを再試行する必要はありません。
また、レアグリスは、彼女の回答で要求言語にとらわれない方法を示しました。私の最初の例を、複数の言語に対応するように変更すると、次のようになります。
set -- $(locale LC_MESSAGES)
yesptrn="$1"; noptrn="$2"; yesword="$3"; noword="$4"
while true; do
read -p "Install (${yesword} / ${noword})? " yn
case $yn in
${yesptrn##^} ) make install; break;;
${noptrn##^} ) exit;;
* ) echo "Answer ${yesword} / ${noword}.";;
esac
done
明らかに、他の通信文字列は未翻訳のままです(Install、Answer)。これはより完全な翻訳で対処する必要がありますが、部分的な翻訳でも多くの場合に役立ちます。
exit
しbreak
ました。
break
ではselect
何のループが存在しない場合は?
応じて
そしてあなたが望むなら
read
次のコマンドを続けて使用できますif ... then ... else
。
echo -n "Is this a good question (y/n)? "
read answer
# if echo "$answer" | grep -iq "^y" ;then
if [ "$answer" != "${answer#[Yy]}" ] ;then
echo Yes
else
echo No
fi
(Adam Katzのコメントのおかげで:上記のテストをより移植性が高く、1つのフォークを回避するテストに置き換えました:)
しかし、ユーザーにを押したくない場合はReturn、次のように書くことができます。
(編集: @JonathanLefflerが正しく示唆しているように、sttyの構成を保存することは、単にそれらを正気にさせるよりも良いかもしれません。)
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo ; answer=$(head -c 1) ; stty $old_stty_cfg # Careful playing with stty
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
fi
注:これは以下でテストされましたsh、 バッシュ、 ksh、 ダッシュ そして busybox!
同じですが、yまたはを明示的に待っていnます:
#/bin/sh
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo
answer=$( while ! head -c 1 | grep -i '[ny]' ;do true ;done )
stty $old_stty_cfg
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
fi
使用して構築された多くのツールがありlibncurses
、libgtk
、libqt
または他のグラフィックライブラリが。たとえば、次のように使用しwhiptail
ます。
if whiptail --yesno "Is this a good question" 20 60 ;then
echo Yes
else
echo No
fi
システムによっては、whiptail
別の同様のツールに置き換える必要がある場合があります。
dialog --yesno "Is this a good question" 20 60 && echo Yes
gdialog --yesno "Is this a good question" 20 60 && echo Yes
kdialog --yesno "Is this a good question" 20 60 && echo Yes
ここで、20
はダイアログボックスの高さ(行数)および60
はダイアログボックスの幅です。これらのツールはすべてほぼ同じ構文を持っています。
DIALOG=whiptail
if [ -x /usr/bin/gdialog ] ;then DIALOG=gdialog ; fi
if [ -x /usr/bin/xdialog ] ;then DIALOG=xdialog ; fi
...
$DIALOG --yesno ...
read -p "Is this a good question (y/n)? " answer
case ${answer:0:1} in
y|Y )
echo Yes
;;
* )
echo No
;;
esac
私は使用したいcase
のでyes | ja | si | oui
、必要に応じてテストすることもできます...
bashの下では、read
コマンドの対象となる入力の長さを指定できます。
read -n 1 -p "Is this a good question (y/n)? " answer
bashでは、read
コマンドはタイムアウトパラメータを受け入れます。これは便利な場合があります。
read -t 3 -n 1 -p "Is this a good question (y/n)? " answer
[ -z "$answer" ] && answer="Yes" # if 'yes' have to be default choice
単純なyes - no
目的を超えた、より洗練されたダイアログボックス:
dialog --menu "Is this a good question" 20 60 12 y Yes n No m Maybe
プログレスバー:
dialog --gauge "Filling the tank" 20 60 0 < <(
for i in {1..100};do
printf "XXX\n%d\n%(%a %b %T)T progress: %d\nXXX\n" $i -1 $i
sleep .033
done
)
小さなデモ:
#!/bin/sh
while true ;do
[ -x "$(which ${DIALOG%% *})" ] || DIALOG=dialog
DIALOG=$($DIALOG --menu "Which tool for next run?" 20 60 12 2>&1 \
whiptail "dialog boxes from shell scripts" >/dev/tty \
dialog "dialog boxes from shell with ncurses" \
gdialog "dialog boxes from shell with Gtk" \
kdialog "dialog boxes from shell with Kde" ) || exit
clear;echo "Choosed: $DIALOG."
for i in `seq 1 100`;do
date +"`printf "XXX\n%d\n%%a %%b %%T progress: %d\nXXX\n" $i $i`"
sleep .0125
done | $DIALOG --gauge "Filling the tank" 20 60 0
$DIALOG --infobox "This is a simple info box\n\nNo action required" 20 60
sleep 3
if $DIALOG --yesno "Do you like this demo?" 20 60 ;then
AnsYesNo=Yes; else AnsYesNo=No; fi
AnsInput=$($DIALOG --inputbox "A text:" 20 60 "Text here..." 2>&1 >/dev/tty)
AnsPass=$($DIALOG --passwordbox "A secret:" 20 60 "First..." 2>&1 >/dev/tty)
$DIALOG --textbox /etc/motd 20 60
AnsCkLst=$($DIALOG --checklist "Check some..." 20 60 12 \
Correct "This demo is useful" off \
Fun "This demo is nice" off \
Strong "This demo is complex" on 2>&1 >/dev/tty)
AnsRadio=$($DIALOG --radiolist "I will:" 20 60 12 \
" -1" "Downgrade this answer" off \
" 0" "Not do anything" on \
" +1" "Upgrade this anser" off 2>&1 >/dev/tty)
out="Your answers:\nLike: $AnsYesNo\nInput: $AnsInput\nSecret: $AnsPass"
$DIALOG --msgbox "$out\nAttribs: $AnsCkLst\nNote: $AnsRadio" 20 60
done
もっとサンプル?見ていたUSBデバイスの選択のためです:whiptailを使用し、USBリムーバブル記憶域セレクタを:USBKeyChooser
例:
#!/bin/bash
set -i
HISTFILE=~/.myscript.history
history -c
history -r
myread() {
read -e -p '> ' $1
history -s ${!1}
}
trap 'history -a;exit' 0 1 2 3 6
while myread line;do
case ${line%% *} in
exit ) break ;;
* ) echo "Doing something with '$line'" ;;
esac
done
これは、ファイルが作成され.myscript.history
、あなたに$HOME
あなたのような、readlineの歴史コマンドを使用することができますよりも、ディレクトリUp、 Down、Ctrl+ rなどがあります。
stty
は、-g
使用するためのオプションが用意されていますold_stty=$(stty -g); stty raw -echo; …; stty "$old_stty"
。これにより、設定が見つかったとおりに復元されstty -sane
ます。これは、と同じ場合も同じでない場合もあります。
case
bashと同様にPOSIXにも使用できます(bash部分文字列ではなくワイルドカード条件を使用しますcase $answer in; [Yy]* ) echo Yes ;;
)が、代わりに条件ステートメントを使用すること[ "$answer" != "${answer#[Yy]}" ]
をお勧めしますecho "$answer" | grep -iq ^y
。移植性が高く(GNU以外の一部のgrepは-q
正しく実装されない)、システムコールがありません。 ${answer#[Yy]}
パラメータ展開を使用してを削除するY
かy
、の最初から、$answer
どちらかが存在する場合に不等式を引き起こします これは、どのPOSIXシェル(ダッシュ、ksh、bash、zsh、busyboxなど)でも機能します。
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"
組み込みの読み取りコマンドを使用できます。-p
オプションを使用して、ユーザーに質問を促します。
BASH4以降、これを使用-i
して回答を提案できます。
read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
echo $FILEPATH
(ただし、「readline」オプション-e
を使用して、矢印キーで行を編集できるようにしてください)
「はい/いいえ」のロジックが必要な場合は、次のようなことができます。
read -e -p "
List the content of your home dir ? [Y/n] " YN
[[ $YN == "y" || $YN == "Y" || $YN == "" ]] && ls -la ~/
FILEPATH
は、選択した変数名であり、コマンドプロンプトへの回答で設定されることに注意してください。したがってvlc "$FILEPATH"
、たとえばを実行すると、vlc
そのファイルが開かれます。
-e
2番目の例(単純なはい/いいえ)の利点は何ですか?
-e -p
代わりに使用する理由はあり-ep
ますか?
-e
フラグ/オプション、あなたは(実装に依存)かもしれない「Y」を入力し、[あなたの心を変更し、「N」(またはそのことについて何か)と交換することができます。コマンドを文書化するとき、オプションを個別にリストすることは、数ある理由の中でも特に、読みやすさ/明確さのために優れています。
exit
内部を追加するまで:)
Ctrl-D
。しかし、もちろん、それを使用する実際のコードでは、本文に区切りまたは出口が必要です。)
exit
スクリプトをすべてbreak
終了し、現在のループのみを終了します(a while
またはcase
ループの場合)
これが私がまとめたものです:
#!/bin/sh
promptyn () {
while true; do
read -p "$1 " yn
case $yn in
[Yy]* ) return 0;;
[Nn]* ) return 1;;
* ) echo "Please answer yes or no.";;
esac
done
}
if promptyn "is the sky blue?"; then
echo "yes"
else
echo "no"
fi
私は初心者なので、これを塩の粒と一緒に服用しますが、うまくいくようです。
case $yn in
しcase ${yn:-$2} in
、あなたはデフォルト値として第二引数を使用することができ、YまたはN.
case $yn
にcase "${yn:-Y}"
デフォルトとしてyesを持っている
inquire () {
echo -n "$1 [y/n]? "
read answer
finish="-1"
while [ "$finish" = '-1' ]
do
finish="1"
if [ "$answer" = '' ];
then
answer=""
else
case $answer in
y | Y | yes | YES ) answer="y";;
n | N | no | NO ) answer="n";;
*) finish="-1";
echo -n 'Invalid response -- please reenter:';
read answer;;
esac
fi
done
}
... other stuff
inquire "Install now?"
...
do_xxxx=y # In batch mode => Default is Yes
[[ -t 0 ]] && # If TTY => Prompt the question
read -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx # Store the answer in $do_xxxx
if [[ $do_xxxx =~ ^(y|Y|)$ ]] # Do if 'y' or 'Y' or empty
then
xxxx
fi
[[ -t 0 ]] && read ...
=> read
TTYの場合にコマンドを呼び出すread -n 1
=> 1文字待つ$'\e[1;32m ... \e[0m '
=>緑で印刷[[ $do_xxxx =~ ^(y|Y|)$ ]]
=> bash正規表現do_xxxx=y
[[ -t 0 ]] && { # Timeout 5 seconds (read -t 5)
read -t 5 -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx || # read 'fails' on timeout
do_xxxx=n ; } # Timeout => answer No
if [[ $do_xxxx =~ ^(y|Y|)$ ]]
then
xxxx
fi
最小限の行数でこれを実現する最も簡単な方法は、次のとおりです。
read -p "<Your Friendly Message here> : y/n/cancel" CONDITION;
if [ "$CONDITION" == "y" ]; then
# do something here!
fi
これif
は一例にすぎません。この変数の処理方法はユーザー次第です。
次のread
コマンドを使用します。
echo Would you like to install? "(Y or N)"
read x
# now check if $x is "y"
if [ "$x" = "y" ]; then
# do something here!
fi
そして、あなたが必要とする他のすべてのもの
ncursesのような素敵な入力ボックスを取得するには、次のようなコマンドダイアログを使用します。
#!/bin/bash
if (dialog --title "Message" --yesno "Want to do something risky?" 6 25)
# message box will have the size 25x6 characters
then
echo "Let's do something risky"
# do something risky
else
echo "Let's stay boring"
fi
POSIXシェルでロケール対応の「はい/いいえ選択」を処理することは可能です。LC_MESSAGES
witchは、ロケールカテゴリのエントリを使用して、入力に一致する既製のRegExパターンと、ローカライズされたはいいいえの文字列を提供します。
#!/usr/bin/env sh
# Getting LC_MESSAGES values into variables
# shellcheck disable=SC2046 # Intended IFS splitting
IFS='
' set -- $(locale LC_MESSAGES)
yesexpr="$1"
noexpr="$2"
yesstr="$3"
nostr="$4"
messages_codeset="$5" # unused here, but kept as documentation
# Display Yes / No ? prompt into locale
echo "$yesstr / $nostr ?"
# Read answer
read -r yn
# Test answer
case "$yn" in
# match only work with the character class from the expression
${yesexpr##^}) echo "answer $yesstr" ;;
${noexpr##^}) echo "answer $nostr" ;;
esac
編集:@Urhixidurが彼のコメントで述べたように:
残念ながら、POSIXは最初の2つ(yesexprとnoexpr)のみを指定しています。Ubuntu 16では、yesstrとnostrは空です。
参照:https : //www.ee.ryerson.ca/~courses/ele709/susv4/xrat/V4_xbd_chap07.html#tag_21_07_03_06
LC_MESSAGES
ロケールキーワードとし、LANGINFO項目は、以前のユーザー肯定と否定の応答を一致させるために使用されました。POSIX.1-2008では、、、、および拡張正規表現は、それらを交換しました。アプリケーションは、一般的なロケールベースのメッセージング機能を使用して、サンプルの必要な応答を含むプロンプトメッセージを発行する必要があります。
yesstr
nostr
YESSTR
NOSTR
yesexpr
noexpr
YESEXPR
NOEXPR
別の方法として、Bashの方法でロケールを使用します。
#!/usr/bin/env bash
IFS=$'\n' read -r -d '' yesexpr noexpr _ < <(locale LC_MESSAGES)
printf -v yes_or_no_regex "(%s)|(%s)" "$yesexpr" "$noexpr"
printf -v prompt $"Please answer Yes (%s) or No (%s): " "$yesexpr" "$noexpr"
declare -- answer=;
until [[ "$answer" =~ $yes_or_no_regex ]]; do
read -rp "$prompt" answer
done
if [[ -n "${BASH_REMATCH[1]}" ]]; then
echo $"You answered: Yes"
else
echo $"No, was your answer."
fi
答えは、ロケール環境が提供する正規表現を使用して照合されます。
残りのメッセージを翻訳するには、を使用bash --dump-po-strings scriptname
してローカライズ用のpo文字列を出力します。
#: scriptname:8
msgid "Please answer Yes (%s) or No (%s): "
msgstr ""
#: scriptname:17
msgid "You answered: Yes"
msgstr ""
#: scriptname:19
msgid "No, was your answer."
msgstr ""
yesexpr
とnoexpr
シェル環境では、バッシュの特定の正規表現のマッチングで使用されるif [[ "$yn" =~ $yesexpr ]]; then echo $"Answered yes"; else echo $"Answered no"; fi
これは、より長く、再利用可能なモジュール式のアプローチです。
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 [y/n]? "
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
}
Show dangerous command [y/N]? [y/n]?
とShow dangerous command [Y/n]? [y/n]?
そのような古い投稿に投稿して申し訳ありません。数週間前、私は同様の問題に直面していました。私の場合、オンラインインストーラースクリプト内でも機能するソリューションが必要でした。例:curl -Ss https://raw.github.com/_____/installer.sh | bash
使用read yesno < /dev/tty
するとうまくいきます:
echo -n "These files will be uploaded. Is this ok? (y/n) "
read yesno < /dev/tty
if [ "x$yesno" = "xy" ];then
# Yes
else
# No
fi
これが誰かを助けることを願っています。
tty
あなたはあなたのためにも行われ、また、不正な入力にループし得ただろうでしたように、入力を(バッファ内の数文字を想像;にあなたの方法は、ユーザーを強制しないだろう、常に何を選択します)。
そのような単純なユーザー入力に対して複数行のエコーメニューを表示する回答を誰も投稿していないことに気付いたので、ここで私の取り組みを説明します。
#!/bin/bash
function ask_user() {
echo -e "
#~~~~~~~~~~~~#
| 1.) Yes |
| 2.) No |
| 3.) Quit |
#~~~~~~~~~~~~#\n"
read -e -p "Select 1: " choice
if [ "$choice" == "1" ]; then
do_something
elif [ "$choice" == "2" ]; then
do_something_else
elif [ "$choice" == "3" ]; then
clear && exit 0
else
echo "Please select 1, 2, or 3." && sleep 3
clear && ask_user
fi
}
ask_user
この方法は、誰かが便利で時間を節約できることを期待して投稿されました。
複数選択バージョン:
ask () { # $1=question $2=options
# set REPLY
# options: x=..|y=..
while $(true); do
printf '%s [%s] ' "$1" "$2"
stty cbreak
REPLY=$(dd if=/dev/tty bs=1 count=1 2> /dev/null)
stty -cbreak
test "$REPLY" != "$(printf '\n')" && printf '\n'
(
IFS='|'
for o in $2; do
if [ "$REPLY" = "${o%%=*}" ]; then
printf '\n'
break
fi
done
) | grep ^ > /dev/null && return
done
}
例:
$ ask 'continue?' 'y=yes|n=no|m=maybe'
continue? [y=yes|n=no|m=maybe] g
continue? [y=yes|n=no|m=maybe] k
continue? [y=yes|n=no|m=maybe] y
$
(スクリプト内で)に設定さREPLY
れy
ます。
Linux見習い:ダイアログを使用してBashシェルスクリプトを改善する
ダイアログコマンドを使用すると、シェルスクリプトでウィンドウボックスを使用して、よりインタラクティブに使用できます。
シンプルで使いやすいです。gdialogと呼ばれるgnomeバージョンもあり、まったく同じパラメーターを使用しますが、XでGUIスタイルを示します。
@Markおよび@Myrddinの回答に触発されて、私はこの関数をユニバーサルプロンプト用に作成しました
uniprompt(){
while true; do
echo -e "$1\c"
read opt
array=($2)
case "${array[@]}" in *"$opt"*) eval "$3=$opt";return 0;; esac
echo -e "$opt is not a correct value\n"
done
}
次のように使用します。
unipromtp "Select an option: (a)-Do one (x)->Do two (f)->Do three : " "a x f" selection
echo "$selection"
より一般的なものは:
function menu(){
title="Question time"
prompt="Select:"
options=("Yes" "No" "Maybe")
echo "$title"
PS3="$prompt"
select opt in "${options[@]}" "Quit/Cancel"; do
case "$REPLY" in
1 ) echo "You picked $opt which is option $REPLY";;
2 ) echo "You picked $opt which is option $REPLY";;
3 ) echo "You picked $opt which is option $REPLY";;
$(( ${#options[@]}+1 )) ) clear; echo "Goodbye!"; exit;;
*) echo "Invalid option. Try another one.";continue;;
esac
done
return
}
これを行う簡単な方法の1つは、xargs -p
or gnuを使用することparallel --interactive
です。
最後に実行するyessesを収集するのではなく、他の対話型のunixコマンドのようにプロンプトの直後に各コマンドを実行するため、xargsの動作は少し良くなっています。(必要なものを通過した後、Ctrl-Cを押すことができます。)
例えば、
echo *.xml | xargs -p -n 1 -J {} mv {} backup/
xargs --interactive
はいまたはいいえに限定されます。それで十分であれば十分ですが、私の最初の質問では、3つの結果が考えられる例を示しました。私はそれがストリーミング可能であることを本当に気に入っています。多くの一般的なシナリオは、パイプで接続する機能の恩恵を受けます。
1行のコマンドの友として、次のコマンドを使用しました。
while [ -z $prompt ]; do read -p "Continue (y/n)?" choice;case "$choice" in y|Y ) prompt=true; break;; n|N ) exit 0;; esac; done; prompt=;
長い形式で書かれ、次のように機能します。
while [ -z $prompt ];
do read -p "Continue (y/n)?" choice;
case "$choice" in
y|Y ) prompt=true; break;;
n|N ) exit 0;;
esac;
done;
prompt=;
私はcase
そのようなシナリオでステートメントを数回使用しました。ケースステートメントを使用することは、それを実行するための良い方法です。while
ecapsulatesループ、case
ブール条件を利用するブロックは、プログラムの一層の制御を保持し、および他の多くの要件を満たすために実装することができます。すべての条件が満たされた後、break
制御をプログラムのメイン部分に戻すを使用できます。また、他の条件を満たすために、当然のことながら、条件付きステートメントを追加して、制御構造(case
ステートメントと可能なwhile
ループ)に含めることができます。
case
ステートメントを使用してリクエストを満たす例
#! /bin/sh
# For potential users of BSD, or other systems who do not
# have a bash binary located in /bin the script will be directed to
# a bourne-shell, e.g. /bin/sh
# NOTE: It would seem best for handling user entry errors or
# exceptions, to put the decision required by the input
# of the prompt in a case statement (case control structure),
echo Would you like us to perform the option: "(Y|N)"
read inPut
case $inPut in
# echoing a command encapsulated by
# backticks (``) executes the command
"Y") echo `Do something crazy`
;;
# depending on the scenario, execute the other option
# or leave as default
"N") echo `execute another option`
;;
esac
exit
#!/usr/bin/env bash
@confirm() {
local message="$*"
local result=''
echo -n "> $message (Yes/No/Cancel) " >&2
while [ -z "$result" ] ; do
read -s -n 1 choice
case "$choice" in
y|Y ) result='Y' ;;
n|N ) result='N' ;;
c|C ) result='C' ;;
esac
done
echo $result
}
case $(@confirm 'Confirm?') in
Y ) echo "Yes" ;;
N ) echo "No" ;;
C ) echo "Cancel" ;;
esac
#!/usr/bin/env bash
@confirm() {
local message="$*"
local result=3
echo -n "> $message (y/n) " >&2
while [[ $result -gt 1 ]] ; do
read -s -n 1 choice
case "$choice" in
y|Y ) result=0 ;;
n|N ) result=1 ;;
esac
done
return $result
}
if @confirm 'Confirm?' ; then
echo "Yes"
else
echo "No"
fi
他者への対応:
BASH4で大文字と小文字を指定する必要はありません。varを小文字にするために ',,'を使用するだけです。また、私はコードを読み取りブロック内に配置して結果を取得し、読み取りブロックIMOの外部で処理することを強く嫌っています。また、IMOを終了するには「q」を含めます。最後に、「yes」と入力する理由は、-n1を使用してyを押すだけです。
例:ユーザーはy / nとqを押すだけで終了できます。
ans=''
while true; do
read -p "So is MikeQ the greatest or what (y/n/q) ?" -n1 ans
case ${ans,,} in
y|n|q) break;;
*) echo "Answer y for yes / n for no or q for quit.";;
esac
done
echo -e "\nAnswer = $ans"
if [[ "${ans,,}" == "q" ]] ; then
echo "OK Quitting, we will assume that he is"
exit 0
fi
if [[ "${ans,,}" == "y" ]] ; then
echo "MikeQ is the greatest!!"
else
echo "No? MikeQ is not the greatest?"
fi
[yn]
オプションを提示すると、大文字で始まるものがデフォルトに[Yn]
なります。つまり、デフォルトは「yes」になり、[yN]
デフォルトは「no」になります。ux.stackexchange.com/a/40445/43532を