শর্তের ভিত্তিতে কেস ফলথ্রু rough


11

আমি ব্যাশের ক্ষেত্রে একটি শর্তের মধ্যে যদি একটি অবস্থার উপর ভিত্তি করে পতন ঘটে যাওয়ার উপায় খুঁজছি। উদাহরণ স্বরূপ:

input="foo"
VAR="1"

case $input in
foo)
    if [ $VAR = "1" ]; then

        # perform fallthrough

    else

        # do not perform fallthrough

    fi
;;
*)
    echo "fallthrough worked!"
;;
esac

উপরের কোড, যদি পরিবর্তনশীল VARহয় 1, আমি যদি শর্ত fallthrough সঞ্চালন আছে চাই।


1
ছোট প্রশ্ন: আপনি if [ $VAR -eq 1 ]; thenকোডের কিছু অংশ থেকে যা কিছু আছে তাতে লাফ দেওয়ার চেষ্টা করছেন *)? কারণ এটি পতনের কথা বলা থেকে সম্পূর্ণ পৃথক, এইভাবে আপনার প্রশ্ন বাক্সটিকে সামান্য বিভ্রান্তিকর করে তোলে।
সের্গেই কোলোডিয়াজনি

উত্তর:


8

আপনি পারবেন না। একটি আছে উপায় caseপতনের মাধ্যমে প্রতিস্থাপন করতে হয় ;;সঙ্গে বিভাজক ;&(অথবা ;;&)। এবং এটি যদি একটি if এর ভিতরে রাখার একটি বাক্য গঠন ত্রুটি।

আপনি নিয়মিত শর্তযুক্ত হিসাবে পুরো যুক্তিটি লিখতে পারেন:

if [ "$input" != "foo" ] || [ "$VAR" = 1 ]; then
    one branch ...
else   # $input = "foo" && $VAR != 1
    another branch...
fi


@ ইসহাক, ভাল, হ্যাঁ, যদিও তারা একটিতে পতনের কথা বেসিং নির্দিষ্ট করেছে if
ইল্কাচ্চু

+1 স্পষ্টত: আমি আপনার উত্তরে ভোট দিয়েছি। :)।
আইজাক

7

আমি আপনার যুক্তিটির পুনর্গঠন করার পরামর্শ দেব: পরিবর্তে "ফলথ্রু" কোডটি একটি ফাংশনে রাখুন:

fallthrough() { echo 'fallthrough worked!'; }

for input in foo bar; do
    for var in 1 2; do
        echo "$input $var"
        case $input in
            foo)
                if (( var == 1 )); then
                    echo "falling through"
                    fallthrough
                else
                    echo "not falling through"
                fi
            ;;
            *) fallthrough;;
        esac
    done
done

আউটপুট

foo 1
falling through
fallthrough worked!
foo 2
not falling through
bar 1
fallthrough worked!
bar 2
fallthrough worked!

7

নিম্নলিখিত স্ক্রিপ্টটি আপনার পরীক্ষাকে "ভিতরে আউট" করে তোলে সেই অর্থে যে আমরা $varপ্রথমে পরীক্ষা করি এবং তারপরে নির্ভর করে পতনপ্রথ ( ;&ক ব্যবহার করে case) সম্পাদন করি $input

আমরা এটা করতে কারণ থাকুক বা না থাকুক করা প্রশ্ন "fallthrough সঞ্চালন" সত্যিই শুধুমাত্র উপর নির্ভরশীল $inputযদি $varহয় 1। যদি এটি অন্য কোনও মান হয় তবে পতনসূত্রটি করা উচিত কিনা তাও জিজ্ঞাসা করতে হবে না।

#/bin/bash

input='foo'
var='1'

case $var in
    1)
        case $input in
            foo)
                echo 'perform fallthrough'
                ;&
            *)
                echo 'fallthough worked'
        esac
        ;;
    *)
        echo 'what fallthrough?'
esac

বা, ছাড়া case:

if [ "$var" -eq 1 ]; then
    if [ "$input" = 'foo' ]; then
        echo 'perform fallthrough'
    fi
    echo 'fallthough worked'
else
    echo 'what fallthrough?'
fi

আমি মনে করি আপনি ওপি আসলে যা চেয়েছিলেন তা পেরেক দিয়েছিলেন, যা মনে হয় যে যদি তাদের কাছে থেকে কিছু থাকে তবে তাদের মূল থেকে লাফিয়ে উঠছে *)। ইতিমধ্যে আমার +1 আছে।
সের্গেই কোলোডিয়াজনি

5

আমি যা করব এমন কিছু নয়, তবে আপনি এর সাথে পৌঁছানোর মতো কিছু অর্জন করতে পারেন:

shopt -s extglob # for !(*)
default='*'
case $input in
  (foo)
    if [ "$VAR" = 1 ]; then
      echo going for fallthrough
    else
      echo disabling fallthrough
      default='!(*)'
    fi ;;&

  ($default)
    echo fallthrough
esac

2

উভয় ভেরিয়েবল একবারে পরীক্ষা করুন (bash 4.0-alpha +):

#!/bin/bash
while (($#>1)); do
    input=$1    VAR=$2
    echo "input=${input} VAR=${VAR}"; shift 2

    if [ "$VAR" = 1 ]; then new=1; else new=0; fi

    case $input$new in
    foo0)   echo "do not perform fallthrough"   ;;
    foo*)   echo "perform fallthrough"          ;&
    *)      echo "fallthrough worked!"          ;;
    esac

    echo
done

পরীক্ষায়:

$ ./script foo 0   foo 1   bar baz
input=foo VAR=0
do not perform fallthrough

input=foo VAR=1
perform fallthrough
fallthrough worked!

input=bar VAR=baz
fallthrough worked!

পরিষ্কার এবং সহজ।

বুঝে নিন যে পরীক্ষিত মানটির ( $new) অবশ্যই দুটি সম্ভাব্য মান থাকতে হবে, এজন্যই যদি ক্লজটি থাকে তবে ভিএআরকে বুলিয়ান মানে রূপান্তর করতে। যদি ভিএআরটিকে বুলিয়ান হিসাবে তৈরি করা যেতে পারে তবে তার জন্য পরীক্ষা করুন 0(না 1) caseএবং এরটি অপসারণ করুন if


1

আপনি উত্থাপিতটি ডিফল্ট করতে পারেন তবে একটি শর্ত রাখতে পারেন যে শর্তটি পূরণ হলেই কোডটি কার্যকর করে

#!/bin/bash

input='foo'
var='1'

case $input in
foo)
        echo "Do fall through"
;& #always fall through
*)
        if [ $var = "1" ] #execute only if condition matches
        then
        echo "fallthrough took place"
        fi
esac

তবে ইল্কাচ্চু যেমন পরামর্শ দিয়েছেন আপনি স্যুইচ করার পরিবর্তে শর্তও ব্যবহার করতে পারেন।


1

যদি কেউ আপনার কোডটি বুঝতে না পারে এমন অভিযোগ করার বিষয়ে আপনি যদি আপত্তি না দেখেন তবে আপনি কেবল দুটি শর্তসাপকের ক্রমটি স্যুইচ করতে পারেন:

input="foo"
VAR="1"

if 
    case $input in
    foo)
        [ $VAR = "1" ]
    ;;
    esac
then
    echo "fallthrough worked!"
fi

বা:

input="foo"
VAR="1"

case $input in
foo)
    [ $VAR = "1" ]
;;
esac &&
    echo "fallthrough worked!"

সহজ এবং পরিষ্কার (কমপক্ষে আমার কাছে)। caseফলস্রুটি নিজেই সমর্থন করে না। কিন্তু আপনি প্রতিস্থাপন করতে পারেন *)সঙ্গে &&পরে esacএটি অন্যান্য শাখা ফেরত মান সম্মান করা।


-4

