কোনও ব্যাশ ভেরিয়েবল খালি কিনা তা কীভাবে নির্ধারণ করবেন?


765

ব্যাশে কোনও চলক খালি ("") খালি থাকলে তা নির্ধারণ করার সর্বোত্তম উপায় কী?

আমি শুনেছি যে এটি করার পরামর্শ দেওয়া হয় if [ "x$variable" = "x" ]

এটা কি সঠিক উপায়? (আরও কিছু সরলভাবে থাকতে হবে)


উত্তর:


1053

যদি কোনও ভেরিয়েবলটি সেট না করা হয় বা খালি স্ট্রিং ("") এ সেট করা হয় তবে এটি সত্য হবে।

if [ -z "$VAR" ];

14
যদি কোনও ভেরিয়েবল "" এর মানতে সেট করে তবে কী এতে অন্তর্ভুক্ত রয়েছে?
ব্রেন্ট

11
হ্যাঁ এটি একটি শূন্য দৈর্ঘ্যের স্ট্রিংয়ের জন্য "-z" পরীক্ষা করে।
ডেভিড জেড

91
if [ ! -z "$VAR" ];
অ্যারন কোপলি

263
বিপরীতটি -zহল-n if [ -n "$VAR" ];
ফিলিপ আলভারেজ

19
ডাবল উদ্ধৃতিগুলি নিশ্চিত করে যে ভেরিয়েবলটি বিভক্ত না হয়। $varএকটি কমান্ড লাইনের একটি সরল তার সাদা স্থান দ্বারা পরামিতিগুলির তালিকায় বিভক্ত "$var"হবে , যখন সর্বদা কেবলমাত্র একটি পরামিতি থাকবে। ভেরিয়েবলগুলি উদ্ধৃত করা প্রায়শই একটি ভাল অনুশীলন এবং হোয়াইটস্পেস (অন্যান্য জিনিসগুলির মধ্যে) সম্বলিত ফাইলের নামগুলিতে ট্রিপ করা থেকে বিরত থাকে। উদাহরণ: করার পরে a="x --help", চেষ্টা করুন cat $a- এটি আপনাকে সহায়তা পৃষ্ঠা দেবে cat। তারপরে চেষ্টা করুন cat "$a"- এটি (সাধারণত) বলবে cat: x --help: No such file or directory। সংক্ষেপে, প্রায়শই উদ্ধৃতি এবং প্রায়শই উদ্ধৃতি এবং আপনি এটির জন্য প্রায় কখনও অনুশোচনা করবেন না।
স্কোর_উন্ডারে

247

বাশ-এ, যখন আপনি শেলগুলি সমর্থন করে না এমন বহনযোগ্যতার বিষয়ে উদ্বিগ্ন নন, আপনার সর্বদা ডাবল-বন্ধনী বাক্য গঠন ব্যবহার করা উচিত:

নিম্নলিখিত যে কোনও:

if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]

বাশ-এ, ডাবল বর্গাকার বন্ধনী ব্যবহার করে, উদ্ধৃতিগুলি প্রয়োজনীয় নয়। আপনি একটি পরিবর্তনশীল যে জন্য পরীক্ষা প্রক্রিয়া সহজ করতে আছে একটি মান ধারণ করে:

if [[ $variable ]]

এই সিনট্যাক্সটি ksh (কমপক্ষে ksh93, যাইহোক) সাথে সামঞ্জস্যপূর্ণ। এটি খাঁটি পসিক্স বা শ বা ড্যাশের মতো পুরানো বোর্ন শেলগুলিতে কাজ করে না।

দেখুন আমার উত্তর এখানে এবং BashFAQ / 031 ডবল এবং একক বর্গাকার বন্ধনী মধ্যে পার্থক্য সম্পর্কে আরও তথ্যের জন্য।

কোনও ভেরিয়েবল নির্দিষ্টভাবে সেট না করা আছে কিনা তা পরীক্ষা করতে পারেন (খালি স্ট্রিং থেকে পৃথক হিসাবে):

if [[ -z ${variable+x} ]]

যেখানে "x" নির্বিচারে।

যদি আপনি জানতে চান যে কোনও ভেরিয়েবলটি নাল তবে আনসেট নয়:

if [[ -z $variable && ${variable+x} ]]

1
এটি if [[ $variable ]]আমার পক্ষে ভাল কাজ করেছে এবং set -uঅন্য প্রস্তাবিত সমাধানগুলির মধ্যে একটিরও এটির প্রয়োজন ছিল না ।
টিমু লেইস্তি

