linux - ভর্তি বাতিলের জন্য আবেদন দরখাস্ত



একটি লিনাক্স শেল স্ক্রিপ্টে আমি হ্যাঁ/না/ইনপুট বাতিল করার জন্য কীভাবে প্রম্পট করব? (19)

একটি জেনেরিক প্রশ্নের জন্য অন্তত পাঁচটি উত্তর।

উপর নির্ভর করে

  • posix সঙ্গতিপূর্ণ: জেনেরিক shell পরিবেশ সঙ্গে দরিদ্র সিস্টেমের উপর কাজ করতে পারে
  • bash নির্দিষ্ট: তথাকথিত bashisms ব্যবহার করে

এবং যদি আপনি চান

  • সাধারণ '`লাইন' 'প্রশ্ন / উত্তর (জেনেরিক সমাধান)
  • চমত্কার বিন্যাসিত ইন্টারফেস, যেমন ncurses বা libgtk বা libqt ব্যবহার করে আরো গ্রাফিকাল ...
  • শক্তিশালী পঠন ইতিহাস ক্ষমতা ব্যবহার করুন

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

( অ্যাডাম Katz এর মন্তব্য ধন্যবাদ: আরো পোর্টেবল এক সঙ্গে উপরে পরীক্ষা প্রতিস্থাপিত এবং একটি ফর্ক এড়ানো :)

POSIX, কিন্তু একক কী বৈশিষ্ট্য

কিন্তু আপনি যদি ব্যবহারকারীকে রিটার্ন আঘাত করতে না চান তবে আপনি লিখতে পারেন:

( সম্পাদিত: @ জনাথন লেফ্লারের ঠিক মতামত দেওয়া হয়েছে যে, স্টিটির কনফিগারেশন সংরক্ষণ করা তাদের পক্ষে সহজেই জোরদার হতে পারে।)

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 , dash এবং 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 সরঞ্জাম সহ 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. Bash নির্দিষ্ট সমাধান

লাইন পদ্ধতি বেসিক

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 জন্য পরীক্ষা করতে পারে yes | ja | si | oui yes | ja | si | oui প্রয়োজন হলে ...

একক কী বৈশিষ্ট্য সঙ্গে লাইন

Bash এর অধীনে, আমরা read কমান্ডের উদ্দেশ্যে উদ্দেশ্যে ইনপুটটির দৈর্ঘ্য নির্দিষ্ট করতে পারি:

read -n 1 -p "Is this a good question (y/n)? " answer

Bash এর অধীনে, কমান্ডটি একটি টাইমআউট পরামিতি গ্রহণ করে যা কার্যকর হতে পারে।

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 অতিক্রম করা 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

আরো নমুনা? ইউএসবি ডিভাইস এবং ইউএসবি অপসারণযোগ্য স্টোরেজ সিলেক্টর নির্বাচন করার জন্য উইটাইল ব্যবহার করে দেখুন: ইউএসবি কেইচোজার

5. পঠন এর ইতিহাস ব্যবহার করে

উদাহরণ:

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

এটি আপনার $HOME ডিরেক্টরিতে .myscript.history ফাইল তৈরি করবে, আপনি .myscript.history , ডাউন , Ctrl + r এবং অন্যদের মতো .myscript.history ইতিহাস কমান্ডগুলি ব্যবহার করতে পারেন।

https://ffff65535.com

আমি একটি শেল স্ক্রিপ্টে ইনপুট থামাতে চাই, এবং ব্যবহারকারীর পছন্দগুলির জন্য অনুরোধ জানাই। মান 'হ্যাঁ, না, বা বাতিল' টাইপ প্রশ্ন। আমি কিভাবে একটি সাধারণ bash প্রম্পটে এই কাজ করতে পারি?


হ্যাঁ / না / বাতিল

ক্রিয়া

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

তুমি চাও:

  • 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
  • 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

@ মার্ক এবং @ মিরডিনের উত্তরগুলি দ্বারা অনুপ্রাণিত আমি এই ক্রিয়াকলাপটি সর্বজনীন প্রম্পটের জন্য তৈরি করেছি

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"

আপনি অন্তর্নির্মিত কমান্ড ব্যবহার করতে পারেন; একটি প্রশ্ন সঙ্গে ব্যবহারকারী প্রম্পট করার জন্য -p বিকল্প ব্যবহার করুন।

যেহেতু BASH4 থেকে, আপনি এখন উত্তর দেওয়ার জন্য -i ব্যবহার করতে পারেন, তাই ব্যবহারকারীকে শুধুমাত্র এটির প্রবেশ করতে return পাঠাতে হবে:

