প্রশ্ন অ্যারে খালি খালি কিনা তা পরীক্ষা করুন


আমার একটি স্ক্রিপ্ট রান হিসাবে বিভিন্ন ত্রুটি বার্তা ভরাট একটি অ্যারে আছে।

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

আমি ইতিমধ্যে এটি একটি স্বাভাবিক VAR এবং এটি ব্যবহার করে -z ব্যবহার করে চিকিত্সা করার চেষ্টা করেছি, কিন্তু এটি কাজ বলে মনে হচ্ছে না। একটি অ্যারে খালি বা না Bash চেক না একটি উপায় আছে কি?

ধন্যবাদ


82
2018-02-11 03:59


উত্স




উত্তর:


আপনার অ্যারের অনুমান করা হয় $errors, শুধুমাত্র উপাদান গণনা শূন্য কিনা দেখতে চেক করুন।

if [ ${#errors[@]} -eq 0 ]; then
    echo "No errors, hooray"
else
    echo "Oops, something went wrong..."
fi

113
2018-02-11 04:10



দয়া করে মনে রাখবেন = একটি স্ট্রিং অপারেটর। এটা এই ক্ষেত্রে জরিমানা কাজ করে, কিন্তু আমি সঠিক গাণিতিক অপারেটর ব্যবহার করবে -eq পরিবর্তে (শুধু ক্ষেত্রে আমি স্যুইচ করতে চাই -ge অথবা -lt, ইত্যাদি)। - musiphil
সঙ্গে কাজ করে না set -u: "আনবাউন্ড পরিবর্তনশীল" - যদি অ্যারে খালি থাকে। - Igor
@ ইগর: ব্যাশ 4.4 এর জন্য আমার জন্য কাজ করে। set -u;  foo=();  [ ${#foo[@]} -eq 0 ] && echo empty। আমি যদি unset foo, তারপর এটা প্রিন্ট foo: unbound variable, তবে এটি আলাদা: অ্যারের পরিবর্তনশীল বিদ্যমান এবং খালি থাকা পরিবর্তে বিদ্যমান নেই। - Peter Cordes
এছাড়াও ব্যবহার করে ব্যাশ 3.2 (OSX) পরীক্ষিত set -u - যতদিন আপনি আপনার পরিবর্তনশীল প্রথম ঘোষিত, এটি পুরোপুরি কাজ করে। - zeroimpl


আপনি একটি সহজ পরিবর্তনশীল হিসাবে অ্যারে বিবেচনা করতে পারেন। যে ভাবে, শুধু ব্যবহার করে

if [ -z "$array" ]; then
    echo "Array empty"
else
    echo "Array non empty"
fi

অথবা অন্য দিকে ব্যবহার করে

if [ -n "$array" ]; then
    echo "Array non empty"
else
    echo "Array empty"
fi

যে সমাধান সঙ্গে সমস্যা হল যে যদি একটি অ্যারে এই মত ঘোষণা করা হয়: array=('' foo)। এই চেক অ্যারে খালি হিসাবে খালি রিপোর্ট করা হবে, যখন এটা পরিষ্কারভাবে হয় না। (ধন্যবাদ @ মুসিফিল!)

ব্যবহার [ -z "$array[@]" ] স্পষ্টভাবে একটি সমাধান না হয়। কোঁকড়া বন্ধনী ব্যাখ্যা না করার চেষ্টা করে $array একটি স্ট্রিং হিসাবে ([@] যে ক্ষেত্রে একটি সহজ আক্ষরিক স্ট্রিং) এবং তাই সবসময় মিথ্যা হিসাবে রিপোর্ট করা হয়: "আক্ষরিক স্ট্রিং [@] খালি? "পরিষ্কারভাবে না।


6
2018-06-23 10:29



[ -z "$array" ] অথবা [ -n "$array" ] কাজ করে না। চেষ্টা array=('' foo); [ -z "$array" ] && echo empty, এবং এটি মুদ্রণ করা হবে empty যদিও array স্পষ্টভাবে খালি হয় না। - musiphil
[[ -n "${array[*]}" ]] সমগ্র অ্যারেটিকে একটি স্ট্রিং হিসাবে ইন্টারপোল করে, যা আপনি অ-শূন্য দৈর্ঘ্যের জন্য পরীক্ষা করেন। আপনি বিবেচনা করেন array=("" "") খালি হতে, বরং দুটি খালি উপাদান থাকার, এই দরকারী হতে পারে। - Peter Cordes


আমি সাধারণত এই ক্ষেত্রে গাণিতিক বিস্তার ব্যবহার করুন:

if (( ${#a[@]} )); then
    echo not empty
fi

3
2017-08-02 06:04



সুন্দর এবং পরিষ্কার! আমি এটা পছন্দ করি. আমি মনে করি যে অ্যারে প্রথম উপাদান সর্বদা অযৌক্তিক হয়, (( ${#a} )) (প্রথম উপাদান দৈর্ঘ্য) কাজ করবে। তবে, যে ব্যর্থ হবে a=(''), যখন (( ${#a[@]} )) উত্তর দেওয়া সফল হবে। - cxw


আমি এটা দিয়ে চেক bash-4.4.0:

#!/usr/bin/env bash
set -eu
check() {
    if [[ ${array[@]} ]]; then
        echo not empty
    else
        echo empty
    fi
}
check   # empty
array=(a b c d)
check   # not empty
array=()
check   # empty

এবং bash-4.1.5:

#!/usr/bin/env bash
set -eu
check() {
    if [[ ${array[@]:+${array[@]}} ]]; then
        echo non-empty
    else
        echo empty
    fi
}
check   # empty
array=(a b c d)
check   # not empty
array=()
check   # empty

পরবর্তী ক্ষেত্রে আপনাকে নিচের কনস্ট্রাক্টটি দরকার:

${array[@]:+${array[@]}}

এটি খালি বা অনির্দিষ্ট অ্যারে ব্যর্থ না। যে আপনি যদি set -eu আমি সাধারণত মত। এই আরো কঠোর ত্রুটি পরীক্ষণের জন্য উপলব্ধ করা হয়। থেকে ডক্স:

-e

একটি পাইপলাইন (পাইপলাইন দেখুন), যা একটি সহজ কমান্ড (সহজ কমান্ড দেখুন), একটি তালিকা (দেখুন তালিকা), বা যৌগ কমান্ড (কম্পাউন্ড কমান্ড দেখুন) একটি অ-শূন্য অবস্থা প্রদান করে তাৎক্ষণিকভাবে প্রস্থান করুন। যদি কমান্ডটি ব্যর্থ হয় তবে শেলটি কোনও সময় বা কীওয়ার্ডের পরে অবিলম্বে কমান্ড তালিকার অংশ নয়, যদি একটি বিবৃতিতে পরীক্ষার অংশ হয় তবে এটি কোনও & কমান্ডের কোনও আদেশের অংশ। চূড়ান্ত && অথবা || নিম্নলিখিত কোনও পাইপলাইনের মধ্যে কোনও আদেশ, তবে শেষ বা যদি কমান্ডের রিটার্ন স্ট্যাটাসটি উল্টানো হচ্ছে! একটি উপশহর ব্যতীত অন্য যৌগ কমান্ডটি একটি অ-শূন্য স্থিতি প্রদান করে কারণ একটি কমান্ড ব্যর্থ হয়েছে যখন -কে উপেক্ষা করা হচ্ছে, শেলটি প্রস্থান করে না। ইআরআর, যদি সেট করা হয়, একটি ফাঁদ শেল প্রস্থান করার আগে মৃত্যুদন্ড কার্যকর করা হয়।

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

যদি একটি যৌগ কমান্ড বা শেল ফাংশন কোন প্রসঙ্গে সঞ্চালিত হয় যেখানে -কে উপেক্ষা করা হচ্ছে, যৌগ কমান্ড বা ফাংশন শরীরের মধ্যে কার্যকর কোন কমান্ডগুলি -ই সেটিংস দ্বারা প্রভাবিত হবে, এমনকি -e সেট থাকলেও এবং একটি কমান্ড ফেরত দেয় ব্যর্থতার অবস্থা। একটি যৌগ কমান্ড বা শেল ফাংশন সেট -e একটি প্রেক্ষাপটে নির্বাহ করার সময় -e কে উপেক্ষা করা হয়, সেই সেটিংটির কোনো প্রভাব থাকবে না যতক্ষণ না যৌগ কমান্ড বা ফাংশন কল ধারণকারী কমান্ডটি সম্পূর্ণ হয়।

-u

প্যারামিটার বিস্তার সঞ্চালনের সময় বিশেষ পরামিতি '@' বা '*' ব্যতীত অন্যের ভেরিয়েবল এবং প্যারামিটারগুলি সেট করুন। স্ট্যান্ডার্ড ত্রুটিতে একটি ত্রুটি বার্তা লেখা হবে এবং একটি নন-ইন্টারেক্টিভ শেল প্রস্থান করবে।

আপনি যদি প্রয়োজন হয় না, অনুপস্থিত মুক্ত মনে :+${array[@]} অংশ।

এছাড়াও এটি ব্যবহার করা অপরিহার্য যে নোট করুন [[ অপারেটর এখানে, সঙ্গে [ তুমি পাও:

$ cat 1.sh
#!/usr/bin/env bash
set -eu
array=(a b c d)
if [ "${array[@]}" ]; then
    echo non-empty
else
    echo empty
fi

$ ./1.sh
_/1.sh: line 4: [: too many arguments
empty

2
2017-12-04 14:58



সঙ্গে -u আপনি আসলে ব্যবহার করা উচিত ${array[@]+"${array[@]}"} CF stackoverflow.com/a/34361807/1237617 - Jakub Bochenski
@ জাকুব বোচেনস্কি বাশের কোন সংস্করণটি সম্পর্কে আপনি কথা বলছেন? gist.github.com/x-yuri/d933972a2f1c42a49fc7999b8d5c50b9 - x-yuri
একক বন্ধনী উদাহরণ সমস্যা হয় @নিশ্চয়ই। আপনি ব্যবহার করতে পারেন * অ্যারের বিস্তার মত [ "${array[*]}" ]তুমি কি পারবে না? এখনও, [[ এছাড়াও জরিমানা কাজ করে। একাধিক খালি স্ট্রিং সহ একটি অ্যারে জন্য উভয় আচরণ একটু অবাক করে। উভয় [ ${#array[*]} ] এবং [[ "${array[@]}" ]] জন্য মিথ্যা array=() এবং array=('') কিন্তু জন্য সত্য array=('' '') (দুই বা আরও খালি স্ট্রিং)। যদি আপনি এক বা একাধিক ফাঁকা স্ট্রিং সবাইকে সত্য বলে জানান তবে আপনি এটি ব্যবহার করতে পারেন [ ${#array[@]} -gt 0 ]। যদি আপনি তাদের সব মিথ্যা চেয়েছিলেন, আপনি সম্ভবত হতে পারে // তাদের আউট। - eisd
@ আইসড আমি ব্যবহার করতে পারি [ "${array[*]}" ], কিন্তু যদি আমি এইরকম অভিব্যক্তিতে চালিত হতাম তবে আমার পক্ষে এটি বোঝা কঠিন হবে। থেকে [...] হস্তক্ষেপ ফলে স্ট্রিং পদে কাজ করে। উল্টোদিকে [[...]], যা interpolated সচেতন হতে পারে। অর্থাৎ, এটি একটি অ্যারে পাস করা হয়েছে যে জানতে পারেন। [[ ${array[@]} ]] যখন "অ্যারে অ-খালি থাকে কিনা তা চেক করুন" হিসাবে আমার কাছে পড়ে [ "${array[*]}" ] হিসাবে "সব অ্যারের উপাদান interpolation ফলাফল একটি অ খালি স্ট্রিং হয় কিনা তা পরীক্ষা করুন"। - x-yuri
... দুই খালি স্ট্রিংয়ের সাথে আচরণের জন্য এটি আমার কাছে বিস্ময়কর নয়। বিস্ময়কর কি একটি খালি স্ট্রিং সঙ্গে আচরণ। কিন্তু যুক্তিযুক্ত যুক্তিসঙ্গত। সংক্রান্ত [ ${#array[*]} ], সম্ভবত আপনি বোঝানো [ "${array[*]}" ], যেহেতু প্রাক উপাদান কোন সংখ্যা জন্য সত্য। কারণ উপাদান সংখ্যা সর্বদা খালি স্ট্রিং। দ্বিতীয় উপাদানগুলির সাথে পরেরটির সম্পর্কে, বন্ধনীগুলির ভিতরে অভিব্যক্তি বিস্তৃত হয় ' ' যা অ খালি স্ট্রিং। জন্য [[ ${array[@]} ]], তারা শুধু মনে করে (এবং ঠিক তাই) দুটি উপাদান কোন অ্যারের খালি হয়। - x-yuri


আমার ক্ষেত্রে, দী দ্বিতীয় উত্তর হোয়াইটস্পেস হতে পারে কারণ যথেষ্ট ছিল না। আমি বরাবর এসেছিলেন:

if [ "$(echo -ne ${opts} | wc -m)" -eq 0 ]; then
  echo "No options"
else
  echo "Options found"
fi

0
2018-02-17 19:54



echo | wc শেল বিল্ট ইনস ব্যবহার করে তুলনাহীন অযৌক্তিক মনে হয়। - Peter Cordes
@PeterCordes আমি বুঝতে পারছি না, আমি দ্বিতীয় উত্তরগুলি সংশোধন করতে পারি [ ${#errors[@]} -eq 0 ]; হোয়াইটস্পেস সমস্যা চারপাশে কাজ করার একটি উপায়? আমি অন্তর্নির্মিত পছন্দ করতে চাই। - Micha
কিভাবে হোয়াইটস্পেস ঠিক একটি সমস্যা কারণ? $# একটি সংখ্যা প্রসারিত, এবং এমনকি পরে জরিমানা কাজ করে opts+=("")। উদাহরণস্বরূপ unset opts;  opts+=("");opts+=(" "); echo "${#opts[@]}" এবং আমি পেতে 2। আপনি কি এমন কিছু উদাহরণ প্রদর্শন করতে পারেন যা কাজ করে না? - Peter Cordes
এটা অনেক আগে। আইআইআরসি মূল উৎস সর্বদা অন্তত "" মুদ্রিত। সুতরাং, opts = "" বা opts = ("") এর জন্য আমাকে খালি নতুন লাইন বা খালি স্ট্রিং উপেক্ষা করে 0, 1 নয়। - Micha
ঠিক আছে, তাই আপনি চিকিত্সা প্রয়োজন opts=("") একই হিসাবে opts=()? এটি একটি খালি অ্যারে নয়, তবে আপনি খালি অ্যারে বা খালি প্রথম উপাদানটি পরীক্ষা করতে পারেন opts=("");  [[ "${#opts[@]}" -eq 0 || -z "$opts" ]] && echo empty। আপনার বর্তমান উত্তর জন্য "কোন বিকল্প" বলে মনে রাখবেন opts=("" "-foo"), যা পুরোপুরি বোকা, এবং এটি যে আচরণ reproduces। আপনি পারে [[ -z "${opts[*]}" ]] আমি অনুমান, সব অ্যারের উপাদান একটি সমতল স্ট্রিং মধ্যে interpolate, যা -z অ শূন্য দৈর্ঘ্যের জন্য চেক।  যদি প্রথম উপাদানটি পরীক্ষা করা যথেষ্ট হয়, -z "$opts" কাজ করে। - Peter Cordes


আমি ডবল বন্ধনী ব্যবহার করতে পছন্দ করি:

if [[ !${array[@]} ]]
then
    echo "Array is empty"
else
    echo "Array is not empty"
fi

ডাবল বন্ধনী: https://stackoverflow.com/questions/669452/is-preferable-over-in-bash


0
2017-11-04 06:40