3
আমি মনে করি এটি গৃহীত উত্তরের চেয়ে ভাল।
কিড

2
আপনি কেন নন-পোর্টেবল বৈশিষ্ট্যটি সুপারিশ করছেন যখন এটি করার কোনও সুবিধা নেই?
অ্যালাস্টার ইরভিন

19
@ অ্যালাস্টারআইরভাইন: আমি আমার উত্তরের প্রথম বাক্যে বহনযোগ্যতার কথা উল্লেখ করেছি, প্রশ্নের শিরোনাম এবং শরীরে "ব্যাশ" শব্দটি রয়েছে এবং প্রশ্নটি বাঁশযুক্ত ব্যাশ , এবং ডাবল বন্ধনী কাঠামো বিভিন্ন উপায়ে সুস্পষ্ট সুবিধা প্রদান করে। ধারাবাহিকতা এবং রক্ষণাবেক্ষণের কারণে আমি ব্র্যাকেট শৈলীর মিশ্রণের পরামর্শ দিচ্ছি না। আপনার যদি সর্বাধিক, সর্বনিম্ন সাধারণ ডিনোমিনেটর বহনযোগ্যতা প্রয়োজন, তবে shব্যাশের পরিবর্তে ব্যবহার করুন। এটি সরবরাহ করে এমন বর্ধিত ক্ষমতাগুলির যদি আপনার প্রয়োজন হয় তবে ব্যাশ ব্যবহার করুন এবং এটি পুরোপুরি ব্যবহার করুন।
ডেনিস উইলিয়ামসন

2
@ ব্রুনো ব্রোনোস্কি: আমি সম্পাদনাটি ফিরিয়ে দিয়েছি। ;শেষে কোনও প্রয়োজন নেই । দ্য thenএ সব একটি সেমিকোলন ছাড়া পরবর্তী লাইনে হতে পারে।
ডেনিস উইলিয়ামসন

230

ব্যাশে একটি পরিবর্তনশীল (এবং যে কোনও POSIX- সামঞ্জস্যপূর্ণ শেল) তিনটি অবস্থার মধ্যে একটিতে হতে পারে:

  • সেট না
  • খালি স্ট্রিং সেট
  • একটি খালি খালি স্ট্রিং সেট

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

নীচে আপনি বিভিন্ন সম্ভাবনা পরীক্ষা করে দেখতে পারেন এবং এটি ব্যাশ বা কোনও পসিক্স-সামঞ্জস্যপূর্ণ শেলটিতে কাজ করে তার উদাহরণ নীচে দেওয়া হয়েছে:

if [ -z "${VAR}" ]; then
    echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
    echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
    echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
    echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
    echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
    echo "VAR is either unset or set to a non-empty string"
fi

এখানে একই জিনিস কিন্তু কার্যকর টেবিল আকারে:

                        +-------+-------+-----------+
                VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ]       | true  | true  | false     |
| [ -z "${VAR+set}" ]   | true  | false | false     |
| [ -z "${VAR-unset}" ] | false | true  | false     |
| [ -n "${VAR}" ]       | false | false | true      |
| [ -n "${VAR+set}" ]   | false | true  | true      |
| [ -n "${VAR-unset}" ] | true  | false | true      |
+-----------------------+-------+-------+-----------+

${VAR+foo}কনস্ট্রাক্ট খালি স্ট্রিং বিস্তৃতি যদি VARসেট না করা থাকে বা fooযদি VARকিছু সেট করা হয় (খালি স্ট্রিং সহ)।

${VAR-foo}কনস্ট্রাক্ট মূল্য বিস্তৃতি VARসেট (খালি স্ট্রিং সেট সহ) এবং যদি fooযদি সেট না। এটি ব্যবহারকারী-ওভারড্রিয়েবল ডিফল্ট প্রদানের জন্য দরকারী (উদাহরণস্বরূপ, ভেরিয়েবলটি কোনও কিছুতে সেট না ${COLOR-red}করা থাকলে ব্যবহার করতে বলে)।redCOLOR

