কেন `[` একটি শেল বিল্টিন এবং `[[[শেল কীওয়ার্ড)?


64

আমি যতদূর জানি, [[এটির বর্ধিত সংস্করণ [, তবে আমি [[কীওয়ার্ড হিসাবে দেখলে এবং [বিল্টিন হিসাবে দেখানো হলে আমি বিভ্রান্ত হয়ে পড়ি ।

[root@server ~]# type [
[ is a shell builtin
[root@server ~]# type [[
[[ is a shell keyword

টিএলডিপি বলছে

বিল্টিন একই নামের সিস্টেম কমান্ডের প্রতিশব্দ হতে পারে তবে বাশ এটিকে অভ্যন্তরীণভাবে প্রতিবিম্বিত করে। উদাহরণস্বরূপ, ব্যাশ ইকো কমান্ডটি / বিন / প্রতিধ্বনি হিসাবে এক নয়, যদিও তাদের আচরণ প্রায় অভিন্ন।

এবং

একটি কীওয়ার্ড একটি সংরক্ষিত শব্দ, টোকেন বা অপারেটর। কীওয়ার্ডগুলির শেলের একটি বিশেষ অর্থ রয়েছে এবং প্রকৃতপক্ষে শেলের সিনট্যাক্সের বিল্ডিং ব্লক। উদাহরণ হিসাবে, যখন, যখন, কর, এবং! কীওয়ার্ড হয়। বিল্টিনের অনুরূপ, একটি কীওয়ার্ডটি হার্ড-কোড করে বাশকে দেওয়া হয় তবে বিল্টিনের বিপরীতে কোনও কীওয়ার্ড নিজেই কোনও কমান্ড নয়, বরং কমান্ড কনস্ট্রাক্টের সাবুনিট। [2]

এটি কি [এবং [[একটি কীওয়ার্ড উভয়ই তৈরি করা উচিত নয় ? আমি এখানে কি অনুপস্থিত কিছু আছে? এছাড়াও, এই লিঙ্কটি আবারও নিশ্চিত করে যে উভয় [এবং [[একই ধরণের হওয়া উচিত।



9
/ বিন / [আমার মেশিনে বিদ্যমান।
জোশুয়া

2
দু'জনের মধ্যে একটি পার্থক্যের একটি সহজ প্রমান if "[" $x -eq 3 ]হিসাবে: প্রত্যাশার মতো কাজ করে (কারণ বাশ আহ্বান করা আদেশটি সন্ধান করে [এবং এটি বিদ্যমান) তবে কাজ if "[[" $x -eq 3 ]]করে না (কারণ আবারও বাশ উপযুক্ত নামের একটি আদেশ সন্ধান করে, কিন্তু সেখানে কিছু নেই) [[কমান্ড)।
কাইল স্ট্র্যান্ড

1
@Joshua তাই করে /usr/bin/echo, কিন্তু তার মানে এই নয় যে এটি একটি নয় builtin
জোনাথন রাইনহার্ট

সমস্ত বুলিটিনগুলি যেগুলি অন্তর্নির্মিত না হলে বাহ্যিকভাবে পার্স আর্গুমেন্টগুলির উপস্থিত রয়েছে।
জোশুয়া

উত্তর:


80

[এবং এর মধ্যে পার্থক্যটি [[বেশ মৌলিক।

  • [একটি আদেশ। এর আর্গুমেন্টগুলি ঠিক একইভাবে প্রক্রিয়া করা হয় যেভাবে অন্য কোনও কমান্ড আর্গুমেন্টগুলি প্রক্রিয়াজাত করা হয়। উদাহরণস্বরূপ, বিবেচনা করুন:

    [ -z $name ]

    শেলটি শব্দটি বিভাজন এবং ফাইলের নাম উত্পাদন উভয়ই প্রসারিত করবে $nameএবং ফলস্বরূপ সম্পাদন করবে , যেমন এটি অন্য কোনও কমান্ডের জন্য হবে।

    উদাহরণ হিসাবে, নিম্নলিখিত ব্যর্থ হবে:

    $ name="here and there"
    $ [ -n $name ] && echo not empty
    bash: [: too many arguments

    এই কাজটি সঠিকভাবে পেতে, উদ্ধৃতিগুলি প্রয়োজনীয়:

    $ [ -n "$name" ] && echo not empty
    not empty
  • [[এটি একটি শেল কীওয়ার্ড এবং এর যুক্তিগুলি বিশেষ বিধি অনুসারে প্রক্রিয়া করা হয়। উদাহরণস্বরূপ, বিবেচনা করুন:

    [[ -z $name ]]

    শেলটি প্রসারিত হবে $nameতবে, অন্য কোনও কমান্ডের বিপরীতে, ফলাফলটি শব্দের বিভাজন বা ফাইলের নাম তৈরি করবে না । উদাহরণস্বরূপ, এম্বেড থাকা ফাঁকা স্থান সত্ত্বেও নিম্নলিখিতগুলি সফল হবে name:

    $ name="here and there"
    $ [[ -n $name ]] && echo not empty
    not empty

সারাংশ

[ একটি কমান্ড এবং শেলটি চালিত অন্যান্য সমস্ত কমান্ডের মতো একই নিয়মের সাপেক্ষে।

কারণ [[একটি কীওয়ার্ড, কোনও কমান্ড নয়, তবে শেলটি এটি বিশেষভাবে বিবেচনা করে এবং এটি খুব পৃথক নিয়মের অধীন পরিচালনা করে।


+1 টি। ধন্যবাদ। কোন বিধি অনুসারে কোন আদেশ এবং কীওয়ার্ড চালিত হয় তার জন্য আপনি উত্স (রেফারেন্স) দিতে পারেন?
টিম

@ টিম যে বিধিগুলির অধীনে কমান্ডগুলি পরিচালনা করে সেগুলি সম্পর্কে বিস্তারিত রয়েছে man bash। দেখুন, বিশেষত "সিম্পল কম্যান্ড এক্সপ্যানশান" এবং "কম্যান্ড এক্সিকিউশন" শিরোনামে বিভাগগুলি দেখুন। ছাড়াও [[, অন্যান্য ব্যাশ কীওয়ার্ড অন্তর্ভুক্ত if, then, while, এবং 'কেস'। কীওয়ার্ডগুলির জন্য কোনও সাধারণ নিয়ম নেই: প্রতিটি কীওয়ার্ড একটি বিশেষ ক্ষেত্রে। man bash প্রতিটি জন্য বিবরণ অন্তর্ভুক্ত।
1024

62

ইন V7 ইউনিক্স যেখানে বোর্ন শেল তার আত্মপ্রকাশ - - [বলা হত test, এবং এটি শুধুমাত্র অস্তিত্ব /bin/test। সুতরাং, কোড আপনি আজ হিসাবে লিখতে হবে:

if [ "$foo" = "bar" ] ; then ...

আপনি পরিবর্তে হিসাবে লিখতে হবে

if test "$foo" = "bar" ; then ...

এই দ্বিতীয় স্বরলিপিটি এখনও বিদ্যমান এবং আমি দেখতে পাচ্ছি যে এটি কী চলছে সে সম্পর্কে এটি আরও স্পষ্ট: আপনি একটি কমান্ড ডেকে testপাঠাচ্ছেন যা তার যুক্তিগুলি মূল্যায়ন করে এবং একটি প্রস্থান স্থিতি কোড দেয় যা ifপরবর্তীটি কী করবে তা সিদ্ধান্ত নিতে ব্যবহার করে। এই কমান্ডটি শেলের মধ্যে নির্মিত হতে পারে, বা এটি কোনও বাহ্যিক প্রোগ্রাম হতে পারে ¹

[পরে testএসেছিলেন বিকল্প হিসাবে ² এটি একটি বিল্টিন প্রতিশব্দ হতে পারে testতবে এটি /bin/[শেলগুলির জন্য আধুনিক সিস্টেমেও সরবরাহ করা হয়েছে যা বিল্টিন হিসাবে নেই।

[এবং testএকই কোড ব্যবহার করে প্রয়োগ করা যেতে পারে। এটি ওএস এক্স- এর ক্ষেত্রে /bin/[এবং এটি একই এক্সিকিউটেবলের শক্ত লিঙ্কসমূহ ³ ফলস্বরূপ, বাস্তবায়নটি সম্পূর্ণরূপে অনুসরণটিকে উপেক্ষা করে : আপনি এটি হিসাবে কল করলে এটির প্রয়োজন হয় না এবং এটি অভিযোগ করে না যদি আপনি না তা প্রদান .⁴/bin/test]/bin/[/bin/test

ইতিহাসের কোনওটিই প্রভাবিত করে না [[, কারণ এখানে কখনও আদিম প্রোগ্রাম বলা হয়নি [[। এটা যারা শাঁস এটি একটি এক্সটেনশান হিসাবে বাস্তবায়ন ভিতরে বিশুদ্ধরূপে বিদ্যমান POSIX শেল

"বিল্টিন" এবং "কীওয়ার্ড" এর মধ্যে পার্থক্যের একটি অংশ এই ইতিহাসের কারণে। এটি জন 1010 এর উত্তরে বর্ণিত [[হিসাবে বাক্যগুলি পার্স করার সিনট্যাক্সের বিধিগুলি পৃথক বলেও প্রতিফলিত হয় ⁵


পাদটিকা:

  1. আপনি যখন সেভাবে এটি দেখেন তখন এটি স্পষ্ট করে দেয় যে [অন্যান্য বেশিরভাগ প্রোগ্রামিং ভাষায় বন্ধনী এবং বন্ধনীর কাজ করার পদ্ধতি থেকে ভিন্ন, আপনাকে শেল স্ক্রিপ্টগুলিতে কেন স্পেস রাখতে হবে । শেলের কমান্ড পার্সার যদি অনুমতি দেয় তবে এটিরও অনুমতি if["$x"...দিতে হবেiftest"$x"...

  2. এটা তোলে 1980 প্রায় ঘটেছে /bin/[আমার কপি বিদ্যমান নেই প্রাচীন ইউনিক্স V7 1979 থেকে, কিংবা নেই man testউপনাম যেমন উল্লেখ করা হয়েছে। আমি একটি প্রাক রিলিজ কপি আছে সংশ্লিষ্ট man পৃষ্ঠা এন্ট্রিতে সিস্টেম তৃতীয় 1980 থেকে ম্যানুয়াল, এটা করা হয় তালিকাভুক্ত।

  3. ls -i /bin/[ /bin/test

  4. তবে এই আচরণের উপর নির্ভর করবেন না। এর ব্যাশ বিল্ট-ইন সংস্করণ [বন্ধের প্রয়োজন নেই ], এবং তার বিল্ট-ইন testবাস্তবায়ন অভিযোগ যদি আপনি হবে না এটা প্রদান।

  5. বিল্টিন বনাম বাহ্যিক কমান্ডের পার্থক্য অন্য কারণের জন্যও গুরুত্বপূর্ণ হতে পারে: দুটি বাস্তবায়ন আলাদাভাবে আচরণ করতে পারে। এটি echoঅনেক সিস্টেমে ক্ষেত্রে । যেহেতু শুধুমাত্র একটি বাস্তবায়ন রয়েছে তাই কোনও কীওয়ার্ডের জন্য এ জাতীয় কোনও তফাত দরকার নেই।


আপনি তরুণ @Warren ধন্যবাদ, কিন্তু কেন builtinএবং keywordমধ্যে পার্থক্য [এবং [[যখন উভয় একই কার্যকারিতা (সত্য যে ব্যতীত প্রদান করে [[তুলনায় আরও বেশি বৈশিষ্ট্য দিয়ে আসে [)?
শ্রী

2
[[@ শ্রী কীওয়ার্ড হওয়ায় বাশকে এমন জিনিসগুলি করতে দেয় যা দিয়ে সম্ভব হয় না [- উদাহরণস্বরূপ উদ্ধৃতি দেওয়া অনেক সময় প্রয়োজন হয় না, কারণ শেলটি সচেতন যে এটি একটি পরিবর্তনশীল। এটি বলতে গেলে, কোনও কীওয়ার্ড ব্যবহার করা হলে কমান্ড লাইনের প্রক্রিয়াকরণ প্রভাবিত হয়, তবে কোনও বিল্টিন ব্যবহার করা হয় না - এটি অনেক পরে ঘটে।
মারু

1
নোট করুন যে ভি 7 বোর্ন শেলটির [কোডটি একটি অন্তর্নির্মিত দেখায় , তবে কোডটি মন্তব্য করা হয়নি।
স্টাফেন চেজেলাস

cdএটি অন্তর্নির্মিত, তবে এটি কোনও ছায়া দেয় না ( cdবাহ্যিক প্রোগ্রাম হিসাবে প্রয়োগ করা যায় না)।
পাওলো ইবারম্যান

2
এটি একটি দুর্দান্ত historicalতিহাসিক সংক্ষিপ্তসার, তবে এটি উপরে (আইএমও) গুরুত্বপূর্ণ বিবরণটি ছাড়িয়েছে, উপরে মুড়ু দ্বারা চিহ্নিত করা হয়েছে এবং তাদের উত্তরে জন 1024 লিখেছেন যে [[একটি কীওয়ার্ড তৈরি করা শেলটিকে তার যুক্তিগুলির জন্য বিশেষ পার্সিং বিধি ব্যবহার করতে দেয়। সুতরাং, হায়রে, আমার উপন্যাস জন 1024 এ যায়।
ইলমারি করোনেন

3

[মূলত এটি ছিল কেবল একটি বাহ্যিক আদেশ, যার অন্য নাম /bin/test। তবে কয়েকটি কমান্ড, যেমন [এবং echo, শেল স্ক্রিপ্টগুলিতে এত ঘন ঘন ব্যবহৃত হয় যে শেল প্রয়োগকারীরা প্রতিবার ব্যবহার করার সময় অন্য কোনও প্রক্রিয়া চালানোর পরিবর্তে সরাসরি শেলটিতে কোডটি অনুলিপি করার সিদ্ধান্ত নিয়েছে। এটি এই কমান্ডগুলিকে "বিল্টিনস" হিসাবে রূপান্তরিত করেছে, যদিও আপনি এখনও পুরো পথ দিয়ে বহিরাগত প্রোগ্রামটি চালিত করতে পারেন।

[[অনেক পরে এসেছিল। যদিও বিল্টিনটি শেলের মধ্যে অভ্যন্তরীণভাবে প্রয়োগ করা হয়েছে, তবে এটি বাহ্যিক কমান্ডের মতো পার্স করা হয়েছে। জন 1024 এর উত্তরে যেমন ব্যাখ্যা করা হয়েছে, তার অর্থ এই যে অব্যক্ত ভেরিয়েবলগুলি তাদের উপর শব্দ বিভাজন করবে এবং টোকেনগুলি পছন্দ করবে >এবং <I / O পুনঃনির্দেশ হিসাবে প্রসেস করা হবে। এটি জটিল তুলনা প্রকাশকে অসুবিধে করেছে। [[শেল সিনট্যাক্স হিসাবে তৈরি হয়েছিল, যাতে এটি আদর্শিকেন্দ্রিকভাবে পার্স করা যায়। মধ্যে [[ভেরিয়েবল শব্দ বিভাজন পাবেন না, <এবং >তুলনা অপারেটরদের হিসাবে ব্যবহার করা যেতে পারে, =ইত্যাদি পরবর্তী পরামিতি উদ্ধৃত করা হয় কিনা বা না নির্ভর করে ভিন্নভাবে আচরণ করতে এই সব সুবিধা যে হয় [[ঐতিহ্যগত তুলনায় সহজে ব্যবহারযোগ্য করতে [কমান্ড / builtin।

এগুলি কেবল [সিনট্যাক্স হিসাবে এটিকে সহজেই পুনর্নির্মাণ করতে পারেনি কারণ এটি লক্ষ লক্ষ স্ক্রিপ্টগুলিতে একটি বেমানান পরিবর্তন হত। নতুন [[সিনট্যাক্স ব্যবহার করে , যা আগে বিদ্যমান ছিল না, তারা upর্ধ্বমুখী সামঞ্জস্যপূর্ণ উপায়ে এটি যেভাবে ব্যবহৃত হয়েছে তা পুরোপুরি পুনর্নির্মাণ করতে পারে।

এটি বিবর্তনের মতো $((...)), যা পাটিগণিতের এক্সপ্রেশনগুলির জন্য সিনট্যাক্সের ফলস্বরূপ , যা বেশিরভাগ theতিহ্যগত exprকমান্ডকে প্রতিস্থাপন করেছে ।


0

নতুন [[bashএকটি হল অপ্টিমাইজেশান এর [

সর্বোত্তম [যখন এটি ঘন ঘন ব্যবহৃত হচ্ছে একটি তুচ্ছ অপারেশন করতে হবে, এক বড় অপূর্ণতা আছে: এটি একটি নতুন প্রক্রিয়া প্রত্যেক সময় ডিম হবে:
(এটা ঠিক তুলনা জন্য একটি নতুন অ্যাড্রেস স্পেস সৃষ্টি 0এবং 1! যতবার)

আমি মনে করি যে সংযোজনের একটি মূল বিষয়টি অতিরিক্ত প্রক্রিয়া না [[করে ভিতরে প্রকাশের মূল্যায়ন করছিল [evalu কিন্তু কীভাবে [কাজ করছে তা পরিবর্তন করা যায়নি - এটি প্রচুর বিভ্রান্তি ও সমস্যা তৈরি করবে। সুতরাং, আরও কার্যকর পদ্ধতিতে একটি শেল বিল্টিন কমান্ড সহ নতুন নামটি প্রয়োগ করা হয়েছিল optim
এটি পার্শ্ব প্রতিক্রিয়া হিসাবে শেল সিনট্যাক্সের কীওয়ার্ডে পরিণত হয়েছে।

সেই সময়টি [প্রথমে ব্যবহৃত হয়েছিল, এটি বাহ্যিক প্রক্রিয়া সহ এটি করার সঠিক উপায়


5
মনে রাখবেন যে যদিও [এটি প্রাথমিকভাবে বাহ্যিক কমান্ড ছিল তবে এটি শেলটিতে একটি বিল্ট-ইন হিসাবে যুক্ত করা হয়েছিল, সম্ভবত ইউনিক্স সিস্টেম তৃতীয় প্রকাশের সময় এবং ইউনিক্স সিস্টেম ভি প্রকাশের আগে অবশ্যই। সুতরাং, 'অতিরিক্ত প্রক্রিয়া' যুগে যুগে সমস্যা হয়নি। তবে সিনট্যাক্সটি অপরিবর্তিত রয়েছে - এটি বহিরাগত কমান্ড হবে বলে মনে করা হয়েছিল।
জোনাথন লেফলার

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