বাশ-তে শূন্য-দৈর্ঘ্যের স্ট্রিংয়ের জন্য পরীক্ষা: [-n “$ var”] বা [“$ var”]


181

আমি শূন্য-দৈর্ঘ্যের স্ট্রিংয়ের জন্য বাশ স্ক্রিপ্টগুলি দুটি ভিন্ন উপায়ে দেখেছি। বেশিরভাগ স্ক্রিপ্টগুলি -nবিকল্পটি ব্যবহার করে :

#!/bin/bash
# With the -n option
if [ -n "$var" ]; then
  # Do something when var is non-zero length
fi

তবে -n বিকল্পটির সত্যই প্রয়োজন নেই:

# Without the -n option
if [ "$var" ]; then
  # Do something when var is non-zero length
fi

কোনটি ভাল উপায়?

একইভাবে, শূন্য-দৈর্ঘ্যের জন্য পরীক্ষার জন্য সর্বোত্তম উপায়:

if [ -z "$var" ]; then
  # Do something when var is zero-length
fi

অথবা

if [ ! "$var" ]; then
  # Do something when var is zero-length
fi

উত্তর:


393

সম্পাদনা: এটি একটি আরও সম্পূর্ণ সংস্করণ যা [(ওরফে test) এবং এর মধ্যে আরও পার্থক্য দেখায় [[

নিম্নলিখিত টেবিলটি দেখায় যে কোনও ভেরিয়েবল উদ্ধৃত হয়েছে কি না, আপনি একক বা ডাবল বন্ধনী ব্যবহার করুন কিনা এবং ভেরিয়েবলটিতে কেবল কোনও স্থান রয়েছে কিনা তা সেই পরীক্ষাগুলি দ্বারা প্রভাবিত হয় যা পরীক্ষার সাহায্যে পরীক্ষায় ব্যবহার করা উচিত কিনা তা প্রভাবিত করে -n/-z

     | 1a    2a    3a    4a    5a    6a   | 1b    2b    3b    4b    5b    6b
     | [     ["    [-n   [-n"  [-z   [-z" | [[    [["   [[-n  [[-n" [[-z  [[-z"
-----+------------------------------------+------------------------------------
unset| false false true  false true  true | false false false false true  true
null | false false true  false true  true | false false false false true  true
space| false true  true  true  true  false| true  true  true  true  false false
zero | true  true  true  true  false false| true  true  true  true  false false
digit| true  true  true  true  false false| true  true  true  true  false false
char | true  true  true  true  false false| true  true  true  true  false false
hyphn| true  true  true  true  false false| true  true  true  true  false false
two  | -err- true  -err- true  -err- false| true  true  true  true  false false
part | -err- true  -err- true  -err- false| true  true  true  true  false false
Tstr | true  true  -err- true  -err- false| true  true  true  true  false false
Fsym | false true  -err- true  -err- false| true  true  true  true  false false
T=   | true  true  -err- true  -err- false| true  true  true  true  false false
F=   | false true  -err- true  -err- false| true  true  true  true  false false
T!=  | true  true  -err- true  -err- false| true  true  true  true  false false
F!=  | false true  -err- true  -err- false| true  true  true  true  false false
Teq  | true  true  -err- true  -err- false| true  true  true  true  false false
Feq  | false true  -err- true  -err- false| true  true  true  true  false false
Tne  | true  true  -err- true  -err- false| true  true  true  true  false false
Fne  | false true  -err- true  -err- false| true  true  true  true  false false

যদি আপনি জানতে চান যে কোনও ভেরিয়েবলটি শূন্য-দৈর্ঘ্যের নয় তবে নিম্নলিখিত যে কোনওটি করুন:

  • একক বন্ধনীতে পরিবর্তনশীল উদ্ধৃতি (কলাম 2 এ)
  • -nএকক বন্ধনীতে চলকটি ব্যবহার করুন এবং উদ্ধৃত করুন (কলাম 4 এ)
  • উদ্ধৃতি সহ বা ছাড়াই বা ছাড়াই ডাবল বন্ধনী ব্যবহার করুন -n(কলাম 1 বি - 4 বি)

কলাম 1A মধ্যে নোটিশ সারি লেবেল "দুই" ফলাফল থেকে বোঝা যায় যে, এ শুরু [নির্ণয় করা হয় বিষয়বস্তু ভেরিয়েবলের যেন তারা শর্তাধীন অভিব্যক্তি অংশ ছিল (ফলাফলের কথন "টি" বা "এফ" এ ক্ষেত্রে প্রযোজ্য সাথে মিলে যায় বিবরণ কলাম)। যখন [[(কলাম 1 বি) ব্যবহৃত হয়, পরিবর্তনশীল সামগ্রীটি একটি স্ট্রিং হিসাবে দেখা হয় এবং মূল্যায়ন হয় না।

3a এবং 5a কলামের ত্রুটিগুলি এই কারণে ঘটে যে ভেরিয়েবলের মানটিতে একটি স্থান অন্তর্ভুক্ত থাকে এবং ভেরিয়েবলটি উদ্ধৃত হয় না। আবার, 3b এবং 5b কলামে দেখানো হিসাবে, [[ভেরিয়েবলের বিষয়বস্তুগুলি স্ট্রিং হিসাবে মূল্যায়ন করে।

অনুরূপভাবে, শূন্য দৈর্ঘ্যের স্ট্রিংগুলির পরীক্ষার জন্য, কলাম 6 এ, 5 বি এবং 6 বি এটি করার সঠিক উপায়গুলি দেখায়। এছাড়াও নোট করুন যে যদি এই পরীক্ষাগুলির কোনওটি তুচ্ছ করা যায় তবে যদি উপেক্ষার বিপরীত ক্রিয়াকলাপটি ব্যবহার করার চেয়ে আরও পরিষ্কার উদ্দেশ্য দেখা যায়। উদাহরণস্বরূপ: if ! [[ -n $var ]]

আপনি যদি ব্যবহার করছেন [, আপনি অপ্রত্যাশিত ফলাফল না পেয়েছেন তা নিশ্চিত করার কীটি চলকটির উদ্ধৃতি দিচ্ছে। ব্যবহার করে [[, এটা কোন ব্যাপার না।

ত্রুটি বার্তা, যা দমন করা হচ্ছে তা হ'ল "ইউনিারি অপারেটর প্রত্যাশিত" বা "বাইনারি অপারেটর প্রত্যাশিত"।

এটি স্ক্রিপ্ট যা উপরের টেবিলটি তৈরি করেছে।

#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://stackoverflow.com/q/3869072
# designed to fit an 80 character terminal

dw=5    # description column width
w=6     # table column width

t () { printf '%-*s' "$w" " true"; }
f () { [[ $? == 1 ]] && printf '%-*s' "$w" " false" || printf '%-*s' "$w" " -err-"; }

o=/dev/null

echo '     | 1a    2a    3a    4a    5a    6a   | 1b    2b    3b    4b    5b    6b'
echo '     | [     ["    [-n   [-n"  [-z   [-z" | [[    [["   [[-n  [[-n" [[-z  [[-z"'
echo '-----+------------------------------------+------------------------------------'

while read -r d t
do
    printf '%-*s|' "$dw" "$d"

    case $d in
        unset) unset t  ;;
        space) t=' '    ;;
    esac

    [ $t ]        2>$o  && t || f
    [ "$t" ]            && t || f
    [ -n $t ]     2>$o  && t || f
    [ -n "$t" ]         && t || f
    [ -z $t ]     2>$o  && t || f
    [ -z "$t" ]         && t || f
    echo -n "|"
    [[ $t ]]            && t || f
    [[ "$t" ]]          && t || f
    [[ -n $t ]]         && t || f
    [[ -n "$t" ]]       && t || f
    [[ -z $t ]]         && t || f
    [[ -z "$t" ]]       && t || f
    echo

done <<'EOF'
unset
null
space
zero    0
digit   1
char    c
hyphn   -z
two     a b
part    a -a
Tstr    -n a
Fsym    -h .
T=      1 = 1
F=      1 = 2
T!=     1 != 2
F!=     1 != 1
Teq     1 -eq 1
Feq     1 -eq 2
Tne     1 -ne 2
Fne     1 -ne 1
EOF

1
ধন্যবাদ! আমি সিদ্ধান্ত নিয়েছি "একক বন্ধনীতে পরিবর্তনশীল উদ্ধৃতি (কলাম 2 এ)" আইএমও, -আন কেবল শব্দ যোগ করে এবং পাঠযোগ্যতা হ্রাস করে। একইভাবে, শূন্য-দৈর্ঘ্য বা আনসেটের পরীক্ষার জন্য, আমি ব্যবহার করব [! "$ var"] [-z "$ var"] এর পরিবর্তে।
অ্যালেনহালসি

2
তাই জন্য আপনার চার্ট ["বনাম [-n"(ওপি প্রথম প্রশ্ন) দেখায় যে তারা সম্পূর্ণরূপে হয় সমতুল্য, ডান?
3:34

1
@ হোবস: হ্যাঁ, এবং কোনটি ব্যবহার করবেন তা নির্ভর করে কোনটি আরও স্পষ্ট। আপনি এটিও লক্ষ্য করবেন যে ডাবল-বন্ধনী ফর্মটি ব্যবহার করার সময় তাদের সমতুল্য যা ব্যাশ ব্যবহারের সময় পছন্দ হয়।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

1
সুতরাং, আপনার দুর্দান্ত টেবিলটির সংক্ষিপ্তসার হিসাবে, নন-নাল স্ট্রিংয়ের পরীক্ষা করার পরিষ্কার ("আরও ভাল") [["
উপায়টি

22

যতদূর বাশ সম্পর্কিত যতটা শক্তিশালী ব্যবহার করা আরও ভাল [[

সাধারণ ক্ষেত্রে

if [[ $var ]]; then   # var is set and it is not empty
if [[ ! $var ]]; then # var is not set or it is set to an empty string

উপরের দুটি কনস্ট্রাক্টস পরিষ্কার এবং পঠনযোগ্য দেখাচ্ছে look তাদের বেশিরভাগ ক্ষেত্রেই যথেষ্ট হওয়া উচিত।

মনে রাখবেন যে শব্দটির বিভাজন এবং গ্লোববিংয়ের[[ কোনও আশঙ্কা না থাকায় আমাদের ভিতরে পরিবর্তনশীল বিস্তৃতি উদ্ধৃত করার দরকার নেই ।

এবং সম্পর্কে শেলচেকের নরম অভিযোগগুলি প্রতিরোধ করতে আমরা বিকল্পটি ব্যবহার করতে পারি ।[[ $var ]][[ ! $var ]]-n

বিরল মামলা

আমাদের বিরল ক্ষেত্রে "একটি খালি স্ট্রিং সেট করা" "বনাম" একেবারে সেট করা হচ্ছে না "এর মধ্যে পার্থক্য তৈরি করতে আমরা এইগুলি ব্যবহার করতে পারি:

if [[ ${var+x} ]]; then           # var is set but it could be empty
if [[ ! ${var+x} ]]; then         # var is not set
if [[ ${var+x} && ! $var ]]; then # var is set and is empty

আমরা -vপরীক্ষাটিও ব্যবহার করতে পারি :

if [[ -v var ]]; then             # var is set but it could be empty
if [[ ! -v var ]]; then           # var is not set
if [[ -v var && ! $var ]]; then   # var is set and is empty
if [[ -v var && -z $var ]]; then  # var is set and is empty

সম্পর্কিত পোস্ট এবং ডকুমেন্টেশন

এই বিষয় সম্পর্কিত অনেকগুলি পোস্ট রয়েছে। এখানে কয়েকটি দেওয়া হল:


9

এখানে আরও কিছু পরীক্ষা দেওয়া হল

সত্য যদি স্ট্রিং ফাঁকা না থাকে:

[ -n "$var" ]
[[ -n $var ]]
test -n "$var"
[ "$var" ]
[[ $var ]]
(( ${#var} ))
let ${#var}
test "$var"

সত্য যদি স্ট্রিং ফাঁকা থাকে:

[ -z "$var" ]
[[ -z $var ]]
test -z "$var"
! [ "$var" ]
! [[ $var ]]
! (( ${#var} ))
! let ${#var}
! test "$var"

এটি আরও ভাল উপায় কী এর ওপির প্রশ্নের উত্তর দেয় না।
কোডফোরস্টার

0

সঠিক উত্তরটি নিম্নরূপ:

if [[ -n $var ]] ; then
  blah
fi

এর ব্যবহারটি নোট করুন [[...]], যা সঠিকভাবে আপনার জন্য ভেরিয়েবলগুলি উদ্ধৃত করে।


2
-nবাশের যখন সত্যই এটি প্রয়োজন হয় না তখন কেন ব্যবহার করবেন ?
কোডফোরস্টার

0

খালি পরিবেশের পরিবর্তনশীল মূল্যায়নের বিকল্প এবং সম্ভবত আরও স্বচ্ছ উপায়টি হ'ল ...

  if [ "x$ENV_VARIABLE" != "x" ] ; then
      echo 'ENV_VARIABLE contains something'
  fi

10
এটি বোর্নের শেল দিনগুলি থেকে খুব পুরানো-স্কুল। এই পুরানো অভ্যাস চিরস্থায়ী করবেন না। bashএটি পূর্বসূরীদের চেয়ে একটি তীক্ষ্ণ সরঞ্জাম tool
tbc0

1
এমনকি প্রাক-ব্যাশ শেলগুলির সাথেও আপনার এটির দরকার নেই, যদি আপনি সিনট্যাক্স এড়িয়ে চলে থাকেন যে পসিক্স স্ট্যান্ডার্ড স্পষ্টভাবে অপ্রচলিত চিহ্নিত করে। পশিক্স-কমপ্লায়েন্ট বাস্তবায়নের সাথে প্রতিটি শেলের [ "$ENV_VARIABLE" != "" ]উপর কাজ করবে - কেবল বাশ নয়, অ্যাশ / ড্যাশ / কেএসএইচ / ইত্যাদি। test
চার্লস ডাফি 15'18

... যা বলা যায়, পরীক্ষাগুলি ব্যবহার -aবা -oসংহত করার জন্য নয় বরং পরিবর্তে ব্যবহার করুন [ ... ] && [ ... ]বা পরীক্ষায় [ ... ] || [ ... ]স্বেচ্ছাসেবী ভেরিয়েবলের ডেটা ব্যবহার করার ক্ষেত্রে প্রয়োগ করা যেতে পারে এমন একমাত্র কোণার বিষয়গুলি স্পষ্টতই বন্ধ রয়েছে।
চার্লস ডাফি

-2

case/esacপরীক্ষার জন্য ব্যবহার করুন :

case "$var" in
  "") echo "zero length";;
esac

12
না, দয়া করে। এটি যা caseবোঝাতে চাইছে তা নয় ।
tbc0

2
caseযখন দুটিরও বেশি বিকল্প থাকে তখন সবচেয়ে ভাল কাজ করে।
কোডফোরস্টার

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