শেল লজিকাল অপারেটরগুলির নজরে &&, ||


126

ল্যাজিকাল অপারেটর অগ্রাধিকার কীভাবে ব্যাশে কাজ করে তা বোঝার চেষ্টা করছি। উদাহরণস্বরূপ, আমি আশা করতাম, নিম্নলিখিত কমান্ডটি কোনও কিছু প্রতিধ্বনিত করে না।

true || echo aaa && echo bbb

তবে আমার প্রত্যাশার বিপরীতে bbbমুদ্রিত হয়ে যায়।

কেউ দয়া করে ব্যাখ্যা করতে পারেন, কীভাবে আমি বাশগুলিতে যৌগিক &&এবং ||অপারেটরদের বোধ করতে পারি ?

উত্তর:


127

অনেক কম্পিউটার ভাষায়, একই নজিরযুক্ত অপারেটরগুলি বাম- সাহচর্যমূলক হয় । এটি হ'ল গ্রুপিং স্ট্রাকচারের অনুপস্থিতিতে প্রথমে বামতম ক্রিয়াকলাপগুলি কার্যকর করা হয়। বাশ এই নিয়মের ব্যতিক্রম নয়

এটি গুরুত্বপূর্ণ কারণ বাশে, &&এবং ||একই নজির রয়েছে।

সুতরাং আপনার উদাহরণে যা ঘটে তা হ'ল প্রথমে বামতম অপারেশন ( ||) করা হয়:

true || echo aaa

যেহেতু trueস্পষ্টত সত্য, ||অপারেটর শর্ট সার্কিট এবং পুরো বিবৃতিটি echo aaaআপনার প্রত্যাশা মতো মূল্যায়ন করার প্রয়োজন ছাড়াই সত্য বলে বিবেচিত হবে। এখন এটি সঠিকতম অপারেশন করা অবশেষ:

(...) && echo bbb

যেহেতু প্রথম ক্রিয়াকলাপটি সত্য হিসাবে মূল্যায়ন করা হয়েছে (যেমন একটি 0 প্রস্থান স্থিতি ছিল), এটি আপনি চালিয়ে যাচ্ছেন

true && echo bbb

সুতরাং &&শর্ট সার্কিট হবে না, যে কারণে আপনি bbbপ্রতিধ্বনি দেখছেন ।

আপনি একই আচরণ পাবেন

false && echo aaa || echo bbb

