बैश में, "क्या आप सुनिश्चित हैं कि [Y / n]" किसी भी कमांड या उपनाम से?


228

इस विशेष मामले में, मैं बैश के लिए एक पुष्टिकरण जोड़ना चाहूंगा

क्या आपको यकीन है? [Y n]

मर्क्यूरियल के लिए hg push ssh://username@www.example.com//somepath/morepath, जो वास्तव में एक उपनाम है। क्या कोई मानक कमांड है जिसे इसे प्राप्त करने के लिए उपनाम में जोड़ा जा सकता है?

इसका कारण यह है hg pushऔर hg outकभी-कभी इसी तरह की ध्वनि हो सकती है और जब मैं चाहता hgoutrepoहूं, मैं गलती से टाइप कर सकता हूं hgpushrepo(दोनों उपनाम हैं)।

अद्यतन: अगर यह किसी अन्य कमांड के साथ बिल्ट-इन कमांड की तरह हो सकता है, जैसे: confirm && hg push ssh://...कि बहुत अच्छा होगा ... बस एक कमांड जो yesया तो पूछ सकता है noऔर बाकी के साथ जारी रख सकता है yes


1
आप शायद एक उपनाम के बजाय एक फ़ंक्शन का उपयोग करना चाहेंगे । से info bash: "लगभग हर उद्देश्य के लिए, शेल फ़ंक्शन उपनामों पर पसंद किए जाते हैं।"
अगली सूचना तक रोक दिया गया।

वास्तव में? जैसे लोगों के लिए भी ls -lया rm -i?
३२ बजे

5
के लिए लगभग हर, नहीं हर । वैसे, कभी भी कुछ ऐसा करें alias rm='rm -i'। एक दिन, जब आपको इसकी सबसे अधिक आवश्यकता होती है, तो उपनाम नहीं होगा और boom!कुछ महत्वपूर्ण खो जाएगा।
अगली सूचना तक रोक दिया गया।

प्रतीक्षा करें, यदि आपके पास उपनाम नहीं है rm -i, तो आप एक शेल स्क्रिप्ट के रूप में अच्छी तरह से गिन नहीं सकते हैं। तो क्या आप हमेशा rm -iहर बार टाइप करते हैं ?
एकाधिकार

8
यह आदतों के बारे में है । आप मेरी पिछली टिप्पणी की तरह एक उपनाम बना सकते हैं rmऔर टाइप करने और -iव्यवहार की अपेक्षा करने की आदत में हो सकते हैं, फिर एक दिन उपनाम नहीं है (किसी कारण से यह सेट नहीं होता है या सेट नहीं है या आप एक अलग सिस्टम पर हैं) ) और आप टाइप करते हैं rmऔर यह बिना पुष्टि के सामान को तुरंत हटाने के लिए आगे बढ़ता है। ऊप्स! हालाँकि, अगर आपने एक उर्फ ​​की तरह किया alias askrm='rm -i'तो आप ठीक होंगे, क्योंकि आपको "कमांड नहीं मिला" त्रुटि मिलेगी।
अगली सूचना तक रोक दिया गया।

जवाबों:


332

ये हामिश के उत्तर के अधिक कॉम्पैक्ट और बहुमुखी रूप हैं । वे ऊपरी और निचले मामले के पत्रों के किसी भी मिश्रण को संभालते हैं:

read -r -p "Are you sure? [y/N] " response
case "$response" in
    [yY][eE][sS]|[yY]) 
        do_something
        ;;
    *)
        do_something_else
        ;;
esac

या, बैश के लिए> = संस्करण 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":। - हमेशा स्ट्रिंग्स वाले वेरिएबल्स में दोहरे उद्धरण चिह्नों का उपयोग करें (जैसे: "$@"इसके बजाय उपयोग करना पसंद करते हैं $@)।

या, बैश 4.x:

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

संपादित करें:

आपके संपादन के जवाब में, यहां बताया गया है कि आप confirmमेरे उत्तर में पहले संस्करण के आधार पर एक कमांड कैसे बनाएंगे और उसका उपयोग करेंगे (यह अन्य दो के साथ भी इसी तरह काम करेगा):

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://..

9
वास्तव में यह वर्तमान परीक्षा के लिए [y / N] होना चाहिए न कि [Y / n]।
साइमन ए। यूगस्टर

