বিবৃতি হলে শেলের একাধিক অবস্থার প্রতিনিধিত্ব করবেন কীভাবে?


307

আমি এর মতো একাধিক শর্তের প্রতিনিধিত্ব করতে চাই:

if [ ( $g -eq 1 -a "$c" = "123" ) -o ( $g -eq 2 -a "$c" = "456" ) ]   
then  
    echo abc;  
else  
    echo efg;   
fi  

তবে আমি যখন স্ক্রিপ্টটি কার্যকর করি তখন এটি প্রদর্শিত হয়

syntax error at line 15: `[' unexpected, 

15 লাইনটি যেখানে প্রদর্শিত হচ্ছে যদি ....

এই শর্তটি কী ভুল? আমি অনুমান করি যে এর সাথে কিছু ভুল আছে ()


6
আপনি শেলের অবস্থার বিষয়ে নয় তবে পরীক্ষার শর্তগুলির বিষয়ে জিজ্ঞাসা করছেন । আপনার উদাহরণে সম্পূর্ণ অভিব্যক্তি শেল দ্বারা নয় test( [) দ্বারা মূল্যায়ন করা হয় । শেলটি কেবল প্রস্থান স্থিতির মূল্যায়ন করে [
সিলিং


সম্পর্কিত: বাশ
কোডফোরস্টার

উত্তর:


381

ক্লাসিক কৌশল (এস্কেপ মেটাচার্যাক্টস):

if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi

আমি রেফারেন্সগুলি $gডাবল উক্তিগুলিতে আবদ্ধ করেছি ; সাধারণভাবে এটি ভাল অনুশীলন। কড়া কথায়, প্রথম বন্ধনীগুলির প্রয়োজন হয় না কারণ এর অগ্রাধিকার রয়েছে -aএবং -oএগুলি ছাড়াও এটি সংশোধন করে।

লক্ষ্য করুন -aএবং -oঅপারেটরদের জন্য POSIX স্পেসিফিকেশন অংশ test, ওরফে [, প্রধানত পিছন সামঞ্জস্যের জন্য (যেহেতু তারা একটা অংশ ছিল test7th সংস্করণ ইউনিক্স মধ্যে, উদাহরণস্বরূপ), কিন্তু তারা স্পষ্টভাবে POSIX দ্বারা 'লুপ্তপ্রায়' হিসেবে চিহ্নিত করা হয়েছে। বাশ ( শর্তসাপেক্ষ এক্সপ্রেশনগুলি দেখুন ) ক্লাসিক এবং POSIX অর্থকে নিজের বিকল্প অপারেটরগুলির পক্ষে -aএবং -oযুক্তিগুলি গ্রহণ করে বলে মনে হয় ।


কিছু যত্ন সহ, আপনি আরও আধুনিক [[অপারেটর ব্যবহার করতে পারেন , তবে সচেতন হন যে বাশ এবং কর্ন শেলের সংস্করণগুলিতে অভিন্ন হওয়ার দরকার নেই ident

for g in 1 2 3
do
    for c in 123 456 789
    do
        if [[ ( "$g" -eq 1 && "$c" = "123" ) || ( "$g" -eq 2 && "$c" = "456" ) ]]
        then echo "g = $g; c = $c; true"
        else echo "g = $g; c = $c; false"
        fi
    done
done

ম্যাক ওএস এক্সে ব্যাশ ৩.২.৫7 ব্যবহার করে রান উদাহরণ:

g = 1; c = 123; true
g = 1; c = 456; false
g = 1; c = 789; false
g = 2; c = 123; false
g = 2; c = 456; true
g = 2; c = 789; false
g = 3; c = 123; false
g = 3; c = 456; false
g = 3; c = 789; false

[[আপনার সাথে ভেরিয়েবলগুলি উদ্ধৃত করার দরকার নেই [কারণ এটি যেভাবে হয় তেমন পৃথক কমান্ড নয় [


এটি কি ক্লাসিক প্রশ্ন নয়?

আমি তাই ভাবতাম। তবে, আরও একটি বিকল্প রয়েছে:

if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi

আসলে, আপনি যদি autoconfসরঞ্জাম বা সম্পর্কিত প্যাকেজগুলির জন্য 'পোর্টেবল শেল' নির্দেশিকাটি পড়েন তবে এই নোটেশনটি ' ||' এবং ' &&' ব্যবহার করে - তারা তাদের পরামর্শ দেয় they আমি মনে করি আপনি এমনকি এতদূর যেতে পারেন:

if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi

ক্রিয়াগুলি যেমন প্রতিধ্বনির মতো তুচ্ছ, সেখানে এটি খারাপ নয়। পুনরাবৃত্তি করার জন্য অ্যাকশন ব্লকটি একাধিক রেখাগুলি হলে পুনরাবৃত্তিটি খুব বেদনাদায়ক এবং পূর্ববর্তী সংস্করণগুলির মধ্যে একটি পছন্দনীয় - অথবা আপনাকে ক্রিয়াকলাপগুলিকে বিভিন্ন ফাংশনে আবদ্ধ করা দরকার যা বিভিন্ন ব্লকটিতে ডাকা thenহয়।


9
পালানো বন্ধনীগুলির কাজটি জেনে রাখা ভাল; যেমন সরাইয়া একটি: এই বিশেষ ক্ষেত্রে, প্রথম বন্ধনী এমনকি প্রয়োজন হয় না, কারণ -aআসলে বেশী প্রাধান্য রয়েছে -o(অসদৃশ &&এবং ||শেল - তবে, ভিতরে bash [[ ... ]] কন্ডিশন , && এছাড়াও বেশী প্রাধান্য রয়েছে ||)। আপনি এড়াতে চেয়েছিলেন -aএবং -oসর্বোচ্চ বলিষ্ঠতার এবং বহনযোগ্যতা জন্য - যা POSIX মানুষ পৃষ্ঠায় সরাসরি প্রস্তাব দেওয়া - আপনার কাছে ব্যবহার করতে পারে subshells জন্য গোষ্ঠীবদ্ধ করা:if ([ $g -eq 1 ] && [ "$c" = "123" ]) || ([ $g -eq 2 ] && [ "$c" = "456" ])
mklement0

ভাল সমাধান, তবে আমি সমস্ত বন্ধনী এবং বন্ধনী ছাড়াই ফর্মটি পছন্দ করি:if test "$g" -eq 1 -a "$c" = "123" || test "$g" -eq 2 -a "$c" = "456"; then ...
মোগেনস ট্র্যাশারডিকে

আমি এই দেরী একটু নই, কিন্তু এটি এখনও একটি শীর্ষ অনুসন্ধান ফলাফল উপস্থিত, তাই আমি চাই দয়া করে মনে রাখবেন ব্যবহার করে ঠিক &&বা ||যেমন আরো অন্যান্য ভাষায় কন্ডিশন মত আচরণ এছাড়াও বাঞ্ছনীয় আছে, এবং আপনি করতে দেয় শর্ট সার্কিট শর্ত। উদাহরণস্বরূপ: if [ -n "${check_inodes}" ] && [ "$(stat -f %i "/foo/bar")" = "$(stat -f %i "/foo/baz")" ]। এইভাবে এটি করা, যদি check_inodesখালি থাকে তবে আপনি দুটি কল এড়াতে পারবেন stat, তবে বৃহত্তর, জটিল পরীক্ষার শর্তটি কার্যকর করার আগে সমস্ত যুক্তিগুলি প্রক্রিয়া করতে হবে (এটি যদি আপনি সেই আচরণটি ভুলে যান তবে বাগগুলিও ডেকে আনতে পারে)।
হারাভিক্ক

182

বাশে:

if [[ ( $g == 1 && $c == 123 ) || ( $g == 2 && $c == 456 ) ]]

9
অবশ্যই সেরা পন্থা bash। একপাশে হিসাবে: এই বিশেষ ক্ষেত্রে প্রথম বন্ধনী এমনকি প্রয়োজন হয় না, কারণ অভ্যন্তরীণ [[ ... ]] শর্তসাপেক্ষে && আসলে তুলনায় উচ্চতর প্রাধান্য রয়েছে ||- যেমন শর্তসাপেক্ষ বাইরে unlike
mklement0

এখানে কোন শর্তের মিল রয়েছে তা আমরা জানতে পারি কি? এটি প্রথম বন্ধনীর এক বা অন্যটি ছিল?
ফায়ারলর্ড

1
@Firelord: আপনি একটি মধ্যে অবস্থার আলাদা প্রয়োজন চাই if/ elseবিবৃতি এবং মধ্যবর্তী কোড আছে thenএবং fiযাতে এটা পুনরাবৃত্তি এড়ানোর জন্য একটি ফাংশন রাখা। খুব সাধারণ ক্ষেত্রে আপনি পতনের caseসাথে একটি বিবৃতি ব্যবহার করতে পারেন ;&(বাশে 4 তে)।
পরবর্তী বিজ্ঞপ্তি না হওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

1
দুটি বর্গাকার বন্ধনীগুলির উদ্দেশ্য কী?
পিটারচাউলা


37

/bin/bashনিম্নলিখিত ব্যবহার করে কাজ করবে:

if [ "$option" = "Y" ] || [ "$option" = "y" ]; then
    echo "Entered $option"
fi

8

আপনার স্ট্রিং ভেরিয়েবলগুলিতে ফাঁকা স্থান রয়েছে এবং আপনি অস্তিত্বের জন্য যাচাই করেন যদি সতর্ক হন। সেগুলি যথাযথভাবে উদ্ধৃত করতে ভুলবেন না।

if [ ! "${somepath}" ] || [ ! "${otherstring}" ] || [ ! "${barstring}" ] ; then

1
যখন আমরা ডলার চিহ্নের পরে কোঁকড়া বন্ধনী ব্যবহার করি !!
আশ্চর্যজনক

6
$ g=3
$ c=133
$ ([ "$g$c" = "1123" ] || [ "$g$c" = "2456" ]) && echo "abc" || echo "efg"
efg
$ g=1
$ c=123
$ ([ "$g$c" = "1123" ] || [ "$g$c" = "2456" ]) && echo "abc" || echo "efg"
abc

2
এটি একটি অকেজো সাবস্কেল। { ;}পরিবর্তে ব্যবহার করা যেতে পারে।
পিএইচকে

2

স্ট্রিং তুলনা জন্য বাশ, আপনি নিম্নলিখিত কৌশল ব্যবহার করতে পারেন।

if [ $var OP "val" ]; then
    echo "statements"
fi

উদাহরণ:

var="something"
if [ $var != "otherthing" ] && [ $var != "everything" ] && [ $var != "allthings" ]; then
    echo "this will be printed"
else
    echo "this will not be printed"
fi

0
#!/bin/bash

current_usage=$( df -h | grep 'gfsvg-gfslv' | awk {'print $5'} )
echo $current_usage
critical_usage=6%
warning_usage=3%

if [[ ${current_usage%?} -lt ${warning_usage%?} ]]; then
echo OK current usage is $current_usage
elif [[ ${current_usage%?} -ge ${warning_usage%?} ]] && [[ ${current_usage%?} -lt ${critical_usage%?} ]]; then
echo Warning $current_usage
else
echo Critical $current_usage
fi

3
স্ট্যাক ওভারফ্লোতে স্বাগতম! এই প্রশ্নটি কেবল ওয়ার্কিং কোডের জন্য নয়, একটি ব্যাখ্যা খুঁজছে । আপনার উত্তরটি প্রশ্নকারীকে কোনও অন্তর্দৃষ্টি দেয় না এবং মুছে ফেলা হতে পারে। পর্যবেক্ষণের লক্ষণগুলির কারণ কী তা বোঝাতে দয়া করে সম্পাদনা করুন ।
টবি স্পিড

0

আপনি 2 টিরও বেশি শর্তও চেইন করতে পারেন:

if [ \( "$1" = '--usage' \) -o \( "$1" = '' \) -o \( "$1" = '--help' \) ]
then
   printf "\033[2J";printf "\033[0;0H"
   cat << EOF_PRINT_USAGE

   $0 - Purpose: upsert qto http json data to postgres db

   USAGE EXAMPLE:

   $0 -a foo -a bar



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