স্ট্রিং যখন বাম-বন্ধনী হয় তখন শেল বন্ধনী পরীক্ষায় ত্রুটি


27

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

তারপরে আমি এটি পেরিয়ে এসেছি:

$ x='('
$ [ "$x" = '1' -a "$y" = '1' ]
bash: [: `)' expected, found 1

একই ত্রুটি পেয়ে সমস্যাটি বিচ্ছিন্ন করার চেষ্টা করছেন:

$ [ '(' = '1' -a '1' = '1' ]
bash: [: `)' expected, found 1

আমি সমস্যাটি এরকমভাবে সমাধান করেছি:

[ "$x" = '1' ] && [ "$y" = '1' ]

তবুও আমার জানতে হবে এখানে কী চলছে।


2
ব্যাশ হিসাবে, আপনি যেমন ব্যবহার করতে পারেন[[ "$x" = '1' && "$y" = '1' ]]
টেরডন

3
পরীক্ষার জন্য পসিক্স স্পেসিফিকেশন এই কারণে স্পষ্টভাবে বর্ণনা করে -aএবং -oঅপ্রচলিত হিসাবে বর্ণিত হয় (যা [OB]তাদের স্পেসিফিকেশনের পাশের সুপারস্ক্রিপ্ট বলতে বোঝায়)। আপনি যদি [ "$x" = 1 ] && [ "$y" = 1 ]পরিবর্তে লিখে থাকেন তবে আপনি ভাল থাকবেন, এবং ভালভাবে সংজ্ঞায়িত / মানকৃত আচরণের ক্ষেত্রের মধ্যে থাকবেন।
চার্লস ডাফি

6
এই কারণেই লোকেরা [ "x$x" = "x1" ]অপারেটর হিসাবে ভুল ব্যাখ্যা করা যুক্তি রোধ করতে ব্যবহার করত ।
জোনাথন লেফলার 14

@ জোনাথনলফলার: আরে, আপনি আমার একক বাক্যে জবাব দিয়েছেন, ন্যায্য নয়! :) যদি কেউ dashব্যাশের পরিবর্তে পসিক্স শেল ব্যবহার করে তবে এটি এখনও একটি কার্যকর অনুশীলন।
নামমাত্র প্রাণী

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

উত্তর:


25

