"Set -o nounset" ব্যবহার করার সময় ব্যাশটিতে কোনও চলক সেট করা আছে কিনা তা পরীক্ষা করুন


99

নিম্নলিখিত কোডটি একটি আনবাউন্ড ভেরিয়েবল ত্রুটি সহ প্রস্থান করে। কীভাবে এটি ঠিক করবেন, যখন এখনও set -oনামসূচক বিকল্পটি ব্যবহার করছেন ?

#!/bin/bash

set -o nounset

if [ ! -z ${WHATEVER} ];
 then echo "yo"
fi

echo "whatever"

উত্তর:


101
#!/bin/bash

set -o nounset


VALUE=${WHATEVER:-}

if [ ! -z ${VALUE} ];
 then echo "yo"
fi

echo "whatever"

এই ক্ষেত্রে, সেট না করা VALUEহলে খালি স্ট্রিং হয়ে শেষ WHATEVERহয়। আমরা {parameter:-word}সম্প্রসারণটি ব্যবহার করছি , যা আপনি man bash"প্যারামিটার সম্প্রসারণ" এর অধীনে সন্ধান করতে পারেন ।


15
শুধু প্রতিস্থাপন যদি [! -z $ AL মান}]; সাথে যদি [! -z $ {WHATVER: -}];
অ্যাঞ্জেলম

18
:-কিনা তা পরীক্ষা পরিবর্তনশীল সেট করা থাকে না বা খালি। আপনি যদি এটি সেট না করে কেবল তা পরীক্ষা করতে চান তবে -: ব্যবহার করুন VALUE=${WHATEVER-}। এছাড়াও, ভেরিয়েবলটি খালি কিনা তা যাচাই করার আরও একটি পঠনযোগ্য উপায়:if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
l0b0

4
এছাড়াও, $WHATEVERকেবল শ্বেতস্থান থাকলে এটি কাজ করবে না - আমার উত্তর দেখুন।
l0b0

11
! -zশুধু " -n" এর পরিবর্তে " " ব্যবহার করার কোনও কারণ আছে কি ?
জোনাথন হার্টলি

32

আপনি যে ফলাফলটি প্রত্যাশা করেছেন তা পেতে চাইলে আপনার ভেরিয়েবলগুলি উদ্ধৃত করতে হবে:

check() {
    if [ -n "${WHATEVER-}" ]
    then
        echo 'not empty'
    elif [ "${WHATEVER+defined}" = defined ]
    then
        echo 'empty but defined'
    else
        echo 'unset'
    fi
}

পরীক্ষা:

$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER='   '
$ check
not empty

আমি এই চেষ্টা এবং আমি বিস্মিত এই কাজ ... সবকিছু ব্যতীত অনুযায়ী সঠিক "info bash", "${WHATEVER-}"একটি থাকতে হবে ":"আগে (কোলন) "-": (ড্যাশ) -এর মত "${WHATEVER:-}", এবং "${WHATEVER+defined}"সামনে একটি কোলন থাকা উচিত "+"মত (প্লাস): "${WHATEVER:+defined}"। আমার জন্য, এটি কোলন সহ বা ছাড়া কোনও উপায়ে কাজ করে। 'নিক্সের কয়েকটি সংস্করণে এটি সম্ভবত কোলনকে অন্তর্ভুক্ত না করে কাজ করবে না, তাই সম্ভবত এটি যুক্ত করা উচিত।
কেভিন ফেগান

9
না, -, +, :+, এবং :-সব সমর্থিত। প্রাক্তন সনাক্ত করে যে ভেরিয়েবলটি সেট করা আছে কি না এবং পরবর্তীকালে এটি সেট বা খালি কিনা তা সনাক্ত করে । থেকে man bash: "কোলনকে ছাড় দেওয়া কেবলমাত্র এমন প্যারামিটারের পরীক্ষায় পরিণত হয় যা আনসেট হয় না।"
l0b0

4
কিছু নয়) আপনি সঠিক. আমি জানি না যে আমি কীভাবে মিস করেছি।
কেভিন ফেগান

দস্তাবেজগুলি থেকে : অন্য কোনও উপায়ে রাখুন, যদি কোলন অন্তর্ভুক্ত থাকে তবে অপারেটর উভয় প্যারামিটারের অস্তিত্বের জন্য পরীক্ষা করে এবং এর মানটি শূন্য হয় না; যদি কোলন বাদ দেওয়া হয় তবে অপারেটর কেবল অস্তিত্বের জন্য পরীক্ষা করে।
একিউম্যানাস

11

কীভাবে একজন অনন্যলাইনার?

