বিঃদ্রঃ
আমি 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}" ]
পসিএক্স অনুগত পরিস্থিতিতে নির্ভরযোগ্য তবে অ্যারে পরিচালনা করতে পারে না।
- কোনও ভেরিয়েবলটি নমনীয় নয় কিনা তা পরীক্ষা করার জন্য এবং অন্যান্য শেলগুলিতে ঘোষিত ভেরিয়েবলগুলি পরীক্ষা করার জন্য অন্যান্য পরীক্ষাগুলি বিদ্যমান। তবে এই পরীক্ষাগুলি বাশ বা পোসিক্স স্ক্রিপ্টগুলির জন্য উপযুক্ত নয়।
if test $# -gt 0; then printf 'arg <%s>\n' "$@"; fi
।