মন্তব্য ভিত্তিক নোটস

  • আপনি জানানো হচ্ছে যে বাঁ-associativity নিয়ম শুধুমাত্র অনুসৃত যখন উভয় অপারেটর একই প্রাধান্য। এই ক্ষেত্রে যখন আপনি যেমন কীওয়ার্ড সঙ্গে একত্রে এই অপারেটর ব্যাবহার নয় [[...]]বা ((...))বা ব্যবহার -oএবং -aআর্গুমেন্ট হিসাবে অপারেটার testবা [কমান্ড। এই জাতীয় ক্ষেত্রে, এবং ( &&বা -a) ওআর ( ||বা -o) এর চেয়ে বেশি অগ্রাধিকার নেয় । এই বক্তব্যটি স্পষ্ট করার জন্য স্টিফেন চেজেলাসের মন্তব্যে ধন্যবাদ।
  • দেখে মনে হয় সি এবং সি-এর মতো ভাষাগুলিতে &&উচ্চতর প্রাধান্য রয়েছে ||যার কারণেই আপনি সম্ভবত আপনার মূল নির্মাণের মতো আচরণ করার প্রত্যাশা করেছিলেন

    true || (echo aaa && echo bbb). 

    এটি বাশের ক্ষেত্রে নয়, তবে উভয় অপারেটরের একই নজির রয়েছে, এ কারণেই বাম বাম-সহযোগীতা রুলটি ব্যবহার করে আপনার অভিব্যক্তি পার্স করে। এটি আনার জন্য কেভিনের মন্তব্যে ধন্যবাদ।

  • এমন সমস্ত ঘটনাও ঘটতে পারে যেখানে সমস্ত 3 টি এক্সপ্রেশন মূল্যায়ন করা হয়। যদি প্রথম কমান্ডটি শূন্য-বহির্গমন স্থিতি ফিরে আসে তবে ||শর্ট সার্কিটটি ব্যবহার করে না এবং দ্বিতীয় কমান্ডটি কার্যকর করা যায়। যদি দ্বিতীয় কমান্ডটি শূন্য প্রস্থান স্থিতি দিয়ে ফিরে আসে, তবে এটি &&শর্ট সার্কিট হিসাবে তৃতীয় হবে না এবং তৃতীয় কমান্ড কার্যকর হবে। এটিকে সামনে আনার জন্য ইগনাসিও ওয়াজকেজ-আব্রামের মন্তব্যকে ধন্যবাদ জানাই।


26
আরও কিছুটা বিভ্রান্তি যুক্ত করার জন্য একটি পুষ্টির নোট: &&এবং ||শেল অপারেটরগুলির যেমন cmd1 && cmd2 || cmd3পূর্বনীতি রয়েছে, তখন &&ইন ((...))এবং [[...]]এর অগ্রাধিকার রয়েছে ||( ((a || b && c))হয় ((a || (b && c))))। একই -a/ -oজন্য test/ [এবং findএবং &/ |ইন যায় expr
স্টাফেন চেজেলাস

16
সি-এর মতো ভাষাগুলিতে এর &&চেয়ে বেশি প্রাধান্য রয়েছে ||, সুতরাং ওপির প্রত্যাশিত আচরণটি ঘটবে। এই জাতীয় ভাষায় ব্যবহৃত অযত ব্যবহারকারীরা বুঝতে পারেন না যে ব্যাশে তাদের একই প্রাধান্য রয়েছে, সুতরাং এটি আরও স্পষ্টভাবে উল্লেখ করা উপযুক্ত যে বাশের ক্ষেত্রেও তাদের একই নজির রয়েছে।
কেভিন

আরও মনে রাখবেন যে পরিস্থিতি রয়েছে যেখানে তিনটি কমান্ড চালানো যেতে পারে, অর্থাত্ মিডল কমান্ড যদি সত্য বা মিথ্যা ফিরে আসতে পারে ।
Ignacio Vazquez-Abram

@ কেভিন দয়া করে সম্পাদিত উত্তর পরীক্ষা করুন।
জোসেফ আর।

1
আজ, আমার জন্য, "বাশ অপারেটর অগ্রাধিকার" শীর্ষে থাকা গুগল হিট হচ্ছে tldp.org/LDP/abs/html/opprecedence.html ... যা দাবি করেছে যে && এর তুলনায় || তবুও @ জোসেফআর স্পষ্টতই সঠিক ডি ফ্যাক্টো এবং ডি জুরও। ড্যাশ একই আচরণ করে এবং pubs.opengroup.org/onlinepubs/009695399/utilities/… এ "অগ্রাধিকার" অনুসন্ধান করে , আমি দেখতে এটি একটি পজিক্স প্রয়োজনীয়তা, তাই আমরা এটির উপর নির্ভর করতে পারি। বাগ রিপোর্টিংয়ের জন্য আমি যা কিছু পেয়েছি তা হ'ল লেখকের ইমেল ঠিকানা, যা অবশ্যই গত ছয় বছরে মারা গেছে death আমি যাইহোক চেষ্টা করব ...
মার্টিন ডরে

62

আপনি যদি একাধিক জিনিস আপনার অবস্থার উপর নির্ভর করতে চান তবে তাদের গোষ্ঠীবদ্ধ করুন:

true || { echo aaa && echo bbb; }

যে কিছুই প্রিন্ট, যখন

true && { echo aaa && echo bbb; }

উভয় স্ট্রিং মুদ্রণ।


এটি হওয়ার কারণটি জোসেফের তুলনায় অনেক বেশি সহজ। মনে রাখবেন বাশ কী ||এবং কী করে &&। এটি পূর্ববর্তী কমান্ডের রিটার্নের স্থিতি সম্পর্কে। আপনার কাঁচা আদেশটি দেখার আক্ষরিক উপায় হ'ল:

( true || echo aaa ) && echo bbb

প্রথম কমান্ডটি ( true || echo aaa) উপস্থিত রয়েছে 0

$ true || echo aaa; echo $?
0
$ true && echo aaa; echo $?
aaa
0

$ false && echo aaa; echo $?
1
$ false || echo aaa; echo $?
aaa
0

7
+1 ওপির উদ্দেশ্যযুক্ত ফলাফল অর্জনের জন্য। মনে রাখবেন যে আপনি যে প্রথম বন্ধনী স্থাপন করেছেন (true || echo aaa) && echo bbbতা হ'ল আমি তৈরি করছি।
জোসেফ আর।

1
বিশ্বের এই দিকে @ অলি দেখতে ভাল লাগল।
ব্রায়াম

7
;একেবারে শেষে অর্ধ-কলামটি নোট করুন । এটি না হলে, এটি কাজ করবে না!
সার্জ Stroobandt

2
আমি এটির সাথে সমস্যায় পড়ছিলাম কারণ আমি শেষ আদেশের (যেমন echo bbb;প্রথম উদাহরণগুলিতে) পেছনের আধা-কোলন অনুপস্থিত ছিল । একবার যখন আমি বুঝতে পারি যে আমি এটি মিস করছি, এই উত্তরটি আমি যা খুঁজছিলাম ঠিক সেটাই ছিল। আমি যা চেয়েছিলাম তা কীভাবে সম্পাদন করতে হবে তা নির্ধারণ করতে আমাকে সহায়তা করার জন্য +1!
ডক্টর জে

5
বিভ্রান্ত (...){...}স্বরলিপি দ্বারা যে কারও পক্ষে মূল্যবান পাঠ : কমান্ড গ্রুপিং ম্যানুয়াল
আন্টার

16

&&এবং ||অপারেটরদের হয় না যদি-তারপর-অন্য জন্য ইনলাইন প্রতিস্থাপন সঠিক। যদিও সাবধানে ব্যবহার করা হয়, তারা একই জিনিসটি অনেক কিছু সম্পাদন করতে পারে।

একটি একক পরীক্ষা সোজা এবং দ্ব্যর্থহীন ...

[[ A == A ]]  && echo TRUE                          # TRUE
[[ A == B ]]  && echo TRUE                          # 
[[ A == A ]]  || echo FALSE                         # 
[[ A == B ]]  || echo FALSE                         # FALSE

তবে একাধিক পরীক্ষা যুক্ত করার চেষ্টা করলে অপ্রত্যাশিত ফলাফল হতে পারে ...

[[ A == A ]]  && echo TRUE   || echo FALSE          # TRUE  (as expected)
[[ A == B ]]  && echo TRUE   || echo FALSE          # FALSE (as expected)
[[ A == A ]]  || echo FALSE  && echo TRUE           # TRUE  (as expected)
[[ A == B ]]  || echo FALSE  && echo TRUE           # FALSE TRUE   (huh?)

মিথ্যা এবং সত্য উভয়ই কেন প্রতিধ্বনিত হয়?

এখানে যা ঘটছে তা হ'ল আমরা বুঝতে পারিনি &&এবং ||ওভারলোডেড অপারেটররা শর্তসাপেক্ষ টেস্ট বন্ধনীর ভিতরে আলাদা আলাদাভাবে কাজ করে [[ ]]যা তারা এখানে এবং ওআর (শর্তসাপেক্ষ কার্যকরকরণ) তালিকার তুলনায় করে।

বাশ ম্যানপেজ থেকে (সম্পাদিত) ...

তালিকাসমূহ

তালিকাটি হ'ল এক বা একাধিক পাইপলাইনগুলির একটি ক্রম যা অপারেটরগুলির মধ্যে একটি দ্বারা পৃথক;, &, &&, বা ││, এবং বিকল্পভাবে; এই তালিকা অপারেটরগুলির মধ্যে, && এবং equal এর পরে সমান প্রাধান্য রয়েছে; এবং & এর সমান নজরে রয়েছে।

এক বা একাধিক নতুন লাইনের একটি ক্রম কমান্ডটি সীমাবদ্ধ করতে সেমিকোলনের পরিবর্তে একটি তালিকায় উপস্থিত হতে পারে।

যদি কমান্ডটি কন্ট্রোল অপারেটর & এর মাধ্যমে সমাপ্ত হয়, তবে শেলটি একটি সাবশেলের পটভূমিতে কমান্ডটি কার্যকর করে। শেলটি কমান্ডটি শেষ হওয়ার জন্য অপেক্ষা করে না, এবং ফেরতের স্থিতি 0 হয় কমান্ড a দ্বারা পৃথক; ধারাবাহিকভাবে মৃত্যুদন্ড কার্যকর করা হয়; শেল প্রতিটি কমান্ডের জন্য ঘুরে দাঁড়ানোর জন্য অপেক্ষা করে। রিটার্নের স্থিতি হ'ল শেষ আদেশের নির্বাহ স্থিতি।

AND এবং OR তালিকাগুলি যথাক্রমে && এবং and কন্ট্রোল অপারেটরগুলি দ্বারা পৃথক করা আরও পাইপলাইনগুলির একটির ক্রম। এবং এবং ওআর তালিকা বাম সাহসিকতার সাথে সম্পাদিত হয়।

একটি এবং তালিকাটির ফর্ম রয়েছে ...
command1 && command2
কমান্ড 2 কার্যকর করা হয় এবং কেবল যদি, কমান্ড 1 শূন্যের প্রস্থান স্থিতি দেয়।

একটি OR তালিকাতে ফর্ম রয়েছে ...
command1 ││ command2
কমান্ড 2 কার্যকর করা হয় এবং কেবলমাত্র যদি কমান্ড 1 একটি শূন্য-বহির্গমন স্থিতি ফিরে আসে।

AND এবং OR তালিকাগুলির রিটার্নের স্থিতি হ'ল তালিকার মধ্যে কার্যকর হওয়া শেষ কমান্ডের প্রস্থান স্থিতি।

আমাদের শেষ উদাহরণে ফিরে ...

[[ A == B ]]  || echo FALSE  && echo TRUE

[[ A == B ]]  is false

     ||       Does NOT mean OR! It means...
              'execute next command if last command return code(rc) was false'

 echo FALSE   The 'echo' command rc is always true
              (i.e. it successfully echoed the word "FALSE")

     &&       Execute next command if last command rc was true

 echo TRUE    Since the 'echo FALSE' rc was true, then echo "TRUE"

ঠিক আছে. যদি এটি সঠিক হয়, তবে শেষ উদাহরণের পরবর্তী কেন কিছু কিছু প্রতিধ্বনিত হয়?

[[ A == A ]]  || echo FALSE  && echo TRUE


[[ A == A ]]  is true

     ||       execute next command if last command rc was false.

 echo FALSE   Since last rc was true, shouldn't it have stopped before this?
                Nope. Instead, it skips the 'echo FALSE', does not even try to
                execute it, and continues looking for a `&&` clause.

     &&       ... which it finds here

 echo TRUE    ... so, since `[[ A == A ]]` is true, then it echos "TRUE"

একাধিক &&বা ||কমান্ড তালিকায় ব্যবহার করার সময় যুক্তি ত্রুটির ঝুঁকি বেশ বেশি।

প্রস্তাবনা

একক &&বা ||কমান্ড তালিকার প্রত্যাশার মতো কাজ করে তাই এটি নিরাপদ। যদি এমন পরিস্থিতি হয় যেখানে আপনার আর একটি ধারা প্রয়োজন হয় না, তবে নীচের মতো কিছু অনুসরণ করা আরও পরিষ্কার হতে পারে (কোঁকড়া ধনুর্বন্ধনী শেষ 2 কমান্ডের গোষ্ঠীকরণের জন্য প্রয়োজনীয়) ...

[[ $1 == --help ]]  && { echo "$HELP"; exit; }

একাধিক &&এবং ||অপারেটর, যেখানে সর্বশেষ ব্যতীত প্রতিটি কমান্ড একটি পরীক্ষা (যেমন বন্ধনীগুলির অভ্যন্তরে [[ ]]) থাকে, সাধারণত সমস্ত হিসাবে সুরক্ষিত থাকে তবে শেষ অপারেটর প্রত্যাশা অনুযায়ী আচরণ করে। শেষ অপারেটর আরও thenবা একটি elseশৃঙ্খলার মতো কাজ করে ।


0

আমি এটির দ্বারাও বিভ্রান্ত হয়ে পড়েছিলাম তবে বাশ যেভাবে আপনার বক্তব্যটি পড়বে (যেহেতু এটি প্রতীকগুলি বাম থেকে ডানদিকে পড়ে) সে সম্পর্কে আমি কীভাবে চিন্তা করি:

  1. প্রতীক পাওয়া গেছে true। কমান্ডের সমাপ্তি শেষ হয়ে গেলে এটি মূল্যায়ন করা দরকার। এই মুহুর্তে, এটির কোনও যুক্তি আছে কিনা তা জানেন না। এক্সিকিউশন বাফারে স্টোর কমান্ড।
  2. প্রতীক পাওয়া গেছে ||। পূর্ববর্তী কমান্ডটি এখন সম্পূর্ণ, সুতরাং এটি মূল্যায়ন করুন। কমান্ড (বাফার) মৃত্যুদন্ড কার্যকর করা হচ্ছে: true। মূল্যায়নের ফলাফল: 0 (অর্থাত্ সাফল্য)। "সর্বশেষ মূল্যায়ন" রেজিস্টারে 0 ফলাফল ফলাফল। এখন ||নিজেই প্রতীক বিবেচনা করুন । এটি সর্বশেষ মূল্যায়নের শূন্য-শুরুর ফলাফলের উপর নির্ভর করে। "সর্বশেষ মূল্যায়ন" রেজিস্টারটি পরীক্ষা করা হয়েছে এবং পাওয়া গেছে 0 যেহেতু 0 শূন্য নয়, নিম্নলিখিত কমান্ডটি মূল্যায়ন করার প্রয়োজন নেই।
  3. প্রতীক পাওয়া গেছে echo। এই প্রতীকটিকে উপেক্ষা করতে পারেন, কারণ নিম্নলিখিত কমান্ডটি মূল্যায়ন করার প্রয়োজন ছিল না।
  4. প্রতীক পাওয়া গেছে aaa। এটি কমান্ডের আর্গুমেন্ট echo(3), তবে যেহেতু echo(3) মূল্যায়ন করার প্রয়োজন ছিল না, তাই এটি উপেক্ষা করা যায়।
  5. প্রতীক পাওয়া গেছে &&। এটি শেষ মূল্যায়ন শূন্য হওয়ার ফলাফলের উপর নির্ভর করে। "সর্বশেষ মূল্যায়ন" রেজিস্টারটি পরীক্ষা করা হয়েছে এবং 0 পাওয়া গেছে। যেহেতু 0 শূন্য, নীচের কমান্ডটি মূল্যায়ন করা দরকার।
  6. প্রতীক পাওয়া গেছে echo। কমান্ডের সমাপ্তির পরে এই কমান্ডটি মূল্যায়ন করা দরকার, কারণ নিম্নলিখিত কমান্ডটি মূল্যায়ন করা দরকার ছিল। এক্সিকিউশন বাফারে স্টোর কমান্ড।
  7. প্রতীক পাওয়া গেছে bbb। এটি আদেশ echo(6) আর্গুমেন্ট । যেহেতু echoমূল্যায়ন করা দরকার, তাই bbbএক্সিকিউশন বাফারে যুক্ত করুন।
  8. লাইনের শেষ প্রান্তে পৌঁছেছে। পূর্ববর্তী কমান্ডটি এখন সম্পূর্ণ এবং মূল্যায়ন করার প্রয়োজন নেই। কমান্ড (বাফার) মৃত্যুদন্ড কার্যকর করা হচ্ছে: echo bbb। মূল্যায়নের ফলাফল: 0 (অর্থাত্ সাফল্য)। "সর্বশেষ মূল্যায়ন" রেজিস্টারে 0 ফলাফল ফলাফল।

এবং অবশ্যই, শেষ পদক্ষেপটি bbbকনসোলে প্রতিধ্বনিত হওয়ার কারণ ।

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