इस बात का उल्लेख करते हुए कि यदि आप not equal toदूसरे उदाहरण पर जांच करना चाहते हैं , तो आपको $responseचर कास्ट करना चाहिए । उदाहरण के लिए: if [[ ! $response =~ ^([yY][eE][sS]|[yY])$ ]]
जोओ कून्हा

@ JoãoCunha: यह =~रेगेक्स मैच ऑपरेटर के बाद से "नहीं के बराबर" होने के बजाय "मैच नहीं" होगा ।
अगली सूचना तक रोक दिया गया।

@ डेनिसविलियम्सन सही है, यही मेरा मतलब है। किसी कारण से मेरी टिप्पणी को संपादित नहीं किया जा सकता।
जोओ कून्हा

6
अच्छा सामान्य उद्देश्य हाँ / कोई कार्य नहीं । एक त्वरित मजबूत का समर्थन करता है, और वैकल्पिक रूप से 'y' या 'n' डिफ़ॉल्ट बनाता है।
WKW

19

यहाँ लगभग एक स्निपेट है जो आप चाहते हैं। मुझे पता लगाने के लिए कि कैसे तर्कों को आगे बढ़ाया जाए।

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:)


13

पुष्टि आसानी से कैरिज रिटर्न के साथ होती है, और मुझे यह मान्य इनपुट के लिए लगातार संकेत देने के लिए उपयोगी लगता है।

यहाँ यह आसान बनाने के लिए एक समारोह है। "अवैध इनपुट" लाल दिखाई देता है यदि 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

आप एक तर्क पास करके डिफ़ॉल्ट प्रॉम्प्ट को बदल सकते हैं


12

'हाँ' के इन प्रकारों के लिए स्पष्ट रूप से जाँच से बचने के लिए आप नियमित अभिव्यक्ति के साथ bash रेगुलर एक्सप्रेशन ऑपरेटर '= ~' का उपयोग कर सकते हैं:

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

यह जांचता है कि क्या उपयोगकर्ता इनपुट 'y' या 'Y' से शुरू होता है और इसके बाद शून्य या अधिक 'es' आता है।


5

यह हैक हो सकता है:

जैसा कि यूनिक्स / बैश में सवाल है , "xargs -p" किसी भी कमांड को चलाने से पहले पुष्टि के लिए संकेत देने का एक अच्छा तरीका है?

हम xargsकाम करने के लिए उपयोग कर सकते हैं :

echo ssh://username@www.example.com//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

$

4

अपने / etc / bashrc फ़ाइल में निम्न जोड़ें। यह स्क्रिप्ट "पुष्टि" नामक उपनाम के बजाय एक निवासी "फ़ंक्शन" जोड़ता है।


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
}

अच्छा लगा। कुछ मामूली सुधार, हालांकि: आपको दोहरे उद्धरण लगाना चाहिए $responseऔर $@गलतफहमी से बचने के लिए, कुछ अनावश्यक अर्धविराम हैं, और *स्थिति को वापस लौटना चाहिए, बाहर नहीं निकलना चाहिए।
गॉर्डन डेविसन

बस स्पष्ट होने के लिए, यह कुछ बयानों के अंत में एकल अर्धविराम है जो अनावश्यक हैं।
अगली सूचना तक रोक दिया गया।

4

यह थोड़ा बहुत कम हो सकता है, लेकिन मेरे अपने निजी उपयोग के लिए, यह बहुत अच्छा काम करता है

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सिर्फ एक चरित्र पढ़ता है। एंट्री मारने की जरूरत नहीं। यदि यह 'एन' या 'एन' नहीं है, तो इसे 'वाई' माना जाता है। बस एंटर दबाने का मतलब Y भी है।

(जैसा कि वास्तविक प्रश्न के लिए है: उस बैश स्क्रिप्ट को बनाएं और अपने उपनाम को उस स्क्रिप्ट की ओर इंगित करने के लिए बदलें जो पहले की ओर इंगित करता है)


छोटी और प्यारी, बस मुझे जो चाहिए था। धन्यवाद!
Raymo111

3
read -r -p "Are you sure? [Y/n]" response
  response=${response,,} # tolower
  if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
      your-action-here
  fi

तो एक अंतरिक्ष चरित्र का मतलब हां है?
एक्सएन 2050 3

सभी लेकिन 'हां या वाई' कार्रवाई की पुष्टि करेगा, इसलिए आप सही हैं! @ xen2050
सर्जियोअराउजो

