সংক্ষিপ্ত শেল বিকল্পের সাথে ভার্সন 4.2 সংস্করণের পূর্বে কোনও ভেরিয়েবলের সংজ্ঞা দেওয়া থাকলে কীভাবে পরীক্ষা করবেন?


16

পূর্বে ব্যাশ সংস্করণের জন্য "গনুহ ব্যাশ, সংস্করণ 4.2" সেখানে কোনো সমতুল্য বিকল্প আছে -vবিকল্প testকমান্ড? উদাহরণ স্বরূপ:

shopt -os nounset
test -v foobar && echo foo || echo bar
# Output: bar
foobar=
test -v foobar && echo foo || echo bar
# Output: foo

-vকোনও বিকল্প নয় test, শর্তাধীন অভিব্যক্তিগুলির জন্য একটি অপারেটর।
টিম

@Tim এটা তিনটি বিষয়, একটি টোকেন, একটি স্ট্রিং এবং একটি লাইন অংশ হওয়ার পাশে: একটি optionএকটি আদেশের জন্য test -v, একটি operatorএকটি থেকে conditional expressionএবং একটি unary test primaryজন্য [ ]। শেল সংজ্ঞা সাথে ইংরেজি ভাষা মিশ্রিত করবেন না।

উত্তর:


36

সমস্ত পসিক্স শেল পোর্টেবল:

if [ -n "${foobar+1}" ]; then
  echo "foobar is defined"
else
  echo "foobar is not defined"
fi

তা নিশ্চিত করুন ${foobar:+1}আপনি চিকিত্সার জন্য চান foobarএটা খালি বা না সংজ্ঞায়িত কিনা একই ভাবে। এছাড়াও আপনি ব্যবহার করতে পারেন ${foobar-}একটি খালি স্ট্রিং যখন পেতে foobarundefined করা হয় এবং এর মান foobar(অথবা পরে অন্য কোন ডিফল্ট মান করা অন্যথায় -)।

কেএসএসে, যদি foobarঘোষণা করা হয় তবে সংজ্ঞায়িত না হয়, যেমনটি হয় typeset -a foobar, তবে ${foobar+1}খালি স্ট্রিংয়ে প্রসারিত হয়।

জেডএসের ভেরিয়েবলগুলি নেই যা ঘোষণা করা হলেও সেট করা নেই: typeset -a foobarএকটি খালি অ্যারে তৈরি করে।

ব্যাশে, অ্যারেগুলি অন্যরকম এবং আশ্চর্যরকম আচরণ করে। খালি শূন্য অ্যারে হলে ${a+1}কেবল প্রসারিত হয় eg1a

typeset -a a; echo ${a+1}    # prints nothing
e=(); echo ${e+1}            # prints nothing!
f=(''); echo ${f+1}          # prints 1

একই নীতিটি অ্যা্যাসোসিয়েটিভ অ্যারেগুলিতে প্রযোজ্য: অ্যারে ভেরিয়েবলগুলি যদি সূচকগুলির খালি খালি সেট থাকে তবে সংজ্ঞায়িত হিসাবে বিবেচনা করা হবে।

কোনও ধরণের ভেরিয়েবল সংজ্ঞায়িত করা হয়েছে কিনা তা পরীক্ষার একটি পৃথক, বাশ-নির্দিষ্ট উপায় এটিতে তালিকাভুক্ত হয়েছে কিনা তা পরীক্ষা করা । এটি বিপরীত হিসাবে সংজ্ঞায়িত হিসাবে খালি অ্যারেগুলি প্রতিবেদন করে তবে রিপোর্ট-কিন্তু-অ-সিইন্ডেড ভেরিয়েবলগুলি ( ) অপরিবর্তিত হিসাবে ঘোষণা করেছে ।${!PREFIX*}${foobar+1}unset foobar; typeset -a foobar

case " ${!foobar*} " in
  *" foobar "*) echo "foobar is defined";;
  *) echo "foobar is not defined";;
esac

এটি ঘোষিত-তবে-অ-স্বাক্ষরিত ভেরিয়েবলগুলিতে ব্যর্থ ব্যতীত, বা এর রিটার্ন মান পরীক্ষারtypeset -p foobardeclare -p foobar সমতুল্য typeset -p foobar

ব্যাশের মধ্যে, ksh এর মতো, অপরিবর্তিত set -o nounset; typeset -a foobar; echo $foobarভেরিয়েবলটি প্রসারণের প্রয়াসে ত্রুটি ঘটায় foobar। Ksh এর বিপরীতে set -o nounset; foobar=(); echo $foobar(বা echo "${foobar[@]}") ত্রুটিও ট্রিগার করে।

মনে রাখবেন যে এখানে বর্ণিত সমস্ত পরিস্থিতিতে ${foobar+1}খালি স্ট্রিংয়ে প্রসারিত হয় কেবল যদি তবেই $foobarত্রুটির কারণ হয় set -o nounset


