এর কোনও ভাল কারণ নেই
[[ $a = a|b ]]
$ a|bA স্ট্রিং কিনা তা পরীক্ষা করার পরিবর্তে একটি ত্রুটির প্রতিবেদন করা উচিত , যখন [[ $a =~ a|b ]]ত্রুটি ফিরে আসে না।
একমাত্র কারণ হ'ল |সাধারণত (বাইরে এবং ভিতরে [[ ... ]]) একটি বিশেষ চরিত্র। সেই [[ $a =অবস্থানে, এমন bashএক ধরণের টোকেন প্রত্যাশা করে যা একটি সাধারণ শেল কমান্ড লাইনে আর্গুমেন্ট বা পুনর্নির্দেশগুলির লক্ষ্যগুলির মতো একটি সাধারণ ডাব্লুআরআরড (তবে যেন extglobবাশ ৪.১-এর পরে বিকল্পটি সক্ষম হয়েছে)।
( এখানে ওয়ার্ড দ্বারা , আমি পোসিক্স স্পেসিফিকেশন দ্বারা বর্ণিত মতকল্পিত শেল ব্যাকরণে একটি শব্দের উল্লেখ করি , এটি এমন কিছু যা শেল একটি সাধারণ শেল কমান্ড লাইনে একটি টোকেন হিসাবে বিভক্ত হবে, ইংরেজির মতো শব্দের সংজ্ঞা নয়) অক্ষর একটি অনুক্রম বা অ- ব্যবধান বর্ণের একটি ক্রম। এক foo"bar baz", $(echo x y)এই ধরনের দুটি শব্দ গুলি)।
একটি সাধারণ শেল কমান্ড লাইনে:
echo a|b
অর্থাৎ echo aজন্য বাঁশি বাজালাম b। a|bএকটি ওয়ার্ড নয় , এটি তিনটি টোকেন: একটি a ওয়ার্ড , একটি |টোকেন এবং একটি b ওয়ার্ড টোকেন।
এটি ব্যবহার করার সময় [[ $a = a|b ]], bashকোনও ওয়ার্ডটি প্রত্যাশা করে যা এটি পায় ( a), তবে তারপরে একটি অপ্রত্যাশিত |টোকেন পাওয়া যায় যা ত্রুটির কারণ হয়।
মজার বিষয়, এতে bashঅভিযোগ করবেন না:
[[ $a = a||b ]]
কারণ এটি এখন একটি aটোকেন এবং তার পরে একটি ||টোকেন রয়েছে b, সুতরাং এটি একইভাবে পার্স করা হয়েছে:
[[ $a = a || b ]]
কোনটি পরীক্ষা করছে যে $aহয় aবা যে bস্ট্রিং খালি নয় এমন।
এখন:
[[ $a =~ a|b ]]
bashএকই পার্সিং বিধি থাকতে পারে না। একই পার্সিং বিধিটি থাকা মানে এই হবে যে উপরেরটি একটি ত্রুটি দেয় এবং এটির জন্য একটি একক ওয়ার্ড| নিশ্চিত a|bকরা দরকার । তবে, বাশ ৩.২ থেকে আপনি যদি এটি করেন:
[[ $a =~ 'a|b' ]]
এটি আর a|bরেজিএক্সএক্সের বিপক্ষে নয় বরং রেজিপ্সপের বিপরীতে মিলছে a\|b। এটি হ'ল শেল কোটিংয়ের রেজিএক্সএক্স অপারেটরগুলির বিশেষ অর্থ সরিয়ে দেওয়ার পার্শ্ব প্রতিক্রিয়া রয়েছে। এটি একটি বৈশিষ্ট্য, তাই আচরণটি [[ $a = "?" ]]একটির অনুরূপ , তবে ওয়াইল্ডকার্ড নিদর্শনগুলি (ব্যবহৃত হয় [[ $a = pattern ]]) হ'ল শেল ওয়ার্ডস (উদাহরণস্বরূপ গ্লোবগুলিতে ব্যবহৃত হয়), যখন রেজিেক্সপস হয় না।
সুতরাং bashসব বর্ধিত regexp অপারেটার অন্যথায় স্বাভাবিকভাবে মত বিশেষ শেল অক্ষর আচরণ করা হয়েছে |, (, )ভিন্নভাবে যখন একটি আর্গুমেন্ট পার্স =~অপারেটর।
তবুও, লক্ষ্য করুন যে
[[ $a =~ (ab)*c ]]
এখন কাজ করে,
[[ $a =~ [)}] ]]
না। তোমার দরকার:
[[ $a =~ [\)}] ]]
[[ $a =~ [')'}] ]]
পূর্ববর্তী সংস্করণগুলির মধ্যে bashযা ব্যাকস্ল্যাশের সাথে ভুলভাবে মেলে। যে এক স্থির ছিল, কিন্তু
[[ $a =~ [^]')'] ]]
না না মত উদাহরণস্বরূপ উচিত ব্যাকস্ল্যাশ উপর মেলে। কারণ বন্ধনীগুলির মধ্যে রয়েছে bashতা উপলব্ধি করতে ব্যর্থ হয় ), তাই )কোনও [^]\)]রেজপ্লেক্সের ফলস্বরূপ পালিয়ে যায় যা কোনও চরিত্রের সাথে মেলে তবে ], \এবং )।
ksh93 যে ফ্রন্টে আরও খারাপ বাগ আছে।
ইন zsh, এটি একটি সাধারণ শেল শব্দ যা প্রত্যাশা করা হয় এবং রেজিএক্সএক্স অপারেটরদের উদ্ধৃতি দিয়ে রেজিএক্সএক্স অপারেটরদের অর্থ প্রভাবিত করে না।
[[ $a =~ 'a|b' ]]
মিলছে a|bরেজিপ্স্পের বিপরীতে ।
তার মানে কমান্ডটি / কমান্ডে =~যুক্ত করা যেতে পারে :[test
[ "$a" '=~' 'a|b' ]
test "$a" '=~' 'a|b'
(এছাড়াও কাজ yash। =~চাহিদা উদ্ধৃত করা zshযেমন =somethingএকটি বিশেষ শেল অপারেটর যায়)।
bash 3.1 এর মতো আচরণ করত zsh। এটি ৩.২-এ পরিবর্তিত হয়েছিল, সম্ভবত এটির সাথে সারিবদ্ধ হওয়ার জন্য ksh93(যদিও bashশেলটি প্রথমে উপস্থিত হয়েছিল [[ =~ ]]) তবে আপনি এখনও করতে BASH_COMPAT=31বা shopt -s compat31পূর্ববর্তী আচরণে [[ $a =~ a|b ]]ফিরে যেতে পারেন ( bash৩.১-এ ত্রুটি ফিরে আসার পরে তা আর হয় না) এর bash -O compat31নতুন সংস্করণ সহ bash)।
আশা করি এটি স্পষ্ট হয়েছে যে আমি কেন নিয়মগুলি বিভ্রান্তিকর বলেছিলাম এবং কেন ব্যবহার করছি:
[[ $a =~ $var ]]
অন্যান্য শেলগুলির বহনযোগ্যতা সহ সহায়তা করে।
|বিশেষ) এর ডানদিকে ডানদিকে ডিফল্টরূপে চালু রয়েছে[[ $var = $pattern ]]। সংস্করণ এবংshoptবিকল্প কনফিগারেশনগুলি যেখানে এই আচরণটি দেখা যায় তা বিচ্ছিন্ন করা আকর্ষণীয় হবে - যদি কেবল এটিই থাকে যেখানেextglobডিফল্ট বা স্পষ্টরূপে কনফিগারেশন অনুসারে হয়, তবে আমরা সেখানে আছি।