নতুন ;&এবং ;;&অপারেটরগুলি 4.0 সালে প্রবর্তিত হয়েছিলBash এবং যদিও তারা উভয়ই একইরকম পরিস্থিতিতে কার্যকর হতে পারে বলে আমি মনে করি তারা আপনার ক্ষেত্রে তাদের কোনও কাজে আসেনি। এই man bashঅপারেটরদের সম্পর্কে এটি যা বলে:

যদি ;; অপারেটর ব্যবহার করা হয়, প্রথম প্যাটার্ন ম্যাচের পরে পরবর্তী কোনও মিলের চেষ্টা করা হয় না। ব্যবহার করে & এর জায়গায় ;; পরবর্তী নিদর্শনগুলির সাথে সংযুক্ত তালিকার সাথে মৃত্যুদন্ড কার্যকর করার কারণ ঘটায়। ব্যবহার করে ;; এর জায়গায় ;; বিবৃতিতে শেলটি পরবর্তী প্যাটার্নের তালিকাটি পরীক্ষা করার কারণ এবং যদি কোনও সফল ম্যাচে সম্পর্কিত কোনও তালিকা সম্পাদন করে।

অন্য কথায়, ;&এর মাধ্যমে একটি পতনের রয়েছে এবং আমরা এটা থেকে জানি Cএবং ;;&তোলে bashঅবশিষ্ট মামলা পরিবর্তে থেকে ফিরে চেক caseসম্পূর্ণভাবে ব্লক। আপনি ;;&এখানে কর্মের একটি দুর্দান্ত উদাহরণ খুঁজে পেতে পারেন : /programming//a/24544780/3691891

এটি বলা হচ্ছে, আপনার স্ক্রিপ্টে ;&বা ;;&ব্যবহার করা যাবে না কারণ তারা উভয়ই গিয়েছিল*) যে সবসময় চালানো হবে।

নিম্নলিখিত স্ক্রিপ্টটি যুক্তিটিকে পুনরায় ব্যবস্থা না করে আপনি যা চান তা কাজ করে এবং কেবল এটি একটি উদাহরণ হিসাবে বিবেচনা করুন এবং কখনও এর উপর নির্ভর করবেন না এটি খুব ভঙ্গুর। আমি এখান থেকে ধারণা নিয়েছি :

#!/usr/bin/env bash

function jumpto
{
    label=$1
    cmd=$(sed -n "/$label:/{:a;n;p;ba};" "$0" | grep -v ':$')
    cmd=$(echo "$cmd" | sed 's,;;,,')
    cmd=$(echo "$cmd" | sed 's,esac,,')
    eval "$cmd"
}

input="foo"
VAR="1"

case $input in
foo)
    if [ $VAR = "1" ]; then

        printf "perform fallthrough\n"
        jumpto ft
    else
        printf "do not perform fallthrough\n"

    fi
;;
*)
    ft:
    echo "fallthrough worked!"
;;
esac


1
এটি খেলনা উদাহরণে কাজ করতে পারে তবে এটি অদম্য near এবং এটি কোনও বৃহত্তর স্ক্রিপ্টে কাজ করবে না। আপনি গোটোকে যেভাবে সিমুলেট করেন তা অত্যন্ত ভঙ্গুর, এবং এটি সত্যিই গোটোকে অনুকরণ করে বলে মনে করে যে এটি অত্যুক্তি। কোডটি jumptoফাংশন থেকে ফিরে আসে এবং এর পরে যা আসে তা কার্যকর করে। এটি যে ব্লকের মধ্যে ব্লকের পরে চালিয়ে যাওয়া চালিয়ে যাওয়ার সমতুল্য ft:এবং ;;এটি একটি কাকতালীয় কারণ jumptoএকই জটিল কমান্ডের শেষ কমান্ড হ'ল জাম্প-টু ব্লক।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

1
ঠিক আছে, আমি আমার জবাবে পরিষ্কারভাবে জোর দিয়েছি।
আরকাদিউস দ্রবকিজিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.