3

कोई दबाव दर्ज करने की आवश्यकता है

यहाँ एक लंबा, लेकिन पुन: प्रयोज्य और मॉड्यूलर दृष्टिकोण है:

  • रिटर्न 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 *

दर्ज करते समय "हाँ" के लिए डिफ़ॉल्ट

ध्यान दें कि 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या असत्य वापस किया गया था। में कोई पूंजीकरण नोट करें[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
}

2

खैर, यहाँ मेरा संस्करण है 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इसके बजाय उपयोग करें । बेशक, यह बैश-4.4 (विंडोज के लिए गिट में वर्तमान एक) के साथ भी संगत है।
  5. IPython- शैली का उपयोग करें "(y / [n])" स्पष्ट रूप से इंगित करने के लिए कि "n" डिफ़ॉल्ट है।

2

यह संस्करण आपको एक से अधिक मामलों yया Y, nया के लिए अनुमति देता हैN

  1. वैकल्पिक रूप से: प्रश्न को तब तक दोहराएं जब तक कि स्वीकृत प्रश्न प्रदान नहीं किया जाता है

  2. वैकल्पिक रूप से: किसी अन्य उत्तर को अनदेखा करें

  3. वैकल्पिक रूप से: यदि आप चाहें तो टर्मिनल से बाहर निकलें

    confirm() {
        echo -n "Continue? y or n? "
        read REPLY
        case $REPLY in
        [Yy]) echo 'yup y' ;; # you can change what you do here for instance
        [Nn]) break ;;        # exit case statement gracefully
        # Here are a few optional options to choose between
        # Any other answer:
    
        # 1. Repeat the question
        *) confirm ;;
    
        # 2. ignore
        # *) ;;
    
        # 3. Exit terminal
        # *) exit ;;
    
        esac
        # REPLY=''
    }

इसे भी नोट करें: इस फ़ंक्शन की अंतिम पंक्ति पर REPLY चर को साफ़ करें। अन्यथा यदि आप echo $REPLYदेखेंगे कि यह तब भी सेट है जब तक आप अपने टर्मिनल को खोलते या बंद नहीं करते हैं या इसे फिर से सेट नहीं करते हैं।


1

खेल के अंत में, लेकिन मैंने 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 -enके साथ काम करता है, bashलेकिन आपके शेल में विफल हो सकता है
  • बहस विफल हो सकती है अगर तर्कों के साथ हस्तक्षेप echoयाxargs
  • एक zillion अन्य कीड़े क्योंकि शेल स्क्रिप्टिंग कठिन है

1

प्रयत्न,

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

यह वास्तव में "हां या नहीं के लिए पूछना" नहीं है, लेकिन सिर्फ एक हैक: उर्फ hg push ...टू टू द नॉट hgpushrepoटू hgpushrepoconfirmedpushद व तब तक जब तक मैं पूरी चीज को बाहर निकाल सकता हूं, बाएं मस्तिष्क ने एक तार्किक विकल्प बना दिया है।


1
लेकिन आप जानते हैं कि आप TABकुंजी का उपयोग करेंगे !
हामिश ग्रुबीजान

ठीक है, सच है, लेकिन कम से कम मैं कमांड को देखूंगा और देखूंगा कि यह अजीब है और
एंट्री

0

समान नहीं है, लेकिन विचार जो वैसे भी काम करता है।

#!/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 के पहले वर्ण की जांच करता है।


0

नीचे कोड दो चीजों को मिला रहा है

  1. shops -s nocasematch जो मामले को असंवेदनशील बना देगा

  2. और अगर शर्त यह है कि दोनों इनपुट स्वीकार करेंगे या तो आप हाँ, हाँ, हाँ, y पास करेंगे।

    shops -s nocasematch

    अगर [[sed-4.2.2। $ LINE = ~ (हाँ | y) $]]

    फिर बाहर निकलें 0

    फाई


0

यहाँ मेरा समाधान है कि स्थानीयकृत रेगेक्स का उपयोग कर रहा हूं। तो जर्मन में भी "जा" के लिए "जे" की व्याख्या हां के रूप में की जाएगी।

पहला तर्क प्रश्न है, यदि दूसरा तर्क "y" है तो हाँ डिफ़ॉल्ट उत्तर होगा अन्यथा कोई डिफ़ॉल्ट उत्तर नहीं होगा। वापसी मान 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]? : "
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.