বাশ-এ কোনও ভেরিয়েবল সেট করা আছে কিনা তা কীভাবে পরীক্ষা করবেন?


1565

বাশে কোনও চলক সেট করা আছে তা আমি কীভাবে জানব?

উদাহরণস্বরূপ, ব্যবহারকারী কোনও ফাংশনে প্রথম প্যারামিটার দিয়েছিল কিনা তা আমি কীভাবে পরীক্ষা করব?

function a {
    # if $1 is set ?
}

12
if test $# -gt 0; then printf 'arg <%s>\n' "$@"; fi
জেনস

210
সমাধান-সন্ধানকারীদের জন্য দ্রষ্টব্য: এই প্রশ্নের অনেকগুলি উচ্চ-রেটযুক্ত উত্তর রয়েছে যা "এই পরিবর্তনশীল অ-খালি" প্রশ্নের উত্তর দেয়। আরও সংশোধন সমাধানগুলি ("ভ্যারিয়েবল সেট") নীচে জেনস এবং লিওনেলের উত্তরে উল্লিখিত হয়েছে।
নাথান কিড

8
এছাড়াও রাসেল হারমন এবং সিউমাস তাদের -vপরীক্ষার সাথে সঠিক , যদিও এটি আপাতদৃষ্টিতে কেবলমাত্র নতুন সংস্করণে পাওয়া যায় bashএবং শেলগুলি জুড়ে বহনযোগ্য নয়।
গ্রামীণ

5
@ নাথনকিড দ্বারা চিহ্নিত হিসাবে, সঠিক সমাধান লিওনেল এবং জেনস দ্বারা দেওয়া হয়। ভাল, আপনার এইগুলির মধ্যে একটিতে আপনার গৃহীত উত্তরটি স্যুইচ করা উচিত ।
গ্যারেট

3
... বা ভুল উত্তরটি আমাদের মধ্যে আরও বিচক্ষণতার দ্বারা অবনমিত হতে পারে, যেহেতু @ প্রসীক সমস্যাটির সমাধান করছেন না।
dan3

উত্তর:


2296

(সাধারণত) সঠিক উপায়

if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

যেখানে ${var+x}একটি হল প্যারামিটার সম্প্রসারণ যা কিছুই মূল্যায়ণ যদি varসেট না করা থাকে, এবং STRING কর্মের পরিবর্তে xঅন্যথায়।

উদ্ধৃতি ডিগ্রেশন

উদ্ধৃতিগুলি বাদ দেওয়া যেতে পারে (সুতরাং আমরা এর ${var+x}পরিবর্তে বলতে পারি "${var+x}") কারণ এই বাক্য গঠন এবং ব্যবহারের গ্যারান্টিটি এটি কেবল এমন কিছুতে প্রসারিত হবে যার উদ্ধৃতিগুলির প্রয়োজন নেই (যেহেতু এটি প্রসারিত হয় x(এতে কোনও শব্দ ভাঙা থাকে না যার জন্য কোনও উদ্ধৃতি প্রয়োজন নেই)) বা কিছুই নয় (যার ফলস্বরূপ [ -z ], যা স্বাচ্ছন্দ্যে একই মানকে মূল্যায়ণ করে (সত্য) যা [ -z "" ]তাও করে))।

যাইহোক, উদ্ধৃতিগুলি নিরাপদে বাদ দেওয়া যেতে পারে, এবং তা অবিলম্বে সবার কাছে স্পষ্ট ছিল না ( এই উদ্ধৃতি বিশ্লেষণের প্রথম লেখক যিনি একজন প্রধান বাশ কোডারও বটে, এটি এমনকি স্পষ্ট ছিল না ), সমাধানটি লেখার জন্য এটি কখনও কখনও আরও ভাল হত [ -z "${var+x}" ]ও (1) গতির দণ্ডের খুব সামান্য ব্যয় হিসাবে , উদ্ধৃতি সহ । প্রথম লেখক এই উত্তরটির URL টি প্রদান করে এই সমাধানটি ব্যবহার করে কোডের পাশে একটি মন্তব্য হিসাবে এটিকে যুক্ত করেছেন, যেখানে এখন উদ্ধৃতিগুলি কেন নিরাপদে বাদ দেওয়া যেতে পারে তার ব্যাখ্যাও অন্তর্ভুক্ত রয়েছে।

(প্রায়শই) ভুল উপায়

if [ -z "$var" ]; then echo "var is blank"; else echo "var is set to '$var'"; fi

এটি প্রায়শই ভুল কারণ এটি আনসেটযুক্ত এমন একটি চলক এবং খালি স্ট্রিংয়ে সেট করা একটি ভেরিয়েবলের মধ্যে পার্থক্য করে না। এর অর্থ হল, যদি var='', তবে উপরের সমাধানটি "var হয় ফাঁকা" আউটপুট দেয়।

আনসেট এবং "খালি স্ট্রিংয়ের কাছে সেট" এর মধ্যে পার্থক্যটি এমন পরিস্থিতিতে আবশ্যক যেখানে ব্যবহারকারীকে একটি এক্সটেনশন বা অতিরিক্ত বৈশিষ্ট্যের তালিকা নির্দিষ্ট করতে হবে এবং যেগুলি খালি শুল্কের ক্ষেত্রে তাদের ডিফল্ট নির্দিষ্ট করে না, যেখানে খালি স্ট্রিং উল্লেখ করা উচিত স্ক্রিপ্টটি খালি এক্সটেনশন বা অতিরিক্ত বৈশিষ্ট্যের তালিকা ব্যবহার করুন।

যদিও পার্থক্য প্রতিটি দৃশ্যে অপরিহার্য নাও হতে পারে। এই ক্ষেত্রে [ -z "$var" ]ঠিক জরিমানা হবে।


29
@ গ্যারেট, আপনার সম্পাদনাটি এই উত্তরটিকে ভুল করে তুলেছে, ${var+x}এটি ব্যবহারের সঠিক বিকল্প। ব্যবহারের [ -z ${var:+x} ]চেয়ে পৃথক ফলাফল উত্পাদন করে না [ -z "$var" ]
গ্রিম

11
এটি কাজ করে না। ভ্যারিয়াকে কোনও মান সেট করা আছে কিনা তা বিবেচনা না করেই আমি "সেট করা নেই" পাচ্ছি ("আনসেট ভার" দিয়ে সাফ করা হয়েছে, "প্রতিধ্বনি $ ভার" কোনও আউটপুট দেয় না)।
ব্রেন্ট 212