কারণ [ x"${VAR}" = x ]প্রায়ই পরীক্ষা করিয়া একটি পরিবর্তনশীল পারেন সেট না থাকে বা খালি ছাড়া স্ট্রিং সেট জন্য সুপারিশ করা হয়, কারণ কিছু বাস্তবায়নের [কমান্ড (নামেও পরিচিত test) বগী হয়। যদি VARএমন কিছুতে সেট করা থাকে -n, তবে কিছু বাস্তবায়ন ভুল কাজ করবে যখন দেওয়া হবে [ "${VAR}" = "" ]কারণ প্রথম যুক্তিটি [ভুলভাবে -nঅপারেটর হিসাবে ব্যাখ্যা করা হয়েছে , স্ট্রিং নয়।


3
খালি স্ট্রিংয়ে কোনও ভেরিয়েবল সেটের জন্য টেস্টিং ব্যবহার করেও করা যেতে পারে [ -z "${VAR-set}" ]
nwellnhof

@ ননহ্নহফ: ধন্যবাদ! আমি আমার উত্তরটি ব্রিফার সিনট্যাক্সটি ব্যবহার করার জন্য আপডেট করেছি।
রিচার্ড হ্যানসেন

প্রথম এবং শেষ নির্মাণের মধ্যে পার্থক্য কী? তারা উভয়ই "ভিএআর হয় সেট না করে সেট করা হয় বা একটি শূন্য খালি স্ট্রিংয়ে সেট করা হয়" to
ফাহিম মিঠা

1
@ ফাহিমমিঠা: এটি আপনার দোষ নয় - আমার উত্তরটি পড়া শক্ত ছিল। আশা করি উত্তরটি আরও পরিষ্কার করার জন্য আমি একটি টেবিল যুক্ত করেছি।
রিচার্ড হ্যানসেন

2
আনসেট পরীক্ষাগুলি নির্ভরযোগ্য নয়। যদি ব্যবহারকারী ফোন করে set -uবা set -o nounsetব্যাশে, তবে পরীক্ষার ফলস্বরূপ "ব্যাশ: ভিএআর: আনবাউন্ড ভেরিয়েবল" ত্রুটি হবে। আরও নির্ভরযোগ্য আনসেট চেকটির জন্য stackoverflow.com/a/13864829 দেখুন । কোনও চলক নাল বা আনসেট করা আছে কিনা তা পরীক্ষা করে দেখার জন্য আমার যেতে হবে [ -z "${VAR:-}" ]। ভেরিয়েবলটি খালি নয় কিনা তা সম্পর্কে আমার চেক [ "${VAR:-}" ]
কেভিন জিন

38

-z একটি সেরা উপায়।

আমি ব্যবহার করেছি আরেকটি বিকল্প হ'ল একটি ভেরিয়েবল সেট করা, তবে এটি অন্য ভেরিয়েবলের মাধ্যমে ওভাররাইড করা যায়

export PORT=${MY_PORT:-5432}

যদি $MY_PORTভেরিয়েবলটি খালি থাকে, তবে PORT5432 এ সেট হয়ে যাবে, অন্যথায় PORT এর মানতে সেট করা আছে MY_PORT। লক্ষণীয় বাক্যটিতে কোলন এবং ড্যাশ অন্তর্ভুক্ত রয়েছে।


দুর্ঘটনাক্রমে আজ এটি খুঁজে পেয়েছিল এবং এটি আমি যা চেয়েছিলাম ঠিক তা হয়েছিল। ধন্যবাদ! set -o nounsetকিছু স্ক্রিপ্টে আমাকে সহ্য করতে হবে ।
অপ্লোলো

24

আপনি যদি সেট-ফাঁকা বনাম আনসেট স্থিতির ক্ষেত্রে আলাদা করতে আগ্রহী হন তবে ব্যাশের জন্য -u বিকল্পটি দেখুন:

$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR

$ [ -z "$BAR" ] && echo true
true

8

আমি যে বিকল্পটি দেখেছি তা [ -z "$foo" ]হ'ল নিম্নরূপ, তবে আমি নিশ্চিত নই কেন লোকেরা এই পদ্ধতিটি ব্যবহার করে, কেউ জানেন?

[ "x${foo}" = "x" ]

যাইহোক আপনি যদি আনসেট ভেরিয়েবলগুলি (হয় set -uবা তা দ্বারা set -o nounset) অস্বীকার করছেন তবে আপনি এই দুটি পদ্ধতির সাথেই সমস্যায় পড়বেন। এটির জন্য একটি সহজ ফিক্স রয়েছে:

[ -z "${foo:-}" ]

দ্রষ্টব্য: এটি আপনার পরিবর্তনশীল অপরিবর্তিত থাকবে।


3
Pubs.opengroup.org/onlinepubs/009695399/utilities/test.html-z এ বিকল্প সম্পর্কে একটি মন্তব্য আছে । মূলত, এটি বিকল্প হিসাবে বোঝানো হয়নি । বরং ক্ষেত্রে যেখানে পরিচালনা কিছু metacharacter যে শুরু থেকে প্রসারিত করতে পারে বা দ্বারা বিভ্রান্ত করা হবে। শুরুতে একটি নির্বিচারে অ-মেটাচার্যাক্টর স্থাপন করা সেই সম্ভাবনাটি সরিয়ে দেয়। -z$foo[test
জেমস স্নেরিংগার

6

প্রশ্ন জিজ্ঞেস করে একটি পরিবর্তনশীল একটি খালি স্ট্রিং কিনা চেক করতে কিভাবে এবং সেরা উত্তর ইতিমধ্যে যে জন্য দেওয়া হয়।
পিএইচপি প্রোগ্রামিং পাস করার পরে আমি এখানে পৌঁছেছিলাম এবং আমি যা অনুসন্ধান করছিলাম তা হল পিএইচপি খালি ফাংশনের মতো একটি ব্যাশ শেলের মধ্যে কাজ করার মতো একটি চেক ।
উত্তরগুলি পড়ার পরে আমি বুঝতে পেরেছিলাম আমি বাশ সম্পর্কে সঠিকভাবে চিন্তা করছি না, তবে কোনওভাবেই এই মুহুর্তে পিএইচপি খালি মতো কোনও ফাংশন আমার ব্যাশ কোডে খুব সুন্দর হয়ে উঠবে।
যেহেতু আমি মনে করি এটি অন্যের সাথেও ঘটতে পারে, আমি পিএইচপি খালি ফাংশনটিকে ব্যাশে রূপান্তর করার সিদ্ধান্ত নিয়েছি পিএইচপি ম্যানুয়াল

অনুসারে :
একটি ভেরিয়েবলটি খালি বিবেচনা করা হয় যদি এটি বিদ্যমান না থাকে বা এর মান নিম্নলিখিতগুলির মধ্যে একটি হয়:

  • "" (একটি খালি স্ট্রিং)
  • 0 (একটি পূর্ণসংখ্যা হিসাবে 0)
  • 0.0 (ভাসা হিসাবে 0)
  • "0" (0 টি স্ট্রিং হিসাবে)
  • একটি খালি অ্যারে
  • একটি ভেরিয়েবল ঘোষিত, কিন্তু মান ছাড়াই

অবশ্যই নাল এবং মিথ্যা মামলাগুলি ব্যাশে রূপান্তর করা যায় না, তাই এগুলি বাদ দেওয়া হয়।

function empty
{
    local var="$1"

    # Return true if:
    # 1.    var is a null string ("" as empty string)
    # 2.    a non set variable is passed
    # 3.    a declared variable or array but without a value is passed
    # 4.    an empty array is passed
    if test -z "$var"
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is zero (0 as an integer or "0" as a string)
    elif [ "$var" == 0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is 0.0 (0 as a float)
    elif [ "$var" == 0.0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return
    fi

    [[ $( echo "" ) ]]
}



ব্যবহারের উদাহরণ:

if empty "${var}"
    then
        echo "empty"
    else
        echo "not empty"
fi



ডেমো:
নিম্নলিখিত স্নিপেট:

#!/bin/bash

vars=(
    ""
    0
    0.0
    "0"
    1
    "string"
    " "
)

for (( i=0; i<${#vars[@]}; i++ ))
do
    var="${vars[$i]}"

    if empty "${var}"
        then
            what="empty"
        else
            what="not empty"
    fi
    echo "VAR \"$var\" is $what"
done

exit

আউটপুট:

VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty

এই কথাটি বলার পরে যে কোনও ব্যাশ যুক্তিতে এই ফাংশনটিতে শূন্যের উপর চেকগুলি পার্শ্ব সমস্যা তৈরি করতে পারে imho, এই ফাংশনটি ব্যবহার করে যে কেউই এই ঝুঁকিটি মূল্যায়ন করতে পারে এবং কেবলমাত্র প্রথমটি রেখে এই চেকগুলি কেটে ফেলার সিদ্ধান্ত নিতে পারে।


ফাংশনের ভিতরে empty- আপনি সরল [[ $( echo "1" ) ]] ; returnপরিবর্তে কেন লিখলেন return 1?
ডোর

5

সম্পূর্ণ যদি-তবে এবং -z অপ্রয়োজনীয়।

["$ foo"] && প্রতিধ্বনি "ফু ফু নেই"
["$ ফু"] || প্রতিধ্বনি "ফু সত্যিই ফাঁকা"


2
Foo কোনও ড্যাশ দিয়ে শুরু হলে এটি কোনও বিকল্প হিসাবে ব্যাখ্যা হওয়ার পরে কিছু শেলগুলিতেও ব্যর্থ হবে। যেমন সোলারিস ksh , zsh এবং বাশ কোনও সমস্যা নেই, sh এবং / বিন / পরীক্ষা ব্যর্থ হবে
কেটিএফ

4

এটি ঠিক সত্য যখন set এফইও সেট করা হয় এবং খালি থাকে:

[ "${FOO+x}" = x ] && [ -z "$FOO" ]

4

ব্যক্তিগতভাবে চেক করার আরও সুস্পষ্ট উপায় পছন্দ করুন:

if [ "${VARIABLE}" == "" ]; then
  echo VARIABLE is empty
else
  echo VARIABLE is not empty
fi

1
কিছু শেল দ্বিগুণ সমান চিহ্নটি গ্রহণ করে না।
ডেনিস উইলিয়ামসন

1
প্রশ্ন ছিল বাশ সম্পর্কে। আমি ব্যাশ ব্যবহার করছি আমার জন্য ভাল কাজ করে। আপনি ঠিক কি সম্পর্কে বলছেন?
ফেদির আরওয়াইথটিক

2
আপনি যদি ব্যাশ ব্যবহার করছেন তবে আপনার ডাবল স্কোয়ার বন্ধনী ব্যবহার করা উচিত। আমার পূর্ববর্তী মন্তব্যটি তাদের উত্তরগুলির জন্য একটি সাধারণ বক্তব্য ছিল যারা আপনার উত্তরটি পড়তে পারে এবং কোনও আলাদা শেল ব্যবহার করতে পারে।
ডেনিস উইলিয়ামসন

একক বর্গাকার বন্ধনীগুলি এই ক্ষেত্রে ঠিক আছে, দয়া করে সার্ভারসফল্ট
লুকা বোররিওন


4

আমার 5 সেন্ট: এর চেয়ে একটি ছোট সংশ্লেষও রয়েছে if ...:

VALUE="${1?"Usage: $0 value"}"

যদি কোনও যুক্তি সরবরাহ করা হয়ে থাকে এবং কোনও ত্রুটির ক্ষেত্রে স্ক্রিপ্ট লাইন নম্বর সহ একটি ত্রুটি বার্তা প্রিন্ট করবে তবে (এবং স্ক্রিপ্টের কার্যকারিতাটি শেষ করবে) এই লাইনটি VALUE সেট করবে।

আর একটি উদাহরণ অ্যাবস-গাইডে পাওয়া যাবে («উদাহরণ 10-7» অনুসন্ধান করুন)।


0

সঠিক উত্তর নয়, তবে এই কৌশলটি ছড়িয়ে পড়ে। আপনি যে স্ট্রিংটির সন্ধান করছেন তা যদি একটি "কমান্ড" থেকে আসে তবে আপনি প্রকৃতপক্ষে কমান্ডটি একটি এনভির মধ্যে সংরক্ষণ করতে পারবেন। পরিবর্তনশীল এবং তারপরে এটি প্রতিবেদনের জন্য প্রতিবার কার্যকর করুন, তারপরে কোনও বন্ধনী প্রয়োজন নেই!

উদাহরণস্বরূপ এই কমান্ডটি নির্ধারণ করে যে আপনি ডিবিয়ান এ আছেন কিনা:

grep debian /proc/version

পুরো উদাহরণ:

IS_DEBIAN="grep -i debian /proc/version"

if $IS_DEBIAN; then
  echo 'yes debian'
else
  echo 'non debian'
fi

সুতরাং এটি খালি স্ট্রিং চেক করার জন্য একটি পরোক্ষ উপায়ের (এটি প্রতিবার পুনরায় পুনরুদ্ধার করার মতো) হয় (এটি কমান্ড থেকে ত্রুটির প্রতিক্রিয়া যাচাই করে দেখা যায়, তবে এটি একটি খালি স্ট্রিংও ফিরে আসবে)।

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