it-swarm.asia

كيف يمكنني مطالبة نعم/لا/إلغاء الإدخال في برنامج نصي Linux Linux؟

أرغب في إيقاف الإدخال مؤقتًا في برنامج شل ، ومطالبة المستخدم بالاختيارات. السؤال القياسي "نعم أو لا أو إلغاء". كيف يمكنني تحقيق ذلك في موجه bash نموذجي؟

1257
Myrddin Emrys

الطريقة الأبسط والأكثر إتاحة على نطاق واسع للحصول على مدخلات المستخدم في Shell Prompt هي 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

هناك طريقة أخرى ، أشار إليها ستيفن هويج ، وهي/Bash's select command. هنا هو نفس المثال باستخدام 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 إذا أعطوا إدخالًا غير صالح.

أيضا ، يرجى التحقق من إجابة ممتازة من قبل F. Hauri.

1414
Myrddin Emrys

خمس إجابات على الأقل لسؤال عام واحد.

اعتمادا علي

  • posix متوافق: يمكن أن تعمل على الأنظمة السيئة ذات البيئات العامة Shell
  • bash محددة: باستخدام ما يسمى bashisms

وايضا لو اردت

  • سؤال/إجابة بسيطة (في السطر) (حلول عامة)
  • واجهات منسقة جداً ، مثل ncurses أو رسومية أكثر باستخدام libgtk أو libqt ...
  • استخدام قدرة قوية تاريخ readline

1. حلول POSIX العامة

يمكنك استخدام الأمر 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

(بفضل تعليق آدم كاتز : استبدل الاختبار أعلاه بأكثر قابلية للنقل وتجنب شوكة واحدة :)

POSIX ، ولكن ميزة مفتاح واحد

ولكن إذا كنت لا تريد أن يضطر المستخدم إلى الدخول 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 ، bash ، 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 ...

2. باش حلول محددة

الأساسية في السطر الطريقة

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

أكثر عينة؟ إلقاء نظرة على باستخدام whiptail لاختيار جهاز USB و محدد تخزين USB قابل للإزالة: USBKeyChooser

5. استخدام تاريخ readline

مثال:

#!/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 و اخرين.

450
F. Hauri
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"
340
Pistos

يمكنك استخدام المدمج في قراءة القيادة ؛ استخدم خيار -p لمطالبة المستخدم بسؤال.

منذ BASH4 ، يمكنك الآن استخدام -i لاقتراح إجابة ، لذلك يتعين على المستخدم فقط الضغط على return لإدخالها:

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 ~/
151
yPhil

باش لديه حدد لهذا الغرض.

select result in Yes No Cancel
do
    echo $result
done
101
Steven Huwig
read -p "Are you alright? (y/n) " RESP
if [ "$RESP" = "y" ]; then
  echo "Glad to hear it"
else
  echo "You need more bash programming"
fi
54
serg

إليكم شيئًا وضعته معًا:

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

أنا مبتدئ ، لذلك خذ هذا مع حبة الملح ، ولكن يبدو أن العمل.

31
mpen
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?"

...
28
SumoRunner

انت تريد:

  • أوامر Bash المضمنة (أي المحمولة)
  • تحقق TTY
  • الجواب الافتراضي
  • نفذ الوقت
  • سؤال ملون

قصاصة

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 => انتظر شخصية واحدة
  • $'\e[1;32m ... \e[0m ' => الطباعة باللون الأخضر
    (اللون الأخضر جيد لأنه قابل للقراءة على كل من الخلفيات البيضاء/السوداء)
  • [[ $do_xxxx =~ ^(y|Y|)$ ]] => bash regex

المهلة => الإجابة الافتراضية هي لا

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
25
olibre

أسهل طريقة لتحقيق ذلك بأقل عدد من الخطوط هي كما يلي:

read -p "<Your Friendly Message here> : y/n/cancel" CONDITION;

if [ "$CONDITION" == "y" ]; then
   # do something here!
fi

if هو مجرد مثال: الأمر متروك لك كيفية التعامل مع هذا المتغير.

21
Apurv Nerlekar

استخدم الأمر 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

ثم كل الأشياء الأخرى التي تحتاجها

17
ThatLinuxGuy

يقرأ هذا الحل حرفًا واحدًا ويستدعي دالة على استجابة yes.

read -p "Are you sure? (y/n) " -n 1
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    do_something      
fi
17
Dennis
read -e -p "Enter your choice: " choice

يتيح خيار -e للمستخدم تحرير الإدخال باستخدام مفاتيح الأسهم.

إذا كنت تريد استخدام اقتراح كمدخلات:

read -e -i "yes" -p "Enter your choice: " choice

يطبع خيار -i مدخلات موحية.

12
Jahid

آسف للنشر على مثل هذا المنصب القديم. منذ بضعة أسابيع كنت أواجه مشكلة مماثلة ، في حالتي كنت بحاجة إلى حل يعمل أيضًا ضمن برنامج نصي عبر الإنترنت ، على سبيل المثال: 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

أمل أن هذا يساعد شخصاما.

9
xyz

للحصول على صندوق إدخال لطيف يشبه 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

