বাশ স্ক্রিপ্টের কোনও পরামিতি কোনও স্ট্রিংয়ের সাথে মেলে কিনা তা পরীক্ষা করুন


67

আমি এমন একটি স্ক্রিপ্ট লেখার চেষ্টা করছি যেখানে আমি কোনও প্যাটার্নি বাশ স্ক্রিপ্টে পাস করেছে কিনা তা পরীক্ষা করে দেখতে চাই a এখনই আমার সেটআপটি যেভাবে চলছে তা হ'ল

if [ "$3" != "-disCopperBld" -a "$4" != "-disCopperBld" -a "$5" != "-disCopperBld" -a "$6" != "-disCopperBld"]

তবে প্যারামিটারগুলির একটি বিশাল সংখ্যা থাকতে পারে, তাই আমি ভাবছিলাম যে এটি করার আরও ভাল উপায় আছে কিনা?

ধন্যবাদ

সম্পাদনা: আমি কোডটির এই খণ্ডটি চেষ্টা করে দেখেছি এবং স্ক্রিপ্টটিকে বিকল্প হিসাবে ডেসেবল ভেনাসবল্ড বলেছি কিন্তু এটি এখনও "বিল্ডিং শুরু করা" ছাপে। আমি কি ভুল কিছু করছি? আগাম ধন্যবাদ!

while [ $# -ne 0 ]
do
    arg="$1"
    case "$arg" in
        -disableVenusBld)
            disableVenusBld=true
            ;;
        -disableCopperBld)
            disableCopperBld=true
            ;;
        -disableTest)
            disableTest=true
            ;;
        -disableUpdate)
            disableUpdate=true
            ;;
        *)
            nothing="true"
            ;;
    esac
    shift
done

if [ "$disableVenusBld" != true ]; then
    echo "Starting build"
fi

প্রত্যুত্তর বলার জন্য ধন্যবাদ, আমি আপনাকে সাহায্য করার জন্য সময় দিতেন তা আমি প্রশংসা করি। আমি কোডের একটি অংশ চেষ্টা করেছি, তবে আমি কী ভুল হচ্ছে তা অনুভব করতে পারি না। কোন ধারনা? (আমি আমার মূল পোস্টের সম্পাদনায়
কোডটি আটকিয়েছি

হুম: এটি আমার পক্ষে কাজ করে। #! /bin/sh -আপনি সেখানে যা অন্তর্ভুক্ত করেছেন তার শীর্ষে আমি যুক্ত করেছি, স্ক্রিপ্টটি কার্যকরযোগ্য করে তুলেছি, তারপরে ./t.sh"বিল্ডিং শুরু করা" ./t.sh -disableVenusBldমুদ্রণ করি , তবে কিছুই প্রিন্ট করে না।
নরম্যান গ্রে

উত্তর:


59

দেখে মনে হচ্ছে আপনি শেল স্ক্রিপ্টে অপশন হ্যান্ডলিং করছেন। এখানে তার প্রতিবাদটি এখানে:

#! /bin/sh -

# idiomatic parameter and option handling in sh
while test $# -gt 0
do
    case "$1" in
        --opt1) echo "option 1"
            ;;
        --opt2) echo "option 2"
            ;;
        --*) echo "bad option $1"
            ;;
        *) echo "argument $1"
            ;;
    esac
    shift
done

exit 0

(ইনডেন্টিংয়ের জন্য কয়েকটি কনভেনশন রয়েছে ;;, এবং কয়েকটি শেল আপনাকে (--opt1)ব্রেস ম্যাচিংয়ে সহায়তা করার জন্য বিকল্পগুলি দেওয়ার অনুমতি দেয় তবে এটি প্রাথমিক ধারণা)