1
অ্যারে সম্পর্কে কি? বাশ সংস্করণে "জিএনইউ বাশ, সংস্করণ 4.1.10 (4) -রিলেজ (আই 686-পিসি-সিগুইন)" echo "${foobar:+1}"প্রিন্ট করে না 1যদি declare -a foobarআগে জারি করা হয়েছিল এবং সুতরাং foobarএটি সূচকযুক্ত অ্যারে হয়। declare -p foobarসঠিকভাবে রিপোর্ট declare -a foobar='()'। কি "${foobar:+1}"অ-বিন্যাস ভেরিয়েবল কেবল কাজ করে?
টিম ফ্রিস্ক

@ টিমফ্রিস্ক ${foobar+1}( বাদে :, আমি আমার মূল উত্তরে দুটি উদাহরণ উল্টিয়েছি ) বাশে অ্যারেগুলির জন্য সঠিক যদি আপনার "সংজ্ঞায়িত" সংজ্ঞাটি "এর $foobarঅধীনে কাজ করবে set -o nounset"। যদি আপনার সংজ্ঞাটি আলাদা হয় তবে বাশ কিছুটা অদ্ভুত। আমার আপডেট হওয়া উত্তরটি দেখুন।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

1
"ব্যাশে ইন, অ্যারেগুলি অন্যরকম এবং অবাক করার মতো আচরণ করে" শীর্ষক বিষয়টি সম্পর্কিত। আচরণটি ব্যাশ (1) ম্যান্যাপ, বিভাগ "অ্যারে" থেকে ব্যাখ্যা করা যেতে পারে। এটিতে বলা হয়েছে যে "সাবস্ক্রিপ্ট ব্যতীত অ্যারে ভেরিয়েবল উল্লেখ করা ০.০ এর সাবস্ক্রিপ্ট সহ অ্যারে উল্লেখ করার সমতুল্য"। তাই যদি তন্ন তন্ন একটি 0সূচক কিংবা একটি কী যেমন জন্য সত্য সংজ্ঞায়িত করা হয় a=(), ${a+1}সঠিকভাবে কিছুই ফেরৎ।
টিম ফ্রিস্ক

1
@ টিমফ্রিসেকে আমি জানি যে বাশ বাস্তবায়ন এর ডকুমেন্টেশনের সাথে সামঞ্জস্য। তবে একটি অনির্ধারিত ভেরিয়েবলের মতো একটি খালি অ্যারের সাথে চিকিত্সা করা সত্যিই অদ্ভুত নকশা।
গিলস 'খারাপ হয়ে যাওয়া বন্ধ করুন'

আমি ফলাফলটি পছন্দ করি: বাশে কোনও চলক সেট করা আছে কিনা তা কীভাবে পরীক্ষা করবেন? -> সঠিক উপায়ে ... আমি কীভাবে কাজ করব এটি কীভাবে করা উচিত তা নিয়ে আমি এক জেলাকে আঘাত করি । সাহস আমি বলি, উইন্ডোজ একটি definedঅপারেটর আছে। Test এটা করতে পারে ; এটা কঠিন করা যাবে না ( উম ....)
হবে

6

গিলসের উত্তরের সংক্ষিপ্ত বিবরণে আমি আমার নীচের বিধিগুলি তৈরি করেছি:

  1. [[ -v foobar ]]বাশ সংস্করণ> = 4.2 এ ভেরিয়েবলের জন্য ব্যবহার করুন ।
  2. declare -p foobar &>/dev/nullবাশ সংস্করণ <4.2 এ অ্যারে ভেরিয়েবলের জন্য ব্যবহার করুন ।
  3. যথাক্রমে ইনডেক্সড ( ) এবং কীড ( ) অ্যারে ( ) এর সাবস্ক্রিপ্ট ব্যবহার করুন (( ${foo[0]+1} ))বা করুন । বিকল্প 1 এবং 2 এখানে কাজ করে না।(( ${bar[foo]+1} ))-a-Adeclare

3

আমি ব্যাশের সমস্ত চলকগুলির জন্য একই কৌশলটি ব্যবহার করি এবং এটি কাজ করে, যেমন:

[ ${foobar} ] && echo "foobar is set" || echo "foobar is unset"

আউটপুট:

foobar is unset

থাকাকালীন

foobar=( "val" "val2" )
[ ${foobar} ] && echo "foobar is set" || echo "foobar is unset"

আউটপুট:

foobar is set

অ্যারের একাধিক মান থাকলে তা সরানো হয়েছে [@]।
স্টেইন ইনজে মরিসবাক

1
এটি দুর্দান্ত কাজ করে, আপনি যতক্ষণ পরীক্ষা করতে চান এটির কোনও মূল্য আছে কিনা তা নির্ধারণ করা হয়েছে কিনা। অর্থাৎ, foobar=""তারপরে এটি রিপোর্ট করবে foobar is unset। অপেক্ষা করো না, আমি এটি ফিরিয়ে নিই। সত্যিই কেবলমাত্র যদি প্রথম উপাদানটি খালি থাকে বা না পরীক্ষা করে থাকে, সুতরাং আপনি যদি ভেরিয়েবলটি অ্যারে না হন তবে এটি কেবলমাত্র ভাল ধারণা বলে মনে হয় এবং আপনি কেবল শূন্যতার বিষয়ে যত্নশীল হন, সংজ্ঞায়িতকরণ নয় not
রন বার্ক

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