read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
echo $FILEPATH

(কিন্তু "রেডলাইন" বিকল্পটি ব্যবহার করতে মনে রাখবেন -e তীরচিহ্নগুলির সাথে লাইন সম্পাদনা করার অনুমতি দিতে)

যদি আপনি "হ্যাঁ / না" যুক্তিটি চান তবে আপনি এটির মতো কিছু করতে পারেন:

read -e -p "
List the content of your home dir ? [Y/n] " YN

[[ $YN == "y" || $YN == "Y" || $YN == "" ]] && ls -la ~/

আপনি একটি read উপর ডিফল্ট REPLY ব্যবহার করতে পারেন, ছোট হাতের অক্ষরে রূপান্তর এবং একটি অভিব্যক্তি সঙ্গে ভেরিয়েবল একটি সেট তুলনা করতে পারেন।
স্ক্রিপ্ট ja / si / qui সমর্থন করে

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

আমি একসাথে করা কিছু এখানে:

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

আমি একটি শিক্ষানবিস, তাই লবণ একটি শস্য সঙ্গে এই নিন, কিন্তু এটা কাজ বলে মনে হয়।


আমি লক্ষ্য করেছি যে কোনও সহজ ব্যবহারকারীর ইনপুটের জন্য মাল্টি-লাইন ইকো মেনু দেখানোর কোনও উত্তর পোস্ট করে নি তাই এখানে আমার যাওয়া যায়:

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

এই পদ্ধতির কেউ এটি দরকারী এবং সময়-সঞ্চয় খুঁজে পেতে পারে যে আশা পোস্ট করা হয়েছে।


এই সমাধান একটি একক অক্ষর পড়া এবং একটি হ্যাঁ প্রতিক্রিয়া একটি ফাংশন কল।

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

এক লাইন কমান্ডের একজন বন্ধু হিসাবে আমি নিম্নলিখিতটি ব্যবহার করেছি:

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

একাধিক পছন্দ সংস্করণ:

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
$

এটি y REPLY দেবে (স্ক্রিপ্টের ভিতরে)।


এটি করার একটি সহজ উপায় হল xargs -p বা gnu parallel --interactive

আমি xargs এর আচরণটির জন্য এটি আরও ভালোভাবে পছন্দ করি কারণ এটি শেষে চালানোর জন্য yesses সংগ্রহ করার পরিবর্তে অন্যান্য ইন্টারেক্টিভ ইউনিক্স কমান্ডের মত প্রম্পটের পরে প্রতিটি কমান্ড কার্যকর করে। (আপনি যা চেয়েছিলেন তা পেতে পরে আপনি Ctrl-C টিপুন।)

যেমন,

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

বাশ এই উদ্দেশ্যে select করেছেন।

select result in Yes No Cancel
do
    echo $result
done

যেমন একটি পুরানো পোস্ট পোস্ট করার জন্য দুঃখিত। কয়েক সপ্তাহ আগে আমি একই রকম সমস্যার মুখোমুখি ছিলাম, আমার ক্ষেত্রে আমার এমন একটি সমাধান দরকার যা অনলাইন ইনস্টলার-স্ক্রিপ্টের মধ্যে কাজ করে, যেমন: curl -Ss https://raw.github.com/_____/installer.sh | bash curl -Ss https://raw.github.com/_____/installer.sh | bash

read yesno < /dev/tty ব্যবহার 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

এই কেউ সাহায্য করে আশা করি।


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

এবং তারপর আপনার প্রয়োজন অন্যান্য স্টাফ


শেল প্রম্পটে ব্যবহারকারী ইনপুট পেতে সহজতম এবং সর্বাধিক ব্যাপকভাবে উপলব্ধ পদ্ধতি হল read কমান্ড। তার ব্যবহার illustrated সবচেয়ে ভাল উপায় একটি সহজ বিক্ষোভ:

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

স্টিভেন হুউইগ-এর আরেকটি পদ্ধতি, বাশের 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 লুপের পুনরায় চেষ্টা করার প্রয়োজন নেই।

এছাড়াও, অনুগ্রহ করে চমৎকার উত্তরটি দেখুন F. Hauri।


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

...

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

-e বিকল্পটি ব্যবহারকারীকে তীর কী ব্যবহার করে ইনপুট সম্পাদনা করতে সক্ষম করে।

যদি আপনি ইনপুট হিসাবে একটি পরামর্শ ব্যবহার করতে চান:

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

-i বিকল্প একটি পরামর্শমূলক ইনপুট প্রিন্ট।


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!'




scripting