3
shiftএকটি কমান্ডের সাথে যুক্তির সংখ্যা আগে থেকে জানা না গেলে একটি বিবৃতি ব্যবহৃত হয়, উদাহরণস্বরূপ যখন ব্যবহারকারীরা তাদের পছন্দমতো আর্গুমেন্ট দিতে পারেন। এই জাতীয় ক্ষেত্রে, যুক্তিগুলির whileপরীক্ষার শর্ত সহ একটি লুপে প্রক্রিয়া করা হয় $#। এই শর্তটি ততক্ষণ সত্য, যতক্ষণ আর্গুমেন্টের সংখ্যা শূন্যের চেয়ে বেশি। $1পরিবর্তনশীল এবং shiftবিবৃতি প্রক্রিয়া প্রতিটি যুক্তি। প্রতিটি সময় shiftসম্পাদন করার পরে আর্গুমেন্টের সংখ্যা হ্রাস হয় এবং শেষ পর্যন্ত শূন্য হয়ে যায়, যার উপর দিয়ে whileলুপটি প্রস্থান করে। উত্স
সার্জ স্ট্রোব্যান্ড

অতিরিক্ত echo $1 | sedযুক্তি মূল্য প্রক্রিয়াকরণ সহ এখানে একটি অনুরূপ উদাহরণ ।
সার্জ Stroobandt

26

এটি আমার পক্ষে কাজ করেছে। এটি আপনি যা চেয়েছিলেন ঠিক তেমন করে এবং আরও কিছুই (কোনও বিকল্প প্রক্রিয়াজাতকরণ নয়)। এটি ভাল বা খারাপ পোস্টারটির জন্য অনুশীলন হোক :)

if [[ "$*" == *YOURSTRING* ]]
then
    echo "YES"
else
    echo "NO"
fi

এটি $* সুপার হ্যান্ডলিং এবং বাশ সুপার-পরীক্ষা [[... ]]বন্ধনীগুলির সুবিধা গ্রহণ করে ।


2
আইএমএইচও এটির সবচেয়ে সঠিক উত্তর হওয়া উচিত, যেহেতু প্রশ্নের কেবলমাত্র প্যারামিটারের উপস্থিতি পরীক্ষা করা দরকার। আমি সম্পাদনা করার পরে, তবে পরিবর্তন $*করতে $@, যেহেতু টু-করা-পরীক্ষিত স্ট্রিং এটি সম্পর্কে ব্যাশ এর ডকুমেন্টেশন স্পেস এবং যোগ লিংক থাকতে পারে।
h7r

9
আপনি কি = ~ অপারেটরটি ব্যবহার করবেন? অন্যথায় আমি দেখতে পাচ্ছি না কেন এটি কাজ করা উচিত এবং যখন আমি সঠিক স্ক্রিপ্টটি চেষ্টা করি তখন এটি কাজ করে না।
সেপ্পো এনারভি

3
কাজ করছে না. bash -c 'echo args=$*; [[ "$@" == "bar" ]] && echo YES || echo NO' -- foo bar
টোবিয়া

2
এটি সম্পূর্ণ যুক্তি তালিকার সাথে তুলনা করে your string। আমি মনে করি আপনার এই উত্তরটি দ্বারা প্রস্তাবিত যা করা দরকার তা করা উচিত । ie: bash -c 'echo args=$*; for i in "$@" ; do [[ $i == "bar" ]] && echo "Is set!" && break ; done' -- bar fooকাজ করবে।
স্টারফ্রি

2
এই উত্তরটি গত চার বছর ধরে ভুল হয়েছে কারণ h7r এর সম্পাদনাটি এটি ভেঙেছে। আসল উত্তর (যা আমি এখন পুনঃস্থাপন করেছি) কাজ করে, সরবরাহিত "আপনার স্ট্রিং" এ কোনও গ্লোব অক্ষর নেই এবং কিছু মিথ্যা ধনাত্মকতা রয়েছে। উদাহরণস্বরূপ, যদি কমান্ডটি হয় create a new certificateএবং "আপনার স্ট্রিং" হয় তবে এটি catএকটি মিলের প্রতিবেদন করবে কারণ certificate এতে রয়েছে cat
স্কট

8

কীভাবে অনুসন্ধান করতে হবে (ওয়াইল্ডকার্ড সহ) পুরো প্যারামিটার স্পেস:

if [[ $@ == *'-disableVenusBld'* ]]
then

সম্পাদনা: ঠিক আছে, ঠিক আছে, তাই এটি একটি জনপ্রিয় উত্তর ছিল না। এটি সম্পর্কে কীভাবে, এটি নিখুঁত!:

if [[ "${@#-disableVenusBld}" = "$@" ]]
then
    echo "Did not find disableVenusBld"
else
    echo "Found disableVenusBld"
fi

সম্পাদনা 2: ঠিক আছে, ঠিক আছে, সম্ভবত এটি নিখুঁত নয় ... ভাবুন এটি কেবল তখনই কাজ করে যদি -প্রেম তালিকার শুরুতে থাকে এবং মিলবে -প্রেমএক্সজেডওয়াই বা -প্রেমএবসিও। আমি এখনও মনে করি বাশ স্ট্রিং ম্যানিপুলেশন দিয়ে মূল সমস্যাটি খুব সুন্দরভাবে সমাধান করা যেতে পারে, তবে আমি এখানে এটিকে খুব একটা ফাটানো হয়নি ... -ক্যান ??


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

দ্বিতীয় পরামর্শ (বিশেষত ${@#) কী করে তা ব্যাখ্যা করতে পারেন?
উলফ

1
@ বিফোর অবশ্যই! সুতরাং আপনি কি জানেন যে $@একটি বিশেষ পরিবর্তনশীল যা কমান্ড লাইনের সমস্ত আর্গুমেন্ট ধারণ করে? ওয়েল আমি "পরিবর্তনযোগ্যভেদসবেল্ড" সাবস্ট্রিংটি সরাতে সেই পরিবর্তনশীলটিতে সবেমাত্র ব্যাশ স্ট্রিং ম্যানিপুলেশন ব্যবহার করেছি, এবং তারপরে আমি এটিকে মূলের সাথে তুলনা করি $@। সুতরাং যদি $@সমান হয় -foo -barতবে ${@#-disableVenusBld}এখনও -foo -barতাই, তাই আমি দেখতে পাচ্ছি যে আমি যে পতাকাটি খুঁজছি তা উপস্থিত নেই present যাইহোক, যদি $@সমান -foo -disableVenusBld -barতারপর ${@#-disableVenusBld}হবে -foo -barযা সমান নয় $@, এইভাবে আমাকে বলছে যে পতাকা আমি চাই উপস্থিত! কুল!
ধনী

@ লিফ্ট এখানে বাশ স্ট্রিংয়ের হেরফের সম্পর্কে আরও জানুন: tldp.org/LDP/abs/html/string-manipulation.html
ধনী

@ ধীরে ধীরে সুন্দর ^^, ব্যাখ্যার জন্য ধন্যবাদ।
velop

4
disCopperBld=
for x; do
  if [ "$x" = "-disCopperBld" ]; then disCopperBld=1; break; fi
done
if [ -n "$disCopperBld" ]; then
  ...
fi

আপনার যদি কেবলমাত্র প্যারামিটারগুলি শুরু করে পরীক্ষা $3করতে হয় তবে কোনও ফাংশনে অনুসন্ধান করুন:

## Usage: search_trailing_parameters NEEDLE NUM "$@"
## Search NEEDLE amongst the parameters, skipping $1 through ${$NUM}.
search_trailing_parameters () {
  needle=$1
  shift $(($2 + 2))
  for x; do
    if [ "$x" = "$needle" ]; then return 0; fi
  done
  return 1
}
if search_trailing_parameters -disCopperBld 2 "$@"; then
  ...
fi

তবে আমি অবাক হয়েছি কেন আপনি প্রথমে এটি করার চেষ্টা করছেন, এটি সাধারণ চাহিদা নয়। সাধারণত, আপনি পূর্ববর্তী প্রশ্নের ডেনিসের জবাব অনুসারে বিকল্পগুলি ক্রমে প্রক্রিয়া করতেন ।

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