يتم تثبيت حزمة الحوار بشكل افتراضي على الأقل مع SUSE Linux.

8
Thorsten Staerk

بضغطة واحدة فقط

إليك مقاربة أطول ولكن قابلة لإعادة الاستخدام وموحدة:

  • إرجاع 0 = نعم و 1 = لا
  • لا يلزم إدخال الضغط - مجرد حرف واحد
  • يمكن الضغط enter لقبول الخيار الافتراضي
  • يمكن تعطيل الخيار الافتراضي لفرض التحديد
  • يعمل لكل من zsh و bash.

التخلف عن "لا" عند الضغط على إدخال

لاحظ أن الأحرف الكبيرة N. هنا أدخل الضغط ، وقبول الافتراضي:

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

لاحظ أيضًا أن [y/N]? تم إلحاقه تلقائيًا. يتم قبول "لا" الافتراضي ، لذلك لا يتم تكرار أي شيء.

أعد المطالبة حتى يتم إعطاء استجابة صالحة:

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

التخلف عن "نعم" عند الضغط على enter

لاحظ أن الأحرف الكبيرة 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
}
6
Tom Hale

يمكنك استخدام الافتراضي REPLY على read ، وتحويله إلى أحرف صغيرة ومقارنته بمجموعة من المتغيرات باستخدام تعبير.
يدعم البرنامج النصي أيضًا ja/si/oui

read -rp "Do you want a demo? [y/n/c] "

[[ ${REPLY,,} =~ ^(c|cancel)$ ]] && { echo "Selected Cancel"; exit 1; }

if [[ ${REPLY,,} =~ ^(y|yes|j|ja|s|si|o|oui)$ ]]; then
   echo "Positive"
fi
6
Walter A

لقد لاحظت أنه لم ينشر أحد إجابة توضح قائمة صدى متعددة الأسطر لمثل هذه المدخلات البسيطة للمستخدم ، فإليك ما يلي:

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

تم نشر هذه الطريقة على أمل أن يجدها شخص ما مفيدة وموفرة للوقت.

4
Yokai

نسخة متعددة الخيارات:

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 (داخل البرنامج النصي).

4
Ernest A

مستوحاة من إجابات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"
4
poxtron

إحدى الطرق البسيطة للقيام بذلك هي مع xargs -p أو gnu parallel --interactive.

يعجبني سلوك xargs بشكل أفضل قليلاً لأنه ينفذ كل أمر فورًا فور مطالبة مثل أوامر unix التفاعلية الأخرى ، بدلاً من تجميع yesses للتشغيل في النهاية. (يمكنك Ctrl-C بعد أن تحصل على ما تريد.)

على سبيل المثال،

echo *.xml | xargs -p -n 1 -J {} mv {} backup/
3
Joshua Goldberg

أقترح عليك استخدام مربع الحوار ...

المتدرب Linux: تحسين البرامج النصية Bash Shell باستخدام مربع حوار

يتيح أمر مربع الحوار استخدام مربعات النوافذ في البرامج النصية Shell لجعل استخدامها أكثر تفاعلية.

إنها بسيطة وسهلة الاستخدام ، وهناك أيضًا نسخة جنوم تسمى gdialog تأخذ نفس المعلمات بالضبط ، ولكنها تُظهر نمط واجهة المستخدم الرسومية على X.

3
Osama Al-Maadeed

أكثر عامة سيكون:

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
}
3
Alexander Löfqvist

كصديق لأمر من سطر واحد استخدمت ما يلي:

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=;

Longform مكتوبة ، وأنها تعمل مثل هذا:

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=;
2
ccDict

لقد استخدمت عبارة case عدة مرات في مثل هذا السيناريو ، باستخدام حالة الحالة هي طريقة جيدة لاستكشافها. يمكن تنفيذ حلقة while ، التي تلغي الكتلة case ، التي تستخدم شرطًا منطقيًا من أجل الاحتفاظ بمزيد من التحكم في البرنامج والوفاء بالعديد من المتطلبات الأخرى. بعد استيفاء جميع الشروط ، يمكن استخدام break والتي ستعيد التحكم إلى الجزء الرئيسي من البرنامج. أيضًا ، لاستيفاء الشروط الأخرى ، يمكن بالطبع إضافة عبارات شرطية لمرافقة هياكل التحكم: case statement و 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
2
oOpSgEo
yn() {
  if [[ 'y' == `read -s -n 1 -p "[y/n]: " Y; echo $Y` ]];
  then eval $1;
  else eval $2;
  fi }
yn 'echo yes' 'echo no'
yn 'echo absent no function works too!'
2
jlettvin

استجابة للآخرين:

لا تحتاج إلى تحديد الحالة في BASH4 فقط استخدم "،" لإنشاء أحرف صغيرة. أنا أيضًا لا أحب بشدة وضع الشفرة داخل كتلة القراءة ، والحصول على النتيجة والتعامل معها خارج كتلة القراءة IMO. قم أيضًا بتضمين "ف" لإنهاء IMO. أخيرًا لماذا اكتب "نعم" فقط استخدم -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
1
Mike Q

نعم/لا/الغاء

وظيفة

#!/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
1
Eduardo Cuomo