10
সমাধানের বাক্য গঠন {{পরামিতি + শব্দ For এর জন্য সরকারী ম্যানুয়াল বিভাগটি gnu.org/software/bash/manual/… ; তবে এর মধ্যে একটি বাগ, এটি খুব ভালভাবে এই বাক্যবিন্যাসের উল্লেখ করে না তবে কেবল উদ্ধৃতিটি বলেছে (কোলন ছাড়ানো [":"] ফলাফল কেবলমাত্র আনসেট না হওয়া প্যারামিটারের জন্য একটি পরীক্ষায় আসে .. {পরামিতি: + শব্দ} [অর্থ] যদি প্যারামিটারটি নাল বা সেট না করে থাকে তবে কিছুই প্রতিস্থাপন করা হয় না, না হলে শব্দের সম্প্রসারণের বিকল্প হয়)); উদ্ধৃত রেফ pubs.opengroup.org/onlinepubs/9699919799/utilities/… (জানা ভাল) এখানে অনেক পরিষ্কার ডক আছে।
ডেসটিনি আর্কিটেক্ট

7
দেখে মনে হচ্ছে কোট প্রয়োজন হয় যখন আপনি একাধিক এক্সপ্রেশন ব্যবহার করেন, যেমন [ -z "" -a -z ${var+x} ]পায় bash: [: argument expected-উবুন্টু 4.3 (কিন্তু যেমন zsh) ব্যাশ হবে। কিছু ক্ষেত্রে কাজের ক্ষেত্রে ঘটে এমন সিনট্যাক্স ব্যবহার করে উত্তরটি আমি সত্যিই অপছন্দ করি।
ফক্সফক্স

41
সরল [ -z $var ]ব্যবহারটি কোটেশন বাদ দেওয়া ছাড়া আর "ভুল" নয়। যেভাবেই হোক, আপনি নিজের ইনপুট সম্পর্কে অনুমান করছেন। যদি আপনি খালি স্ট্রিংটিকে আনসেট হিসাবে গণ্য করে থাকেন তবে [ -z $var ]আপনার যা প্রয়োজন তা হল।
ভাগ্নে

908

নন-নাল / নন-শূন্য স্ট্রিং ভেরিয়েবলের জন্য পরীক্ষা করতে, যদি সেট করা থাকে তবে ব্যবহার করুন

if [ -n "$1" ]

এর বিপরীত -z। আমি নিজেকে -nআরও বেশি ব্যবহার করে দেখতে পাই -z

আপনি এটি ব্যবহার করুন:

if [ -n "$1" ]; then
  echo "You supplied the first parameter!"
else
  echo "First parameter not supplied."
fi

86
আমি সাধারণত [[ ]]বেশি পছন্দ করি [ ], কারণ [[ ]]এটি আরও শক্তিশালী এবং নির্দিষ্ট পরিস্থিতিতে কম সমস্যা সৃষ্টি করে ( উভয়ের মধ্যে পার্থক্যের ব্যাখ্যা দেওয়ার জন্য এই প্রশ্নটি দেখুন )) প্রশ্নটি বিশেষত বাশ সমাধানের জন্য জিজ্ঞাসা করে এবং কোনও বহনযোগ্যতার প্রয়োজনীয়তা উল্লেখ করে না।
ফ্লো

18
প্রশ্নটি কীভাবে দেখা যায় যে কোনও ভেরিয়েবল সেট করা আছে কিনা । তারপর আপনি অনুমান করতে পারে না যে পরিবর্তনশীল হয় সেট।
হ্যালো গুডবাই

7
আমি সম্মত, []বিশেষ করে শেল (নন-ব্যাশ) স্ক্রিপ্টগুলির জন্য আরও ভাল কাজ করে।
হেনজি


63
নোট করুন -nএটি ডিফল্ট পরীক্ষা, তাই আরও সহজভাবে [ "$1" ]বা [[ $1 ]]পাশাপাশি কাজ করুন। এছাড়াও লক্ষ করুন যে [[ ]] উদ্ধৃতি সহ অপ্রয়োজনীয়
tne

477

প্যারামিটারটি সেট না করা , না খালি ("নাল") বা মান সহ সেট করা আছে কিনা তা এখানে পরীক্ষা করা যায় :

+--------------------+----------------------+-----------------+-----------------+
|   Expression       |       parameter      |     parameter   |    parameter    |
|   in script:       |   Set and Not Null   |   Set But Null  |      Unset      |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word}  | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word     | assign word     |
| ${parameter=word}  | substitute parameter | substitute null | assign word     |
| ${parameter:?word} | substitute parameter | error, exit     | error, exit     |
| ${parameter?word}  | substitute parameter | substitute null | error, exit     |
| ${parameter:+word} | substitute word      | substitute null | substitute null |
| ${parameter+word}  | substitute word      | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+

উত্স: পসিক্স: প্যারামিটার সম্প্রসারণ :

"বিকল্প" দিয়ে দেখানো সমস্ত ক্ষেত্রে, বর্ণটি প্রদর্শিত মানের সাথে প্রতিস্থাপন করা হয়। "অ্যাসাইন" দিয়ে দেখানো সমস্ত ক্ষেত্রে, প্যারামিটারটি সেই মানটি বরাদ্দ করা হয়, যা অভিব্যক্তিটিও প্রতিস্থাপন করে।

এটি কার্যকরভাবে দেখানোর জন্য:

+--------------------+----------------------+-----------------+-----------------+
|   Expression       |  FOO="world"         |     FOO=""      |    unset FOO    |
|   in script:       |  (Set and Not Null)  |  (Set But Null) |     (Unset)     |
+--------------------+----------------------+-----------------+-----------------+
| ${FOO:-hello}      | world                | hello           | hello           |
| ${FOO-hello}       | world                | ""              | hello           |
| ${FOO:=hello}      | world                | FOO=hello       | FOO=hello       |
| ${FOO=hello}       | world                | ""              | FOO=hello       |
| ${FOO:?hello}      | world                | error, exit     | error, exit     |
| ${FOO?hello}       | world                | ""              | error, exit     |
| ${FOO:+hello}      | hello                | ""              | ""              |
| ${FOO+hello}       | hello                | hello           | ""              |
+--------------------+----------------------+-----------------+-----------------+

5
@ হেলো গুডবাই হ্যাঁ এটি কাজ করে: set foo; echo ${1:-set but null or unset}ইকোস " ফু "; set --; echo ${1:-set but null or unset}প্রতিধ্বনি সেট হলেও নাল ...
জেনস

4
@ হেলো গুডবি, অবস্থানিক পরামিতিগুলি উহ, set:-) এর সাথে সেট করা যেতে পারে
জেনস

95
এই উত্তরটি খুব বিভ্রান্তিকর। এই টেবিলটি কীভাবে ব্যবহার করবেন সে সম্পর্কে কোনও ব্যবহারিক উদাহরণ?
বেন ডেভিস

12
@ বেনড্যাভিস পসিক্স স্ট্যান্ডার্ডের লিঙ্কে বিশদটি ব্যাখ্যা করা হয়েছে, যা সারণীটি নেওয়া হয়েছে সেই অধ্যায়টির উল্লেখ করে। আমি যে প্রায় কোনও স্ক্রিপ্টে ব্যবহার করি একটি কনস্ট্রাক্ট হ'ল : ${FOOBAR:=/etc/foobar.conf}ভেরিয়েবলের জন্য একটি ডিফল্ট মান সেট করা যদি এটি সেট না করে বা নাল হয়।
জেনস

1
parameterযে কোনও পরিবর্তনশীল নাম। wordআপনি যে টেবিলটি ব্যবহার করছেন সেটি কোন সিনট্যাক্সের উপর নির্ভর করে এবং পরিবর্তনশীল $parameterসেট, সেট কিন্তু নাল, বা আনসেট নয় তা নির্ভর করে বিকল্পের কিছু স্ট্রিং । জিনিসগুলিকে আরও জটিল করার জন্য নয়, তবে wordভেরিয়েবলগুলিও অন্তর্ভুক্ত করতে পারে! এটি একটি চরিত্র দ্বারা পৃথক alচ্ছিক আরোগুলি পাস করার জন্য খুব দরকারী হতে পারে। উদাহরণস্বরূপ: সেট করা থাকলেও শূন্য না থাকলে ${parameter:+,${parameter}}আলাদা কমা আলাদা করে আউটপুট দেয় ,$parameter। এই ক্ষেত্রে, wordহয়,${parameter}
TrinitronX

260

এখানে বর্ণিত বেশিরভাগ কৌশল সঠিক হলেও ব্যাশ ৪.২ ভেরিয়েবলের মান পরীক্ষা করার পরিবর্তে ভেরিয়েবলের ( ম্যান বাশ ) উপস্থিতির জন্য একটি আসল পরীক্ষা সমর্থন করে।

[[ -v foo ]]; echo $?
# 1

foo=bar
[[ -v foo ]]; echo $?
# 0

foo=""
[[ -v foo ]]; echo $?
# 0