[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"

-z খালি বা আনসেট ভেরিয়েবলের জন্য উভয় পরীক্ষা করে


4
না, -zকেবলমাত্র পরবর্তী প্যারামিটারটি খালি আছে কিনা তা পরীক্ষা করে দেখুন। -zএটি [কমান্ডের একটি যুক্তি মাত্র । [ -zকিছু করার আগে চলক প্রসারণ ঘটে ।
ডলম্যান

4
এটি সঠিক সমাধানের মতো বলে মনে হচ্ছে, $ VAR সেট না করা থাকলে এটি ত্রুটি উত্পন্ন করে না। @ ডলম্যান আপনি কখন উদাহরণস্বরূপ এটি কাজ করতে পারবেন না?
ক্রিস স্ট্রাইজিনস্কি

@ ডলম্যান প্যারাম বিস্তৃতি সম্পর্কে বিভিন্ন বাশ সংস্থান পড়েছেন এবং অন্যান্য উত্তরগুলি অতি জটিল বলে খুঁজে পেয়েছেন, আমি এগুলির কোনও কিছুই দেখছি না। সুতরাং প্রযুক্তিগতভাবে সঠিক হলেও আপনার "স্পেসিফিকেশন "টি অনুশীলনে বরং অর্থহীন বলে মনে হচ্ছে, যদি না খালি খালি আপনাকে সেট না করে আলাদা করতে হয়। আমি আনসেট, খালি এবং খালি-খালি পরীক্ষা করেছি (বাশ ৪) এবং প্রতিবার বিজ্ঞাপনে এটি বেশ কিছু করেছে।
জেএল পিয়েরেট

9

অনুমান:

$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset

যদি আপনি কোনও ত্রুটি ছাপানোর জন্য একটি অ-ইন্টারেক্টিভ স্ক্রিপ্ট চান এবং কোনও ভেরিয়েবলটি নাল হয় বা সেট না করা থেকে প্রস্থান করতে পারেন:

$ [[ "${HOME:?}" ]]

$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set

$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set

আপনি যদি স্ক্রিপ্টটি প্রস্থান করতে না চান:

$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."

$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

এমনকি আপনি ব্যবহার করতে পারেন [এবং ]পরিবর্তে [[এবং ]]উপরে, কিন্তু আধুনিক ব্যাশ মধ্যে বাঞ্ছনীয়।

কোলন উপরে কি করে তা লক্ষ করুন। ডক্স থেকে :

অন্য একটি উপায় রাখুন, যদি কোলন অন্তর্ভুক্ত করা হয়, অপারেটর উভয় প্যারামিটারের অস্তিত্বের জন্য পরীক্ষা করে এবং এর মানটি শূন্য হয় না; যদি কোলন বাদ দেওয়া হয় তবে অপারেটর কেবল অস্তিত্বের জন্য পরীক্ষা করে।

স্পষ্টতই এর প্রয়োজন নেই -nবা নেই -z

সংক্ষেপে, আমি সাধারণত কেবল ব্যবহার করতে পারি [[ "${VAR:?}" ]]উদাহরণস্বরূপ, এটি একটি ত্রুটি প্রিন্ট করে এবং যদি কোনও ভেরিয়েবল নাল হয় বা সেট না থাকে তবে প্রস্থান করে।


4

তুমি ব্যবহার করতে পার

if [[ ${WHATEVER:+$WHATEVER} ]]; then

কিন্তু

if [[ "${WHATEVER:+isset}" == "isset" ]]; then

আরও পঠনযোগ্য হতে পারে।


স্ট্রিং তুলনাগুলি স্ট্যান্ডার্ড (POSIX) =অপারেটরটি ব্যবহার করা উচিত , ==বহনযোগ্যতায় সহায়তা করার জন্য নয় এবং যদি সম্ভব হয় [তার পরিবর্তে [[
জেনস

4
@ জেনস প্রশ্নটি ব্যাশের সাথে সুনির্দিষ্ট এবং এতে ব্যাশের নির্দিষ্ট set -o nounsetযা অন্তর্ভুক্ত রয়েছে । আপনি যদি #!/bin/bashআপনার স্ক্রিপ্টের শীর্ষে রাখেন তবে বাশের বর্ধনগুলি ব্যবহার করা ভাল।
ব্রুনো ব্রোনোস্কি 25'17

0

যদিও এটি উপরে বর্ণিত ব্যবহারের ক্ষেত্রে ঠিক না , আমি খুঁজে পেয়েছি যে আপনি যদি nounset(বা -u) ডিফল্ট আচরণটি ব্যবহার করতে চান তবে একটি বর্ণনামূলক বার্তা সহ ননজারো থেকে বেরিয়ে আসুন।

এটি বুঝতে যথেষ্ট সময় লেগেছিল যে আমি বুঝতে পেরেছিলাম যে এটি সমাধান হিসাবে পোস্ট করার উপযুক্ত।

যদি আপনি যা চান তা হ'ল বাইরে বেরোনোর ​​সময় অন্য কিছু প্রতিধ্বনিত করা বা কিছু ক্লিনআপ করা, আপনি একটি ফাঁদ ব্যবহার করতে পারেন।

:-অপারেটর সম্ভবত কি আপনি অন্যথায় চাই।

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