এটি একটি খুব অস্পষ্ট কোণার কেস যা কিনা পরীক্ষা [-নিরীক্ষণটি সংজ্ঞায়িত করা হয় তাতে একটি বাগ বিবেচনা করতে পারে ; তবে এটি [অনেক সিস্টেমে উপলব্ধ প্রকৃত বাইনারিগুলির ব্যবহারের সাথে মেলে না । যতদুর আমি বলতে পারেন, এটি শুধুমাত্র নির্দিষ্ট ক্ষেত্রে এবং একটি পরিবর্তনশীল যে একটি ম্যাচ একটি মান না থাকার প্রভাবিত [মত অপারেটর (, !, =, -e, ইত্যাদি।

বাশ এবং পসিক্স শেলগুলিতে কেন এবং কীভাবে এটি ব্যবহার করা যায় তা আমাকে ব্যাখ্যা করতে দিন।


ব্যাখ্যা:

নিম্নোক্ত বিবেচনা কর:

x="("
[ "$x" = "(" ] && echo yes || echo no

সমস্যা নেই; উপরেরটি কোনও ত্রুটি এবং ফলাফল দেয় না yes। আমরা স্টাফগুলি এইভাবে কাজ করার আশা করি। আপনি '1'যদি তুলনামূলক স্ট্রিংটি পছন্দ করেন তবে এর মান এবং এর মানটি পরিবর্তন করতে পারেন xএবং এটি প্রত্যাশার মতো কাজ করবে।

নোট করুন যে আসল /usr/bin/[বাইনারি একইভাবে আচরণ করে। আপনি যদি চালনা করেন যেমন '/usr/bin/[' '(' = '(' ']'কোনও ত্রুটি নেই কারণ প্রোগ্রামটি সনাক্ত করতে পারে যে আর্গুমেন্টগুলিতে একটি স্ট্রিং তুলনা অপারেশন রয়েছে।

বাগটি ঘটে যখন আমরা এবং দ্বিতীয় প্রকাশ করি expression দ্বিতীয় অভিব্যক্তিটি যতক্ষণ তা বৈধ হবে তা বিবেচ্য নয়। উদাহরণ স্বরূপ,

[ '1' = '1' ] && echo yes || echo no

ফলাফল yesএবং এটি অবশ্যই একটি বৈধ এক্সপ্রেশন; তবে, যদি আমরা দুটোকে একত্রিত করি,

[ "$x" = "(" -a '1' = '1' ] && echo yes || echo no

বাশ এক্সপ্রেশনটিকে প্রত্যাখ্যান করে যদি এবং কেবল xহয় (বা হয় !

আমরা যদি প্রকৃত [প্রোগ্রামটি ব্যবহার করে উপরেরটি চালিত করি তবে

'/usr/bin/[' "$x" = "(" -a '1' = '1' ] && echo yes || echo no

ত্রুটিটি বোধগম্য হবে: যেহেতু শেলটি পরিবর্তনশীল বিকল্পগুলি করে, /usr/bin/[বাইনারি কেবল পরামিতি ( = ( -a 1 = 1এবং সমাপ্তি গ্রহণ করে] , বোধগম্যভাবে খোলা বন্ধনীগুলি একটি সাব-এক্সপ্রেশন শুরু করে কিনা তা পার্স করতে ব্যর্থ হয়, সেখানে একটি এবং অপারেশন জড়িত রয়েছে। অবশ্যই, দুটি স্ট্রিং তুলনা হিসাবে এটিকে পার্স করা সম্ভব, তবে বন্ধুত্বপূর্ণ সাব-এক্সপ্রেশনগুলির সাথে যথাযথ অভিব্যক্তিতে প্রয়োগ করার সময় লোভের সাথে এটি করা সমস্যার কারণ হতে পারে।

সমস্যা, সত্যই, এটি শেল [ অন্তর্নির্মিত একইভাবে আচরণ করে, যেন এটি xএক্সপ্রেশনটি পরীক্ষা করার আগে এর মানকে প্রসারিত করে ।

(এই অস্পষ্টতা এবং পরিবর্তনশীল প্রসারণ সম্পর্কিত অন্যান্য, বাশ কার্যকর করার জন্য একটি বড় কারণ ছিল এবং এখন এটি ব্যবহার করার পরামর্শ দেয় [[ ... ]] পরিবর্তে পরীক্ষামূলক অভিব্যক্তি ))


কর্মক্ষেত্রটি তুচ্ছ এবং প্রায়শই পুরানো shশাঁস ব্যবহার করে স্ক্রিপ্টগুলিতে দেখা যায় । xস্ট্রিং তুলনা হিসাবে অভিব্যক্তিটি স্বীকৃত হয়েছে তা নিশ্চিত করার জন্য আপনি প্রায়শই স্ট্রিংগুলির (উভয় মানের তুলনা করা হচ্ছে) সামনে একটি "নিরাপদ" চরিত্র যুক্ত করেন :

[ "x$x" = "x(" -a "x$y" = "x1" ]

1
আমি কোনও [বিল্ট-ইন বাগের আচরণকে কল করব না । যদি কিছু হয় তবে এটি একটি অন্তর্নিহিত ডিজাইনের ত্রুটি। [[এটি একটি শেল কীওয়ার্ড , কেবল একটি অন্তর্নির্মিত কমান্ড নয়, সুতরাং এটি উদ্ধৃতি-অপসারণের আগে জিনিসগুলির দিকে নজর দেয় এবং প্রকৃতপক্ষে স্বাভাবিক শব্দ বিভাজনকে ওভাররাইড করে। যেমন [[ $x == 1 ]]ব্যবহার করার দরকার নেই "$x", কারণ একটি [[প্রসঙ্গ স্বাভাবিকের চেয়ে আলাদা different যাইহোক, [[এর ক্ষতিগুলি এড়াতে সক্ষম [। পসিক্সের মতো [আচরণ করা প্রয়োজন , এবং ব্যাশ বেশিরভাগ ক্ষেত্রেই পসিক্স মেনে চলতে বাধ্য হয় --posix, সুতরাং [কীওয়ার্ডে পরিবর্তন আনুষঙ্গিক।
পিটার কর্ডেস

আপনার workaround POSIX দ্বারা প্রস্তাবিত হয় না। কেবল দুটি কল ব্যবহার করুন [
ওয়াইল্ডকার্ড

@ পিটারকর্ডস: একদম ঠিক; ভাল যুক্তি. (আমি সম্ভবত ব্যবহৃত উচিত ছিল পরিকল্পিত পরিবর্তে সংজ্ঞায়িত আমার প্রথম অনুচ্ছেদে কিন্তু [এর আচরণ ইতিহাস predating POSIX দ্বারা ভারাক্রান্ত হচ্ছে, আমি আধুনিক শব্দ পরিবর্তে বেছে নেওয়া হয়েছে।) আমি ব্যক্তিগতভাবে ব্যবহার এড়িয়ে না [[আমার উদাহরণ স্ক্রিপ্ট-এ, কিন্তু শুধুমাত্র কারণ এটি একটি হল আমি সর্বদা বীণা বাঞ্ছনীয় সুপারিশ ব্যতীত (যেহেতু উদ্ধৃতিগুলি বাদ দেওয়া আমার কাছে দেখা স্ক্রিপ্ট বাগের সর্বাধিক সাধারণ কারণ), এবং [[আমার উদ্ধৃতি সুপারিশ না করে নিয়মের ব্যতিক্রম কেন তা ব্যাখ্যা করার জন্য আমি একটি সাধারণ অনুচ্ছেদ সম্পর্কে ভাবি নি have সন্দেহভাজন।
নামমাত্র প্রাণী

@ উইল্ডকার্ড: নং পসিক্স এই অনুশীলনের বিরুদ্ধে সুপারিশ করে না এবং এটিই গুরুত্বপূর্ণ। কোনও কর্তৃপক্ষ এই অনুশীলনের সুপারিশ করার জন্য ঘটায় না তাই এটি খারাপ করে না। প্রকৃতপক্ষে, আমি উল্লেখ করেছি যে, এটি shস্ক্রিপ্টগুলিতে ব্যবহৃত historical তিহাসিক অনুশীলন , যা POSIX মানকে মানিকতার পূর্বাভাস দেয়। পরীক্ষাগুলিতে বন্ধনীযুক্ত subexpressions এবং -aএবং -oলজিকাল অপারেটর ব্যবহার / [আরও দক্ষ যে এক্সপ্রেশন শৃঙ্খলার উপর নির্ভর করে (মাধ্যমে &&এবং ||); এটি কেবলমাত্র বর্তমান মেশিনে, পার্থক্যটি অপ্রাসঙ্গিক।
নামমাত্র প্রাণী

@ উইল্ডকার্ড: তবে, আমি ব্যক্তিগতভাবে পরীক্ষার মতামতগুলি ব্যবহার করে শৃঙ্খলা পছন্দ করি &&এবং ||এর কারণটি হ'ল আমাদের পক্ষে ব্যাগ প্রবর্তন না করেই তাদের সংরক্ষণ (পড়া, বুঝতে এবং / প্রয়োজন হলে সংশোধন করা) সহজ করে তোলে। সুতরাং, আমি আপনার পরামর্শের সমালোচনা করছি না, তবে কেবলমাত্র পরামর্শের পিছনে যুক্তি। (খুব একই কারণে জন্য .LT., .GE., ফোরট্রান 77 ইত্যাদি তুলনা অপারেটরদের অনেক বেশি মানুষের বান্ধব সংস্করণ পেয়েছিলাম <, >=পরে সংস্করণে ইত্যাদি।)
নামমাত্র প্রাণী

11

[ওরফে testদেখেছে:

 argc: 1 2 3 4  5 6 7 8
 argv: ( = 1 -a 1 = 1 ]

testপ্রথম বন্ধনে subexpresstions গ্রহণ; সুতরাং এটি মনে করে যে বাম বন্ধনী একটি সুস্পষ্ট এক্সপ্রেশনটি খোলে এবং এটি বিশ্লেষণের চেষ্টা করছে; পার্সার সূচিত =subexpression প্রথম জিনিস হিসেবে এবং মনে করেন যে এটি একটি অন্তর্নিহিত স্ট্রিং দৈর্ঘ্যের পরীক্ষা, তাই এটি খুশি হয়; subexpression এর পরে একটি ডান বন্ধনী অনুসরণ করা উচিত, এবং পরিবর্তে পার্সার সন্ধান করা 1হবে finds) । এবং এটি অভিযোগ।

কখন test ঠিক তিনটি আর্গুমেন্ট থাকে এবং মধ্যম আর্গুমেন্ট স্বীকৃত অপারেটরগুলির মধ্যে একটি, এটি প্রথমটি এবং তৃতীয় আর্গুমেন্টগুলিকে প্রথম বন্ধনীগুলিতে সুব্যাক্রেশন অনুসন্ধান না করে প্রযোজ্য।

সম্পূর্ণ বিবরণের জন্য দেখুন man bash, অনুসন্ধান করুনtest expr

উপসংহার: ব্যবহৃত পার্সিং অ্যালগরিদম testজটিল। শুধুমাত্র সহজ এক্সপ্রেশন ব্যবহার করুন এবং ব্যবহার শেল অপারেটার !, &&এবং ||তাদের একত্রিত করতে হবে।

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