উল্লেখযোগ্যভাবে, set -u/ set -o nounsetমোডে কোনও আনসেট ভেরিয়েবল পরীক্ষা করার জন্য ব্যবহার করার মতো অন্যান্য পদ্ধতির মত নয়, এই পদ্ধতির ফলে কোনও ত্রুটি ঘটবে না [ -z


9
4.1.2 বাশে, ভেরিয়েবল সেট করা নির্বিশেষে, [[ -v aaa ]]; echo $?==>-bash: conditional binary operator expected -bash: syntax error near 'aaa'
ড্যান

32
'পরীক্ষা' বিল্টিনে '-v' যুক্তি বাশ ৪.২ এ যুক্ত হয়েছিল।
তি স্টারগা

19
-v আর্গুমেন্টটি -u শেল বিকল্পের (nounset) পরিপূরক হিসাবে যুক্ত করা হয়েছিল। (নাম-সেট) চালু (সেট-ইউ) দিয়ে, শেলটি ত্রুটিটি ফিরিয়ে দেবে এবং যদি এটি ইন্টারেক্টিভ না হয় তবে সমাপ্ত হবে। অবস্থানগত পরামিতিগুলি পরীক্ষা করার জন্য checking # ভাল ছিল। যাইহোক, নামযুক্ত ভেরিয়েবলগুলি আনসেট হিসাবে চিহ্নিত করার জন্য ক্লোবার্বিং ছাড়া অন্য কোনও উপায়ে প্রয়োজন। দুর্ভাগ্যজনক যে এই বৈশিষ্ট্যটি এত দেরিতে এসেছে কারণ অনেকগুলি পূর্ববর্তী সংস্করণে সামঞ্জস্যপূর্ণ হতে বাধ্য, যে ক্ষেত্রে তারা এটি ব্যবহার করতে পারবেন না। কেবলমাত্র অন্য বিকল্পটি ট্রিকস বা 'হ্যাক' ব্যবহার করে উপরের মতো দেখানো হয়েছে তবে এটি সবচেয়ে অযোগ্য।
ওসিরিসগোথর

2
নোট করুন এটি ঘোষিত তবে আনসেট না হওয়া ভেরিয়েবলগুলির জন্য কাজ করে না। যেমনdeclare -a foo
মিকেন 32

17
এই কারণেই আমি গৃহীত / সর্বাধিক-ভোট প্রাপ্ত উত্তরগুলি পরে পড়া চালিয়ে যাচ্ছি।
জো

176

নিম্নলিখিতগুলির মধ্যে একটি হ'ল এটি করার অনেকগুলি উপায় রয়েছে:

if [ -z "$1" ]

এটি সফল হয় যদি $ 1 টি নাল বা আনসেট না করে থাকে


46
একটি আনসেট প্যারামিটার এবং নাল মান সহ একটি প্যারামিটারের মধ্যে পার্থক্য রয়েছে।
চিপনার

21
আমি কেবল প্যাডেন্টিক হতে চাই এবং এটিই উত্থাপন করতে চাই যা প্রশ্ন উত্থাপন করে তার বিপরীত উত্তর। প্রশ্নগুলি জিজ্ঞাসা করে যে ভেরিয়েবলটি সেট করা আছে কিনা, ভেরিয়েবলটি সেট করা নেই কিনা।
ফিলুমিনাতি

47
[[ ]]একটি বহনযোগ্যতা ক্ষতি ছাড়া কিছুই নয়। if [ -n "$1" ]এখানে ব্যবহার করা উচিত।
জেনস

73
এই উত্তরটি ভুল। প্রশ্নটি কোনও চলক সেট করা আছে কিনা তা বলার জন্য একটি উপায় জিজ্ঞাসা করে, এটি কোনও শূন্য নয় এমন মানতে সেট করা হয় কিনা। প্রদত্ত foo="", $fooএর একটি মান রয়েছে তবে -zকেবল এটি খালি বলে জানাবে। এবং -z $fooযদি আপনার গাট্টা হবে set -o nounset
কিথ থমসন

4
এটি "পরিবর্তনশীল সেট করা হয়" এর সংজ্ঞা উপর নির্ভর করে depends আপনি যদি ভেরিয়েবলটি নন-শূন্য স্ট্রিংয়ে সেট করা আছে কিনা তা পরীক্ষা করতে চান , তবে এমব্র্যানিংয়ের উত্তরটি সঠিক। তবে আপনি যদি ভেরিয়েবলটি ঘোষিত হয় তবে সূচনা হয় না (যেমন foo=) তবে তা পরীক্ষা করতে চান , তবে রাসেলের উত্তরটি সঠিক।
ফ্লো

76

আমি সর্বদা পসিক্স সারণীটি উত্তরের উত্তরগুলিতে সর্বদা কুঁচকে ধীরে ধীরে পাই so

   +----------------------+------------+-----------------------+-----------------------+
   |   if VARIABLE is:    |    set     |         empty         |        unset          |
   +----------------------+------------+-----------------------+-----------------------+
 - |  ${VARIABLE-default} | $VARIABLE  |          ""           |       "default"       |
 = |  ${VARIABLE=default} | $VARIABLE  |          ""           | $(VARIABLE="default") |
 ? |  ${VARIABLE?default} | $VARIABLE  |          ""           |       exit 127        |
 + |  ${VARIABLE+default} | "default"  |       "default"       |          ""           |
   +----------------------+------------+-----------------------+-----------------------+
:- | ${VARIABLE:-default} | $VARIABLE  |       "default"       |       "default"       |
:= | ${VARIABLE:=default} | $VARIABLE  | $(VARIABLE="default") | $(VARIABLE="default") |
:? | ${VARIABLE:?default} | $VARIABLE  |       exit 127        |       exit 127        |
:+ | ${VARIABLE:+default} | "default"  |          ""           |          ""           |
   +----------------------+------------+-----------------------+-----------------------+

নোট করুন যে প্রতিটি গ্রুপে (পূর্ববর্তী কোলন সহ এবং তার বাইরেও) একই সেট এবং আনসেট করা মামলা রয়েছে, তাই খালি মামলাগুলি কীভাবে পরিচালনা করা হয় তা কেবলমাত্র পৃথক হওয়া বিষয় ।

পূর্ববর্তী কোলনের সাথে, খালি এবং আনসেট করা মামলাগুলি অভিন্ন, তাই আমি যেখানে সম্ভব সেখানে ব্যবহার করব (যেমন ব্যবহার করুন :=, কেবল নয় =, কারণ খালি ক্ষেত্রেটি বেমানান)।

শিরোনাম:

  • সেট মানে VARIABLEখালি নয় ( VARIABLE="something")
  • খালি মানে VARIABLEফাঁকা / নাল ( VARIABLE="")
  • আনসেটের অর্থ VARIABLEবিদ্যমান নেই ( unset VARIABLE)

মান:

  • $VARIABLE মানে ফলাফলটি ভেরিয়েবলের আসল মান।
  • "default" মানে ফলাফলটি প্রতিস্থাপনের স্ট্রিং সরবরাহ করা হয়েছিল।
  • "" মানে ফলাফলটি নাল (একটি খালি স্ট্রিং)।
  • exit 127 মানে স্ক্রিপ্টটি প্রস্থান কোড 127 দিয়ে চালানো বন্ধ করে দেয়।
  • $(VARIABLE="default")মানে ফলাফলটি ভেরিয়েবলের আসল মান এবং প্রদত্ত প্রতিস্থাপনের স্ট্রিংটি ভেরিয়েবলকে ভবিষ্যতের ব্যবহারের জন্য বরাদ্দ করা হয়।

1
আপনি কেবল আসল কোডিং ত্রুটিগুলি ঠিক করেছেন (ভেরিয়েবলগুলির সাথে কাজ করার সময় অযাচিত ইন্ডিরেশনের উদাহরণ)। আমি আরও কয়েকটি কেস ঠিক করার জন্য একটি সম্পাদনা করেছি যেখানে ডলার বর্ণনার ব্যাখ্যায় কোনও পার্থক্য তৈরি করে। বিটিডাব্লু, সমস্ত শেল ভেরিয়েবল (অ্যারে বাদে) স্ট্রিং ভেরিয়েবল; এটি কেবল ঘটতে পারে যে তাদের একটি স্ট্রিং রয়েছে যা একটি সংখ্যা হিসাবে ব্যাখ্যা করা যায়। স্ট্রিং সম্পর্কে কথা বলা শুধুমাত্র বার্তাটি কুয়াশাচ্ছন্ন করে। উদ্ধৃতিগুলির স্ট্রিংগুলির সাথে কোনও সম্পর্ক নেই, এগুলি পালানোর কেবল একটি বিকল্প। VARIABLE=""হিসাবে লেখা যেতে পারে VARIABLE=। তবুও, প্রাক্তনটি আরও বেশি পঠনযোগ্য।
প্লেক

টেবিলের জন্য ধন্যবাদ এটি খুব দরকারী, তবে আমি সেট না করা বা খালি থাকলে স্ক্রিপ্টটি প্রস্থান করার চেষ্টা করছি। কিন্তু প্রস্থান কোড আমি পেতে 1 না 127.
মহাকাশচারী

64

কোনও ভেরিয়েবল কিছুই নয় কিনা তা দেখতে, আমি ব্যবহার করি

if [[ $var ]]; then ...       # `$var' expands to a nonempty string

বিপরীত পরীক্ষাগুলি যদি কোনও ভেরিয়েবলটি আনসেট বা খালি হয়:

if [[ ! $var ]]; then ...     # `$var' expands to the empty string (set or not)

কোনও ভেরিয়েবল সেট করা আছে কিনা তা দেখতে (খালি বা কিছুই নয়), আমি ব্যবহার করি

if [[ ${var+x} ]]; then ...   # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ...     # Parameter 1 exists (empty or nonempty)

বিপরীত পরীক্ষাগুলি যদি কোনও ভেরিয়েবলটি সেট না করা হয়:

if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ...   # We were called with no arguments

আমিও কিছুক্ষণের জন্য এটি ব্যবহার করে আসছি; কেবলমাত্র একটি হ্রাস উপায়ে:[ $isMac ] && param="--enable-shared"

@Bhaskar আমি মনে করি কারণ এটা এই উত্তরটি ইতিমধ্যে মূলত একই উত্তর (ব্যবহারের প্রদান ${variable+x}পেতে xiff $variableপ্রায় অর্ধেক একটি বছর আগে সেট)। এটি কেন সঠিক তা ব্যাখ্যা করে আরও অনেক বিশদ রয়েছে।
মার্ক হাফারক্যাম্প

তবে ${variable+x}কম পঠনযোগ্য (এবং স্পষ্ট)
09

35

বাশের আধুনিক সংস্করণে (৪.২ বা তার পরে আমি মনে করি; আমি নিশ্চিতভাবে জানি না), আমি এটি চেষ্টা করব:

if [ ! -v SOMEVARIABLE ] #note the lack of a $ sigil
then
    echo "Variable is unset"
elif [ -z "$SOMEVARIABLE" ]
then
    echo "Variable is set to an empty string"
else
    echo "Variable is set to some string"
fi

5
এছাড়াও খেয়াল করুন যে [ -v "$VARNAME" ]এটি ভুল নয়, তবে কেবল একটি ভিন্ন পরীক্ষা করে। ধরুন VARNAME=foo; তারপরে এটি পরীক্ষা করা আছে fooযে নাম নির্ধারিত কোনও ভেরিয়েবল আছে কিনা ।
চিপনার

5
যাঁরা বহনযোগ্যতা চান তাদের জন্য দ্রষ্টব্য, -v
পসিক্স

যদি কেউ পায় [: -v: unexpected operatorতবে তার bashপরিবর্তে ব্যবহার নিশ্চিত করতে হবে sh
কোপ্পার

25
if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

যদিও যুক্তিগুলির জন্য সাধারণত আমার মতে $ # পরীক্ষা করা ভাল, যা আর্গুমেন্টের সংখ্যা।

if [ $# -gt 0 ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

1
প্রথম পরীক্ষা পিছিয়ে; আমি মনে করি আপনি [ "$1" != "" ](বা [ -n "$1" ]) চান ...
গর্ডন ডেভিসন

10
$1খালি স্ট্রিংতে সেট করা থাকলে এটি ব্যর্থ হবে ।
হ্যালো গুডবাই

2
উত্তরের দ্বিতীয় অংশ (গণনা পরামিতি) হ'ল উত্তরের প্রথম অংশটি যখন $1খালি স্ট্রিংয়ের সাথে সেট করা হয় তখন কাজ না করে for
মার্ক বেরি

চালু থাকলে এটি ব্যর্থ হবে set -o nounset
ফ্লিম

21

বিঃদ্রঃ

আমি bashট্যাগের কারণে একটি ভারী বাশ-কেন্দ্রিক উত্তর দিচ্ছি ।

সংক্ষিপ্ত উত্তর

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

variable-is-set() {
    declare -p "$1" &>/dev/null
}

কেন এই কাজ করে

বাশ-এ (কমপক্ষে 3.0.০ হিসাবে ফিরে), যদি varঘোষিত / সেট ভেরিয়েবল হয়, তবে declare -p varএকটি declareকমান্ড আউটপুট varদেয় যা তার বর্তমান ধরন এবং মান যাই হোক না কেন তার পরিবর্তনশীল সেট করে এবং স্থিতি কোড 0(সাফল্য) দেয় returns যদি varঅঘোষিত থাকে, তবে এতে declare -p varত্রুটি বার্তা আউটপুট দেয় stderrএবং স্থিতি কোডটি দেয় 1। ব্যবহার করে &>/dev/null, নিয়মিত stdoutএবং stderrআউটপুট উভয়ই পুনর্নির্দেশ করে /dev/null, কখনও দেখা যায় না এবং স্থিতি কোডটি পরিবর্তন না করেই। সুতরাং ফাংশনটি কেবল স্থিতির কোডটি দেয়।

কেন অন্যান্য পদ্ধতি (কখনও কখনও) বাশে ব্যর্থ হয়

  • [ -n "$var" ]: এটি কেবল নিরপেক্ষ কিনা ${var[0]}তা পরীক্ষা করে । (ইন ব্যাশ, $varহিসাবে একই ${var[0]}।)
  • [ -n "${var+x}" ]: এটি ${var[0]}সেট করা আছে কিনা তা যাচাই করে।
  • [ "${#var[@]}" != 0 ]: অন্তত একটি সূচক $varসেট করা আছে কিনা এটি এটি পরীক্ষা করে।

এই পদ্ধতিটি যখন বাশে ব্যর্থ হয়

এটি কেবলমাত্র নামে ভেরিয়েবল (তত্সহ জন্য কাজ করে $_), না নির্দিষ্ট বিশেষ ভেরিয়েবল ( $!, $@, $#, $$, $*, $?, $-, $0, $1, $2, ..., এবং যে কোনো আমি ভুলে গেছি পারে)। এগুলির কোনওটি অ্যারে না হওয়ায়, পসিক্স-স্টাইল [ -n "${var+x}" ]এই সমস্ত বিশেষ ভেরিয়েবলের জন্য কাজ করে। তবে কোনও ফাংশনে এটি মোড়ানোর বিষয়ে সতর্ক থাকুন যেহেতু ফাংশন বলা হয় তখন অনেকগুলি বিশেষ ভেরিয়েবল মান / অস্তিত্ব পরিবর্তন করে change

শেল সামঞ্জস্য নোট

যদি আপনার স্ক্রিপ্টে অ্যারে রয়েছে এবং আপনি এটি যতটা সম্ভব শোলের সাথে সামঞ্জস্য করার চেষ্টা করছেন, তবে typeset -pপরিবর্তে ব্যবহার করার কথা বিবেচনা করুন declare -p। আমি পড়েছি যে ksh কেবলমাত্র প্রাক্তনকে সমর্থন করে তবে এটি পরীক্ষা করতে সক্ষম হয় নি। আমি জানি যে বাশ 3.0+ এবং জেডএস 5.5.1 উভয়ই উভয়কে সমর্থন করে typeset -pএবং declare -pকেবল আলাদা হয় যার মধ্যে একটির অপরের বিকল্প an তবে আমি এই দুটি কীওয়ার্ডের বাইরে পার্থক্য পরীক্ষা করেছি না এবং আমি অন্যান্য শেলও পরীক্ষা করে দেখিনি।

যদি আপনার স্ক্রিপ্টটি POSIX sh সাথে সামঞ্জস্যপূর্ণ হতে হয় তবে আপনি অ্যারে ব্যবহার করতে পারবেন না। অ্যারে, [ -n "{$var+x}" ]কাজ ছাড়া ।

বাশের বিভিন্ন পদ্ধতির জন্য তুলনা কোড

এই ফাংশনটি ভেরিয়েবলটি আনসেট করে var, evalপাস কোডটি, ডি কোড varদ্বারা সেট করা হয় কিনা তা নির্ধারণের জন্য পরীক্ষা চালায় evalএবং শেষ পর্যন্ত বিভিন্ন পরীক্ষার ফলাফলের স্থিতি কোডগুলি দেখায়।

আমি কুঁদন করছি test -v var, [ -v var ]এবং [[ -v var ]]কারণ তারা POSIX মান অভিন্ন ফলাফল উত্পাদ [ -n "${var+x}" ], ব্যাশ 4.2+ প্রয়োজন হয়। আমিও এড়িয়ে যাচ্ছি typeset -pকারণ এটি declare -pপরীক্ষা করা শেলগুলির মতোই রয়েছে (৫.০-এর মধ্য দিয়ে ৩.০ এবং জেএসএস ৫.৫.১) it's

is-var-set-after() {
    # Set var by passed expression.
    unset var
    eval "$1"

    # Run the tests, in increasing order of accuracy.
    [ -n "$var" ] # (index 0 of) var is nonempty
    nonempty=$?
    [ -n "${var+x}" ] # (index 0 of) var is set, maybe empty
    plus=$?
    [ "${#var[@]}" != 0 ] # var has at least one index set, maybe empty
    count=$?
    declare -p var &>/dev/null # var has been declared (any type)
    declared=$?

    # Show test results.
    printf '%30s: %2s %2s %2s %2s\n' "$1" $nonempty $plus $count $declared
}

পরীক্ষার কেস কোড

নোট করুন যে পরীক্ষার ফলাফলটি যদি অ্যাসোসিয়েটিভ অ্যারে হিসাবে ঘোষিত না করা হয় তবে "0" হিসাবে নন-সংখ্যাযুক্ত অ্যারে সূচকগুলি বিবেচনা করে বাশকে আচরণ করার কারণে পরীক্ষার ফলাফল অপ্রত্যাশিত হতে পারে। এছাড়াও, সহযোগী অ্যারেগুলি কেবল বাশ 4.0+-এ বৈধ।

# Header.
printf '%30s: %2s %2s %2s %2s\n' "test" '-n' '+x' '#@' '-p'
# First 5 tests: Equivalent to setting 'var=foo' because index 0 of an
# indexed array is also the nonindexed value, and non-numerical
# indices in an array not declared as associative are the same as
# index 0.
is-var-set-after "var=foo"                        #  0  0  0  0
is-var-set-after "var=(foo)"                      #  0  0  0  0
is-var-set-after "var=([0]=foo)"                  #  0  0  0  0
is-var-set-after "var=([x]=foo)"                  #  0  0  0  0
is-var-set-after "var=([y]=bar [x]=foo)"          #  0  0  0  0
# '[ -n "$var" ]' fails when var is empty.
is-var-set-after "var=''"                         #  1  0  0  0
is-var-set-after "var=([0]='')"                   #  1  0  0  0
# Indices other than 0 are not detected by '[ -n "$var" ]' or by
# '[ -n "${var+x}" ]'.
is-var-set-after "var=([1]='')"                   #  1  1  0  0
is-var-set-after "var=([1]=foo)"                  #  1  1  0  0
is-var-set-after "declare -A var; var=([x]=foo)"  #  1  1  0  0
# Empty arrays are only detected by 'declare -p'.
is-var-set-after "var=()"                         #  1  1  1  0
is-var-set-after "declare -a var"                 #  1  1  1  0
is-var-set-after "declare -A var"                 #  1  1  1  0
# If 'var' is unset, then it even fails the 'declare -p var' test.
is-var-set-after "unset var"                      #  1  1  1  1

টেস্ট আউটপুট

শিরোলেখ সারি মিলা পরীক্ষা স্মৃতিবর্ধনবিদ্যা করতে [ -n "$var" ], [ -n "${var+x}" ], [ "${#var[@]}" != 0 ], এবং declare -p varযথাক্রমে।

                         test: -n +x #@ -p
                      var=foo:  0  0  0  0
                    var=(foo):  0  0  0  0
                var=([0]=foo):  0  0  0  0
                var=([x]=foo):  0  0  0  0
        var=([y]=bar [x]=foo):  0  0  0  0
                       var='':  1  0  0  0
                 var=([0]=''):  1  0  0  0
                 var=([1]=''):  1  1  0  0
                var=([1]=foo):  1  1  0  0
declare -A var; var=([x]=foo):  1  1  0  0
                       var=():  1  1  1  0
               declare -a var:  1  1  1  0
               declare -A var:  1  1  1  0
                    unset var:  1  1  1  1

সারসংক্ষেপ

  • declare -p var &>/dev/null কমপক্ষে 3.0.০ থেকে বাশ-এ নামকরণের ভেরিয়েবল পরীক্ষা করার জন্য (100%?) নির্ভরযোগ্য?
  • [ -n "${var+x}" ] পসিএক্স অনুগত পরিস্থিতিতে নির্ভরযোগ্য তবে অ্যারে পরিচালনা করতে পারে না।
  • কোনও ভেরিয়েবলটি নমনীয় নয় কিনা তা পরীক্ষা করার জন্য এবং অন্যান্য শেলগুলিতে ঘোষিত ভেরিয়েবলগুলি পরীক্ষা করার জন্য অন্যান্য পরীক্ষাগুলি বিদ্যমান। তবে এই পরীক্ষাগুলি বাশ বা পোসিক্স স্ক্রিপ্টগুলির জন্য উপযুক্ত নয়।

3
আমি যে উত্তরগুলির চেষ্টা করেছি তার declare -p var &>/dev/nullমধ্যে এটি ( ) কেবলমাত্র একটি যা কাজ করে। ধন্যবাদ!
ব্যবহারকারী 1387866

2
@ চিহ্ন-হাফারক্যাম্প আপনার ফাংশন কোডটিতে সমালোচনামূলক পূর্ববর্তী "/" যুক্ত করার জন্য আমি আপনার উত্তর সম্পাদনা করার চেষ্টা করেছি যাতে এটি পড়ে ... &> /dev/nullতবে এসও আমাকে একটি অক্ষর সম্পাদনা করতে দেয় না 🙄 (অবশ্যই> 6 টি অক্ষর হতে পারে - এমনকি সাদা-স্পেস যুক্ত করার চেষ্টাও করেছিলেন তবে এটি কার্যকর হয়নি)। এছাড়াও, $1ভেরিয়েবল (উদাহরণস্বরূপ OUTPUT_DIR) নামক একটি নমুনার জন্য স্যুইচ আউট করার জন্য ফাংশনটি পরিবর্তনযোগ্য হতে পারে যেহেতু আপনি উল্লেখ করেছেন, বিশেষ ভেরিয়েবলগুলি $1এখানে কাজ করে না। যাইহোক, এটি একটি সমালোচনামূলক সম্পাদনা অন্যথায় কোডটি nullএকটি অপেক্ষাকৃত ডিরেক্টরিতে ডাকা একটি ফাইল তৈরি করতে চাইছে dev। বিটিডাব্লু - দুর্দান্ত উত্তর!
জোহান্না

এছাড়াও, $ উপসর্গ ব্যতীত ভেরিয়েবলের নাম ব্যবহার করাও কাজ করে: declare -p PATH &> /dev/null0 প্রদান করে যেখানে declare -p ASDFASDGFASKDF &> /dev/nullরিটার্ন 1। (বাশ 5.0.11 তে (1) রিরিজ)
জোহান্না

1
মহান কাজ! সতর্কতার 1 শব্দ: declare varএকটি পরিবর্তনশীল Var ঘোষণা কিন্তু এটা করে না পরিপ্রেক্ষিতে এটি সেট set -o nounset: সঙ্গে টেস্টdeclare foo bar=; set -o nounset; echo $bar; echo $foo
xebeche

@ জোহান্না যে অনুপস্থিত ধরার জন্য ধন্যবাদ /! আমি এটি স্থির করেছিলাম, তবে আমি মনে করি যুক্তিটি কোনও ক্রিয়াকলাপের জন্য যথেষ্ট পরিমাণে বিভ্রান্ত করছে, বিশেষত @ xebeche এর মন্তব্যের আলোকে। @xebeche এটি আমার উত্তরের জন্য অসুবিধাজনক… ... দেখে মনে হচ্ছে আমাকে declare -p "$1" | grep =বা এর মতো কিছু চেষ্টা করতে হবে test -v "$1"
মার্ক হাফার্ক্যাম্প

19

স্ক্রিপ্টের সাথে যখন আনসেট বা খালিটি পরীক্ষা করতে খুঁজছেন তাদের জন্য set -u:

if [ -z "${var-}" ]; then
   echo "Must provide var environment variable. Exiting...."
   exit 1
fi

নিয়মিত [ -z "$var" ]চেক ব্যর্থ হয়ে যাবে var; unbound variableযদি set -uকিন্তু [ -z "${var-}" ] বিস্তৃতি স্ট্রিং খালি যদি varব্যর্থ ছাড়া সেট করা থাকে না।


আপনি একটি কোলন অনুপস্থিত। এটা হওয়া উচিত ${var:-}, না ${var-}। তবে বাশে, আমি নিশ্চিত করতে পারি যে এটি কোলন ছাড়াও কাজ করে।
প্যালেক

3
${var:-}এবং ${var-}বিভিন্ন জিনিস বোঝাতে। ${var:-}যদি স্ট্রিং খালি প্রসারিত হবে varসেট না বা নাল এবং ${var-}শুধুমাত্র যদি সেট না খালি স্ট্রিং প্রসারিত হবে।
রুবেনলগুনা

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

17

এটি সেট না থাকলে আপনি প্রস্থান করতে চান

এটি আমার পক্ষে কাজ করেছে। আমি চেয়েছিলাম যে আমার স্ক্রিপ্টটি কোনও পরামিতিটি সেট না করা থাকলে একটি ত্রুটি বার্তা দিয়ে প্রস্থান করা হবে।

#!/usr/bin/env bash

set -o errexit

# Get the value and empty validation check all in one
VER="${1:?You must pass a version of the format 0.0.0 as the only argument}"

এটি চালানোর সময় এটি একটি ত্রুটি সহ ফিরে আসে

peek@peek:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument

কেবলমাত্র চেক করুন, কোনও প্রস্থান নেই - খালি এবং আনসেট অন্তর্ভুক্ত

এই বিকল্পটি ব্যবহার করে দেখুন আপনি যদি মান সেট = ভ্যালিড বা আনসেট / খালি = ইনভালিড কিনা তা পরীক্ষা করতে চান।

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
if [ "${TUNSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

বা, এমনকি সংক্ষিপ্ত পরীক্ষাগুলি ;-)

[ "${TSET:-}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY:-}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET:-}" ] && echo "VALID" || echo "INVALID"

কেবলমাত্র চেক করুন, কোনও প্রস্থান নেই - কেবল খালি ইনভ্যালিড

এবং এই প্রশ্নের উত্তর। আপনি যদি মান / সেট / খালি = VALID বা আনসেট = ইনভালিড সন্ধান করতে চান তবে এটি ব্যবহার করুন।

দ্রষ্টব্য, ".." 1 "" - 1} "তুচ্ছ, এটি কিছু হতে পারে (এক্স এর মতো)

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TUNSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

সংক্ষিপ্ত পরীক্ষা

[ "${TSET+1}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY+1}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET+1}" ] && echo "VALID" || echo "INVALID"

আমি এই উত্তরটি @ এমকিলেটমেন্ট 0 (মন্তব্য) এর কাছে উত্সর্গ করছি যারা আমাকে প্রশ্নের উত্তরটি নির্ভুলভাবে উত্তর দিতে চ্যালেঞ্জ করেছিল।

রেফারেন্স http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02


15

কোনও ভেরিয়েবলটি খালি-খালি মানের সাথে সেট করা আছে কিনা তা পরীক্ষা করতে [ -n "$x" ], অন্যরা ইতিমধ্যে নির্দেশিত হিসাবে ব্যবহার করুন ।

বেশিরভাগ সময়, কোনও ভেরিয়েবলের চিকিত্সা করা ভাল ধারণা যেটি একটি ভেরিয়েবলের মতো একইভাবে খালি মূল্য রয়েছে যা আনসেট নেই। আপনার যদি প্রয়োজন হয় তবে আপনি দুটি পার্থক্য করতে পারেন: [ -n "${x+set}" ]( সেট "${x+set}"করা setথাকলে প্রসারিত xএবং xআনসেট থাকলে খালি স্ট্রিংয়ে প্রসারিত )।

কোনও প্যারামিটার পাস হয়েছে কিনা তা পরীক্ষা করতে পরীক্ষা করুন $#যা কোন ফাংশনে (বা স্ক্রিপ্টে, কোনও ফাংশনে না থাকলে) পাস হওয়া প্যারামিটারের সংখ্যা ( পলের উত্তর দেখুন )।


14

bashম্যান পৃষ্ঠার "প্যারামিটার সম্প্রসারণ" বিভাগটি পড়ুন । প্যারামিটার সম্প্রসারণ কোনও ভেরিয়েবল সেট হওয়ার জন্য একটি সাধারণ পরীক্ষা সরবরাহ করে না, তবে প্যারামিটারটি সেট না করা থাকলে আপনি কিছু করতে পারেন।

উদাহরণ স্বরূপ:

function a {
    first_arg=${1-foo}
    # rest of the function
}

নির্ধারিত হলে এর first_argসমান সেট করবে $1, অন্যথায় এটি "foo" মানটি ব্যবহার করে। যদি aএকেবারে অবশ্যই একটি একক প্যারামিটার নিতে হয় এবং কোনও ভাল ডিফল্ট উপস্থিত না থাকে তবে কোনও পরামিতি দেওয়া না হলে আপনি একটি ত্রুটি বার্তা দিয়ে প্রস্থান করতে পারেন:

function a {
    : ${1?a must take a single argument}
    # rest of the function
}

( :নাল কমান্ড হিসাবে ব্যবহারটি নোট করুন , এটি কেবলমাত্র তার আর্গুমেন্টগুলির মানগুলি প্রসারিত করে। আমরা $1এই উদাহরণে কিছু করতে চাই না, সেট না করা থাকলে কেবল প্রস্থান করুন)


1
আমি বিস্মিত হয়েছি যে অন্য উত্তরগুলির মধ্যে কোনওটিই সহজ এবং মার্জিত উল্লেখ করে না : ${var?message}
ট্রিপলি

তুমি কোথা থেকে এলে? চমৎকার! এটা জাস্টা কাজ করে! এবং এটি সংক্ষিপ্ত এবং মার্জিত! ধন্যবাদ!
রজার

13

ব্যাশে আপনি বিল্টিনের -vভিতরে ব্যবহার করতে পারেন [[ ]]:

#! /bin/bash -u

if [[ ! -v SOMEVAR ]]; then
    SOMEVAR='hello'
fi

echo $SOMEVAR

8

ব্যবহার [[ -z "$var" ]]সহজ পদ্ধিতি হল উপায় জানতে যদি একটি পরিবর্তনশীল হয় বা না, কিন্তু যে বিকল্প -zএকটি সেট না পরিবর্তনশীল এবং একটি খালি স্ট্রিং একটি পরিবর্তনশীল সেট মধ্যে পার্থক্য করে না:

$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset" 
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset

ভেরিয়েবলের ধরণ অনুসারে এটি পরীক্ষা করা ভাল: এনভ ভেরিয়েবল, পরামিতি বা নিয়মিত ভেরিয়েবল।

একটি env পরিবর্তনশীল জন্য:

[[ $(env | grep "varname=" | wc -l) -eq 1 ]] && echo "Set" || echo "Unset"

একটি প্যারামিটারের জন্য (উদাহরণস্বরূপ, প্যারামিটারের অস্তিত্ব পরীক্ষা করা $5):

[[ $# -ge 5 ]] && echo "Set" || echo "Unset"

নিয়মিত পরিবর্তনশীল (একটি সহায়ক পদ্ধতিতে এটি একটি মার্জিত উপায়ে করতে) ব্যবহারের জন্য:

function declare_var {
   declare -p "$1" &> /dev/null
}
declare_var "var_name" && echo "Set" || echo "Unset"

মন্তব্য:

  • $#: আপনাকে অবস্থানগত পরামিতির সংখ্যা দেয়।
  • declare -p: আপনাকে প্যারামিটার হিসাবে পাস ভেরিয়েবলের সংজ্ঞা দেয়। যদি এটি বিদ্যমান থাকে তবে 0 প্রদান করে, যদি না হয় তবে 1 প্রদান করে এবং একটি ত্রুটি বার্তা প্রিন্ট করে।
  • &> /dev/null:declare -p এর রিটার্ন কোডকে প্রভাবিত না করে আউটপুটকে দমন করে ।

5

বাশ বিকল্পটি set -uসক্ষম থাকলে উপরের উত্তরগুলি কার্যকর হয় না । এছাড়াও, তারা গতিশীল নয়, উদাহরণস্বরূপ, "ডামি" নামের সাথে কীভাবে পরীক্ষার পরীক্ষা করা যায়? এটা চেষ্টা কর:

is_var_defined()
{
    if [ $# -ne 1 ]
    then
        echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
        exit 1
    fi
    # Tricky.  Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
    # is defined with this construct: [ ! -z "$var" ].  Instead, we must use default value
    # substitution with this construct: [ ! -z "${var:-}" ].  Normally, a default value follows the
    # operator ':-', but here we leave it blank for empty (null) string.  Finally, we need to
    # substitute the text from $1 as 'var'.  This is not allowed directly in Bash with this
    # construct: [ ! -z "${$1:-}" ].  We need to use indirection with eval operator.
    # Example: $1="var"
    # Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
    # Code  execute: [ ! -z ${var:-} ]
    eval "[ ! -z \${$1:-} ]"
    return $?  # Pedantic.
}

সম্পর্কিত: বাশ-এ, আমি কোনও ভেরিয়েবল "-u" মোডে সংজ্ঞায়িত করা হলে কীভাবে পরীক্ষা করব?


1
এই উত্তরটি কেন হ্রাস পেয়েছে তা আমি এতটা জানতে চাই ... আমার জন্য দুর্দান্ত কাজ করে।
লাভাস্কর্নেড ওভেন

ব্যাশ, আপনি একটি Eval ছাড়া একই কাজ করতে পারে: পরিবর্তন eval "[ ! -z \${$1:-} ]"পরোক্ষ মূল্যায়ন করুন: [ ! -z ${!1:-} ];

@ বাইনারিজেব্রা: আকর্ষণীয় ধারণা। আমি আপনাকে পৃথক উত্তর হিসাবে পোস্ট করার পরামর্শ দিচ্ছি।
কেভিনার্পে

"ইভাল" ব্যবহার করা এই সমাধানটিকে কোড ইনজেকশনের পক্ষে ঝুঁকিপূর্ণ করে তোলে: $ is_var_defised 'x}]; প্রতিধ্বনি "গেটচা"> & 2; # '
গেটচা

4

আপনি করতে পারেন:

function a {
        if [ ! -z "$1" ]; then
                echo '$1 is set'
        fi
}


1
আপনার চারপাশের কোট প্রয়োজন $1, অর্থাত [ ! -z "$1" ]। অথবা আপনি [[ ! -z $1 ]]bash / ksh / zsh এ লিখতে পারেন ।
গিলস 'অশুভ হওয়া বন্ধ করুন'

5
$1খালি স্ট্রিংতে সেট করা থাকলে এটি ব্যর্থ হবে ।
হ্যালো গুডবাই

4

আমার পছন্দের উপায়টি হ'ল:

$ var=10
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
is set
$ unset -v var
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
NOT set

সুতরাং মূলত, যদি কোনও ভেরিয়েবল সেট করা থাকে, তবে এটি "ফলাফলের অবহেলা" হয়ে যায় false(যা হবে true= "সেট করা হবে")।

এবং, যদি এটি সেট না করা হয়, এটি true"ফলাফলের একটি অবহেলা" হয়ে যাবে (খালি ফলাফলটি যেমন মূল্যায়ন করে true) (সুতরাং false= "সেট না হয়ে " শেষ হবে )।



1

শেলের মধ্যে আপনি -zঅপারেটরটি ব্যবহার করতে পারেন যা স্ট্রিংয়ের দৈর্ঘ্য শূন্য হলে সত্য।

সেট না করা থাকলে ডিফল্ট সেট করার জন্য একটি সাধারণ ওয়ান-লাইনার MY_VAR, অন্যথায় optionচ্ছিকভাবে আপনি বার্তাটি প্রদর্শন করতে পারেন:

[[ -z "$MY_VAR" ]] && MY_VAR="default"
[[ -z "$MY_VAR" ]] && MY_VAR="default" || echo "Variable already set."

0
if [[ ${1:+isset} ]]
then echo "It was set and not null." >&2
else echo "It was not set or it was null." >&2
fi

if [[ ${1+isset} ]]
then echo "It was set but might be null." >&2
else echo "It was was not set." >&2
fi

$1, $2এবং আপ $Nসর্বদা সেট করা হয়। দুঃখিত, এটি ব্যর্থ হয়েছে।

আমি চেষ্টা করেছিলাম, এবং এটি কার্যকর হয়নি, সম্ভবত আমার বাশ সংস্করণে এর জন্য সমর্থনটির অভাব রয়েছে। ইড্ক, আমি ভুল হলে দুঃখিত। :)

0

আপনি যদি কিছুতে যাচাই করতে চান তবে এটি করার জন্য আমি একটি (অনেক) আরও ভাল কোড পেয়েছি $@

যদি [[$ 1 = ""]]
তারপর
  প্রতিধ্বনি '$ 1 ফাঁকা'
আর
  প্রতিধ্বনি '$ 1 পূরণ হয়েছে'
ফাই

কেন এই সব? সবকিছু $@ব্যাশ বিদ্যমান, কিন্তু ডিফল্ট ভাবে এটা ফাঁকা, তাই test -zএবং test -nআপনাকে সাহায্য করতে পারে না।

আপডেট: আপনি পরামিতিগুলিতে অক্ষরের সংখ্যাও গণনা করতে পারেন।

যদি [$ {# 1} = 0]
তারপর
  প্রতিধ্বনি '$ 1 ফাঁকা'
আর
  প্রতিধ্বনি '$ 1 পূরণ হয়েছে'
ফাই

আমি জানি, কিন্তু এটি। যদি কিছু খালি থাকে তবে আপনি একটি ত্রুটি পাবেন! দুঃখিত। : পি

0
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi

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

0

এটি আমি প্রতিদিন ব্যবহার করি:

#
# Check if a variable is set
#   param1  name of the variable
#
function is_set()
{
    [[ -n "${1}" ]] && test -n "$(eval "echo "\${${1}+x}"")"
}

এটি লিনাক্স এবং সোলারিসের অধীনে 3.0 বাশাকে ভালভাবে কাজ করে।

bash-3.00$ myvar="TEST"
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ mavar=""
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ unset myvar
bash-3.00$ is_set myvar ; echo $?
1

1
যেহেতু বাশ ২.০+ অপ্রত্যক্ষ সম্প্রসারণ উপলব্ধ। আপনি test -n "$(eval "echo "\${${1}+x}"")"সমতুল্যের জন্য দীর্ঘ এবং জটিল (একটি অন্তর্ভুক্ত [[ ${!1+x} ]]

0

ব্যাশের অপরিশোধিত বিবরণ গোপন করার জন্য আমি সহায়ক ফাংশনগুলি পছন্দ করি। এই ক্ষেত্রে, এটি করা আরও বেশি (লুকানো) অদ্ভুততা যুক্ত করে:

# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
  local varname="$1"
  ! [ -z ${!varname+x} ]
}

যেহেতু আমার প্রথম এই প্রয়োগে বাগ ছিল (জেনস এবং লিওনেলের উত্তরগুলি দ্বারা অনুপ্রাণিত হয়েছিল), তাই আমি একটি পৃথক সমাধান নিয়ে এসেছি:

# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
  declare -p $1 &>/dev/null
}

আমি এটি আরও সোজা-এগিয়ে, আরও বাষ্পী এবং বুঝতে / মনে রাখা সহজ বলে মনে করি। পরীক্ষার ক্ষেত্রে এটি সমতুল্য দেখায়:

function main()
{
  declare -i xyz
  local foo
  local bar=
  local baz=''

  IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
  IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
  IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
  IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"

  IsDeclared xyz; echo "IsDeclared xyz: $?"
  IsDeclared foo; echo "IsDeclared foo: $?"
  IsDeclared bar; echo "IsDeclared bar: $?"
  IsDeclared baz; echo "IsDeclared baz: $?"
}

main

পরীক্ষার কেসটিও দেখায় যে var ঘোষণা local varকরে না ('=' অনুসরণ না করে)। বেশ কিছু সময়ের জন্য আমি ভেবেছিলাম যে আমি এইভাবে ভেরিয়েবলগুলি ঘোষণা করেছি, কেবল এখন আবিষ্কার করার জন্য যে আমি নিছক আমার অভিপ্রায় প্রকাশ করেছি ... এটি কোনও অনি-অপার, আমার ধারণা।

ইসড্যাক্লারেড_ট্রিকি xyz: 1
ইসডেক্লেয়ারড ট্রিকি ফু: 1
ইসড্যাক্লেয়ারড ক্রিটিক বার: 0
ইসডেক্লেয়ারড ক্রিটিক বাজ: 0
ইসড্যাক্লেয়ারড এক্সজি: 1
ইসড্যাক্লারেড foo: 1
ইসডিক্লার্ড বার: 0
ইসডিক্লার্ড বাজ: 0

বোনাস: ইউজকেস

কিছুটা "মার্জিত" এবং নিরাপদ উপায়ে (প্রায় একটি ইন্টারফেসের সাথে সাদৃশ্য ...) ফাংশনগুলিতে প্যারামিটারগুলি দেওয়ার (এবং প্রত্যাবর্তনের) জন্য আমি বেশিরভাগই এই পরীক্ষাটি ব্যবহার করি :

#auxiliary functions
function die()
{
  echo "Error: $1"; exit 1
}

function assertVariableDeclared()
{
  IsDeclared "$1" || die "variable not declared: $1"
}

function expectVariables()
{
  while (( $# > 0 )); do
    assertVariableDeclared $1; shift
  done
}

# actual example
function exampleFunction()
{
  expectVariables inputStr outputStr
  outputStr="$inputStr world!"
}

function bonus()
{
  local inputStr='Hello'
  local outputStr= # remove this to trigger error
  exampleFunction
  echo $outputStr
}

bonus

যদি সকলের সাথে ডাকা হয় তবে ভেরিয়েবলগুলি ঘোষণা করা দরকার:

ওহে বিশ্ব!

অন্য:

ত্রুটি: ভেরিয়েবল ঘোষিত হয়নি: আউটপুটএসটিআর


0

সমস্ত উত্তর skimming পরে, এটি কাজ করে:

if [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"

SOME_VARআমার কাছে যা আছে তার পরিবর্তে আপনি যদি তা না রাখেন তবে $SOME_VARএটি এটিকে একটি খালি মূল্য হিসাবে সেট করবে; $এটি কাজ করার জন্য প্রয়োজনীয়।


যখন আপনি set -uকার্যকর হয়ে যা unboud variableত্রুটিটি মুদ্রণ করবে তখন কাজ করবে না
মাইকেল হুবার্গার

-1

কোনও ভার সেট আছে কিনা তা পরীক্ষা করতে To

var=""; [[ $var ]] && echo "set" || echo "not set"

3
$varখালি স্ট্রিংতে সেট করা থাকলে এটি ব্যর্থ হবে ।
হ্যালো গুডবাই

-1

যদি আপনি পরীক্ষা করতে চান যে কোনও ভেরিয়েবলটি আবদ্ধ বা আনবাউন্ডেড নয়, আপনি নামটি বিকল্পটি চালু করার পরেও এটি ভালভাবে কাজ করে:

set -o noun set

if printenv variableName >/dev/null; then
    # variable is bound to a value
else
    # variable is unbound
fi

আমি মনে করি আপনি বোঝাতে চেয়েছেন set -o nounset, না set -o noun set। এটি কেবল exportসম্পাদিত ভেরিয়েবলগুলির জন্য কাজ করে । এটি আপনার সেটিংসটিকে এমনভাবে পরিবর্তন করে যেটিকে পূর্বাবস্থায় ফিরিয়ে আনার পক্ষে অবাস্তব।
কিথ থমসন

-1

আমি সর্বদা এটি ব্যবহার করি, এই প্রথম যে কোডটি প্রথমবারের মতো দেখেছে তার দ্বারা বোঝা সহজ বলে মনে করা হয়েছে তার ভিত্তিতে:

if [ "$variable" = "" ]
    then
    echo "Variable X is empty"
fi

এবং, খালি না কিনা তা পরীক্ষা করতে চাইলে;

if [ ! "$variable" = "" ]
    then
    echo "Variable X is not empty"
fi

এটাই.


4
প্রশ্নটি জিজ্ঞাসা করে যে কোনও ভেরিয়েবলটি খালি আছে কিনা তা স্থির করে কিনা তা পরীক্ষা করতে হয়।
হ্যালো গুডবাই

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