শেল বিল্টিন এবং শেল কীওয়ার্ডের মধ্যে পার্থক্য কী?


33

আমি এই দুটি কমান্ড চালানোর সময়, আমি পেতে

$ type cd
cd is a shell builtin
$ type if
if is a shell keyword

এটি পরিষ্কারভাবে দেখানো হয়েছে যে cdএকটি শেল বিল্টিন এবং ifএটি একটি শেল কীওয়ার্ড। তাহলে শেল বিল্টিন এবং কীওয়ার্ডের মধ্যে পার্থক্য কী?


2
সম্পর্কিত: unix.stackexchange.com/questions/267761/…
Ciro

উত্তর:


45

একটি বিল্টিন এবং কীওয়ার্ডের মধ্যে শক্তিশালী পার্থক্য রয়েছে, যেভাবে বাশ আপনার কোডটিকে বিশ্লেষণ করে। পার্থক্য সম্পর্কে কথা বলার আগে, আসুন সমস্ত কীওয়ার্ড এবং বিল্টিনগুলি তালিকাবদ্ধ করুন:

Builtins:

$ compgen -b
.         :         [         alias     bg        bind      break     
builtin   caller    cd        command   compgen   complete  compopt   
continue  declare   dirs      disown    echo      enable    eval      
exec      exit      export    false     fc        fg        getopts   
hash      help      history   jobs      kill      let       local     
logout    mapfile   popd      printf    pushd     pwd       read      
readarray readonly  return    set       shift     shopt     source    
suspend   test      times     trap      true      type      typeset   
ulimit    umask     unalias   unset     wait                          

মূলশব্দ:

$ compgen -k
if        then      else      elif      fi        case      
esac      for       select    while     until     do        
done      in        function  time      {         }         
!         [[        ]]        coproc              

লক্ষ্য করুন যে উদাহরণস্বরূপ [একটি বিল্টিন এবং এটি [[একটি কীওয়ার্ড। আমি এই দুটি ব্যবহার করব নীচের পার্থক্যটি চিত্রিত করার জন্য, যেহেতু তারা সুপরিচিত অপারেটর: প্রত্যেকে তাদের চেনে এবং নিয়মিত (বা হওয়া উচিত) ব্যবহার করে।

একটি কীওয়ার্ডটি পার্সিংয়ের প্রথম দিকে বাশ দ্বারা স্ক্যান করা এবং বোঝা যায়। এটি নিম্নলিখিত উদাহরণগুলির জন্য অনুমতি দেয়:

string_with_spaces='some spaces here'
if [[ -n $string_with_spaces ]]; then
    echo "The string is non-empty"
fi

এটি সূক্ষ্মভাবে কাজ করে এবং বাশ আনন্দের সাথে আউটপুট দেবে

The string is non-empty

মনে রাখবেন যে আমি উদ্ধৃতি দিইনি $string_with_spaces। যেখানে নিম্নলিখিত:

string_with_spaces='some spaces here'
if [ -n $string_with_spaces ]; then
    echo "The string is non-empty"
fi

দেখায় যে বাশ খুশি নয়:

bash: [: too many arguments

কেন এটি কীওয়ার্ড দিয়ে কাজ করে, বিল্টিনগুলির সাথে নয়? কারণ যখন বাশ কোডটি বিশ্লেষণ করে তখন এটি [[কোন কীওয়ার্ডটি দেখায় এবং খুব তাড়াতাড়ি বুঝতে পারে যে এটি বিশেষ। সুতরাং এটি সমাপ্তির সন্ধান ]]করবে এবং একটি বিশেষ উপায়ে অভ্যন্তরটি আচরণ করবে। একটি বিল্টিন (বা কমান্ড) একটি আসল কমান্ড হিসাবে বিবেচিত হয় যা আর্গুমেন্টের সাথে ডাকা হয়। এই শেষ উদাহরণে, বাশ বুঝতে পারে যে এটি [আর্গুমেন্টের মাধ্যমে কমান্ডটি চালানো উচিত (প্রতি লাইনে একটি দেখানো হয়েছে):

-n
some
spaces
here
]

যেহেতু পরিবর্তনশীল প্রসারণ, উদ্ধৃতি অপসারণ, পথের নাম প্রসারণ এবং শব্দ বিভাজন ঘটে। কমান্ডটি [শেলটিতে তৈরি হতে দেখা যায়, সুতরাং এটি এই যুক্তি দিয়ে এটি সম্পাদন করে, যার ফলে একটি ত্রুটি হয়, তাই অভিযোগ the

অনুশীলনে, আপনি দেখতে পাচ্ছেন যে এই পার্থক্যটি পরিশীলিত আচরণের অনুমতি দেয়, যা বিল্টিন (বা আদেশগুলি) দিয়ে সম্ভব হত না possible

এখনও অনুশীলনে রয়েছে, কীভাবে আপনি কোনও বিল্টইনকে কোনও কীওয়ার্ড থেকে আলাদা করতে পারেন? এটি সম্পাদনের জন্য একটি মজাদার পরীক্ষা:

$ a='['
$ $a -d . ]
$ echo $?
0

বাশ যখন লাইনটি পার্স করে $a -d . ], তখন এটি বিশেষ কিছু দেখায় না (অর্থাত্ কোনও উপন্যাস নয়, পুনঃনির্দেশগুলি নেই, কোনও কীওয়ার্ড নেই), সুতরাং এটি কেবল পরিবর্তনশীল সম্প্রসারণ সম্পাদন করে। পরিবর্তনশীল বিস্তারের পরে এটি দেখতে পায়:

[ -d . ]

তাই কমান্ড (builtin) executes [আর্গুমেন্ট সহ -d, .এবং ], যা, অবশ্যই সত্য (এই শুধুমাত্র পরীক্ষার কিনা .একটি ডিরেক্টরি যায়)।

এখন দেখ:

$ a='[['
$ $a -d . ]]
bash: [[: command not found

উহু. কারণ বাশ যখন এই লাইনটি দেখেন, তখন এটি বিশেষ কিছু দেখতে পায় না এবং তাই সমস্ত ভেরিয়েবল প্রসারিত করে এবং অবশেষে দেখায়:

[[ -d . ]]

এই মুহুর্তে, ওরফে সম্প্রসারণ এবং কীওয়ার্ড স্ক্যানিং দীর্ঘকাল ধরে করা হয়েছে এবং আর সম্পাদিত হবে না, সুতরাং বাশ কমান্ডটি আহ্বান করার চেষ্টা করে, এটি খুঁজে [[পায় না এবং অভিযোগ করে।

একই লাইন বরাবর:

$ '[' -d . ]
$ echo $?
0
$ '[[' -d . ]]
bash: [[: command not found

এবং

$ \[ -d . ]
$ echo $?
0
$ \[[ -d . ]]
bash: [[: command not found

এলিয়াস সম্প্রসারণও বিশেষ কিছু। আপনি নিম্নলিখিতগুলি কমপক্ষে একবারে সম্পন্ন করেছেন:

$ alias ll='ls -l'
$ ll
.... <list of files in long format> ....
$ \ll
bash: ll: command not found
$ 'll'
bash: ll: command not found

যুক্তিটি একই রকম: ভেরিয়েবল প্রসারণ এবং উদ্ধৃতি অপসারণের অনেক আগে ওরফে প্রসারণ ঘটে।


কীওয়ার্ড বনাম উপন্যাস

এখন আপনি কী মনে করেন যদি আমরা একটি উপনামকে কীওয়ার্ড হিসাবে সংজ্ঞায়িত করি তবে কী ঘটে?

$ alias mytest='[['
$ mytest -d . ]]
$ echo $?
0

ওহ, এটি কাজ করে! সুতরাং উপন্যাসের ব্যবহারকারীর নাম ব্যবহার করা যেতে পারে! জেনে ভালো লাগল.


উপসংহার: বিল্টিনগুলি সত্যিকার অর্থে কমান্ডগুলির মতো আচরণ করে: তারা যুক্তিগুলির সাথে মৃত্যুদন্ড কার্যকর করা এমন একটি ক্রিয়াটির সাথে সামঞ্জস্য করে যা প্রত্যক্ষ পরিবর্তনশীল প্রসার এবং শব্দ বিভাজন এবং গ্লোববিংয়ের মধ্য দিয়ে যায়। এটা সত্যিই শুধু একটি বহিস্থিত কমান্ড কোথাও থাকার মত /binবা /usr/binযে পরিবর্তনশীল সম্প্রসারণ ইত্যাদি নোট পরে দেওয়া আর্গুমেন্ট সহ বলা হয় যে, যখন আমি বলতে এটা সত্যিই শুধু একটি বহিস্থিত কমান্ড থাকার মত আমি শুধু আর্গুমেন্ট থেকে সম্মান, শব্দ বিভাজন, globbing সঙ্গে বলতে চাচ্ছি, পরিবর্তনশীল প্রসারণ ইত্যাদি একটি বিল্টিন শেলের অভ্যন্তরীণ অবস্থা পরিবর্তন করতে পারে!

অন্যদিকে কীওয়ার্ডগুলি খুব তাড়াতাড়ি স্ক্যান করে বোঝা যায় এবং অত্যাধুনিক শেল আচরণের অনুমতি দেয়: শেল শব্দের বিভাজন বা পথের নাম প্রসারণ ইত্যাদি নিষিদ্ধ করতে সক্ষম হবে

এখন বিল্টিনগুলি এবং কীওয়ার্ডগুলির তালিকাটি দেখুন এবং কিছুটির কীওয়ার্ড হওয়া দরকার তা বোঝার চেষ্টা করুন।


!একটি কীওয়ার্ড। মনে হয় এটি কোনও ক্রিয়াকলাপের সাথে এর আচরণের নকল করা সম্ভব হবে:

not() {
    if "$@"; then
        return false
    else
        return true
    fi
}

তবে এটি যেমন নির্মাণগুলি নিষেধ করবে:

$ ! ! true
$ echo $?
0

অথবা

$ ! { true; }
echo $?
1

এর জন্য একই time: এটির মূলশব্দ থাকা আরও শক্তিশালী যাতে এটি জটিল সংশ্লেষ কমান্ড এবং পুনঃনির্দেশগুলি সহ পাইপলাইনের সময় করতে পারে:

$ time grep '^#' ~/.bashrc | { i=0; while read -r; do printf '%4d %s\n' "$((++i))" "$REPLY"; done; } > bashrc_numbered 2>/dev/null

যদি timeকেবলমাত্র কমান্ড (এমনকি বিল্টিন) থাকে তবে এটি কেবল আর্গুমেন্টগুলি দেখতে পাবে grep, ^#এবং /home/gniourf/.bashrcএই সময়টি, এবং তারপরে পাইপলাইনের অবশিষ্ট অংশগুলি অতিক্রম করবে। তবে একটি কীওয়ার্ড দিয়ে বাশ সব কিছু পরিচালনা করতে পারে! এটি timeপুনর্নির্দেশগুলি সহ সম্পূর্ণ পাইপলাইনটি করতে পারে ! যদি timeকেবলমাত্র আদেশই থাকত তবে আমরা এটি করতে পারি না:

$ time { printf 'hello '; echo world; }

এটি চেষ্টা করুন:

$ \time { printf 'hello '; echo world; }
bash: syntax error near unexpected token `}'

এটি ঠিক করার চেষ্টা করুন (?):

$ \time { printf 'hello '; echo world;
time: cannot run {: No such file or directory

আশাহীন।


কীওয়ার্ড বনাম ওরফে?

$ alias mytime=time
$ alias myls=ls
$ mytime myls

আপনি কি মনে করেন?


সত্যই, একটি বিল্টিন হ'ল একটি কমান্ডের মতো, এটি শেলের মধ্যে নির্মিত ছাড়া অন্যদিকে কীওয়ার্ড এমন একটি জিনিস যা পরিশীলিত আচরণের সুযোগ দেয়! আমরা বলতে পারি এটি শেলের ব্যাকরণের একটি অংশ।


2
@ জোহনিটেক্সের সাথে একমত, এটি স্ট্যাকের সাইটগুলিতে আমি দেখেছি এমন একটি সবচেয়ে বিস্তৃত এবং উপযুক্ত উত্তর। ধন্যবাদ. এক সম্ভবত সম্পর্কহীন প্রশ্ন: শুধু কৌতূহল দোহাই জন্য আমি কমান্ড পূর্ববর্তী থেকে 'সাময়িকভাবে নিষ্ক্রিয় ওরফে' কার্যকারিতার জন্য ডকুমেন্টেশন খুঁজে বের করার চেষ্টা করছি =\'ব্যবহার করে man, aproposএবং helpআমি কোন ভাগ্য ছিল না করেছি। কোন ধারণা আমি এই তথ্য সন্ধান করতে যেখানে যেতে হবে? বেশিরভাগ ক্ষেত্রে যাতে ভবিষ্যতে আমি দেখতে পাই যে সেখানে কী রয়েছে, কারণ আমি মনে করি যে আমি একটি রেফারেন্স উত্স হারিয়েছি।
এনসি।

@nc: আপনি এটি স্পষ্টভাবে নথিভুক্ত পাবেন না। এটি কাজ করার কারণটি এই উত্তরে ব্যাখ্যা করা হয়েছে। শেল অপারেশন বিভাগের রেফারেন্স ম্যানুয়ালিতে আপনি সবচেয়ে কাছের সন্ধান পাবেন । আপনি দেখতে পাবেন যে উলেফ প্রসারণটি খুব তাড়াতাড়ি সম্পন্ন হয়েছে (2 আমি এই উত্তরের উপর জোর দেওয়ার চেষ্টা করেছি), উদ্ধৃতি অপসারণ, প্যারামিটার সম্প্রসারণ, গ্লোবিং ইত্যাদি পরে সম্পাদিত হয়। সুতরাং করতে অক্ষম উপনাম, আপনি মূল্য উদ্ধৃতি কিছু ব্যবহার করতে পারেন নিষেধ উপনাম হিসাবে একটি টোকেন বুঝতে, যেমন, থেকে খোলসের \ll, "ll"বা 'll'
gniourf_gniourf

1
আমি আসলে অর্ডার জিনিসটি পেয়েছি, উপনাম এবং কীওয়ার্ডগুলি বরখাস্ত করা আগে ঘটে। যেহেতু আমরা উদ্ধৃত [[ফলনশীল \[[এটা উপনাম হিসেবে পার্স না হয়ে যায়। ঠিক এখন পর্যন্ত? যেখানে আমি হারিয়েছি ব্যাকস্ল্যাশটি বুঝতে পারছিল না যে বাশের একটি উদ্ধৃত বিষয় ছিল এবং আমি এটিকে অন্যান্য নাম এবং কীওয়ার্ডের আওতায় দেখার চেষ্টা করেছি এবং পুরোপুরি হারিয়ে যেতে বসলাম ... এখন ঠিক আছে। উদ্ধৃতি বিভাগের অধীনে:> একটি অ-উদ্ধৃত ব্যাকস্ল্যাশ () হ'ল পালানোর চরিত্র।
এনসি।

1
সুতরাং আমরা সেই অপের তালিকাকে টোকেনাইজেশন হিসাবে ভাবতে পারি, এবং লিটারালকোট \[[টোকেন টাইপের একক টোকেন, [[যার বিপরীতে ওপেনটেষ্টকিওয়ার্ডটোকেন হবে এবং এর ]]জন্য অরপার সংকলন / সঠিক সিনট্যাক্সের জন্য ক্লোজটেষ্টকিওয়ার্ডটোকেন প্রয়োজন । পরবর্তীতে, (4) এ লিটারালকোইট টোকেনকে [[বুলিটিন / কমান্ড কার্যকর করার জন্য নাম হিসাবে মূল্যায়ন করা হবে , এবং (6) বাশ বার্ফ করবে কারণ কোনও [[বিল্টিন বা আদেশ নেই। খুশী হলাম। আমি সময়ের সাথে সাথে সুনির্দিষ্ট বিবরণগুলি ভুলে যেতে পারি তবে এই মুহুর্তে বাশ যেভাবে জিনিস চালায় তা আমার কাছে আরও স্পষ্ট; ধন্যবাদ.
এনসি।

9

man bashতাদের কল SHELL BUILTIN COMMANDS। সুতরাং, একটি "শেল builtin" শুধু একটি স্বাভাবিক কমান্ড মত মত হল grep, ইত্যাদি, কিন্তু একটি পৃথক ফাইল অন্তর্ভুক্ত হওয়ার পরিবর্তে, এটা হচ্ছে ব্যাশ নিজেই পাতাটা । এটি তাদের বাহ্যিক কমান্ডের চেয়ে আরও দক্ষতার সাথে সম্পাদন করে।

একটি কীওয়ার্ডটি "বাশে কঠোরভাবে কোডযুক্ত, তবে একটি বিল্টিনের মতো নয়, একটি কীওয়ার্ড নিজেই একটি কমান্ড নয়, তবে একটি কমান্ড কনস্ট্রাক্টের সাবুনিট।" আমি এর ব্যাখ্যাটি বোঝাতে চাইছি যে কীওয়ার্ডগুলির একা কোনও ফাংশন নেই, তবে কিছু করার জন্য আদেশের প্রয়োজন commands (লিঙ্ক থেকে, অন্যান্য উদাহরণ আছে for, while, do, এবং !, এবং আছে আরও আমার উত্তর আপনার অন্য প্রশ্নের।)


1
আকর্ষণীয় ঘটনা: [[ is a shell keywordকিন্তু [ is a shell builtin। কেন আমি জানি না।
স্পারহাক

1
এটি সম্ভবত historicalতিহাসিক কারণে এবং পসিক্স স্ট্যান্ডার্ড হিসাবে পুরানো বোর্ন শেলকে যথাসম্ভব ঘনিষ্ঠভাবে মেনে চলার কারণে, কারণ [দিনটিতে পৃথক কমান্ড হিসাবে উপস্থিত ছিল। [[স্ট্যান্ডার্ড দ্বারা নির্দিষ্ট করা হয়নি, তাই বিকাশকারীরা কীওয়ার্ড বা অন্তর্নির্মিত হিসাবে এটি অন্তর্ভুক্ত করতে বেছে নিতে পারেন।
সের্গেই কোলোডিয়াজনি

1

উবুন্টুর সাথে কমান্ড-লাইন ম্যানুয়ালটি কীওয়ার্ডগুলির সংজ্ঞা দেয় না, তবে অনলাইন ম্যানুয়াল (সিডেনোট দেখুন) এবং পসিক্স শেল কমান্ড ভাষার মান নির্দিষ্টকরণগুলি এগুলিকে "সংরক্ষিত শব্দ" হিসাবে উল্লেখ করে এবং উভয়ই এর তালিকা সরবরাহ করে। পসিক্স স্ট্যান্ডার্ড থেকে:

এই স্বীকৃতিটি তখনই ঘটতে পারে যখন কোনও অক্ষরের উদ্ধৃতি না দেওয়া হয় এবং যখন শব্দটি ব্যবহৃত হয়:

  • কমান্ডের প্রথম শব্দ

  • ক্ষেত্রে, ক্ষেত্রে বা ক্ষেত্রে ব্যতীত সংরক্ষিত শব্দের একটি অনুসরণ করে প্রথম শব্দ

  • কেস কমান্ডের তৃতীয় শব্দ (কেবলমাত্র এই ক্ষেত্রে কার্যকর হবে)

  • কমান্ডের জন্য তৃতীয় শব্দ (কেবলমাত্র এই ক্ষেত্রে কার্যকর হবে)

এখানে মূল কীটি হ'ল কীওয়ার্ড / সংরক্ষিত শব্দের বিশেষ অর্থ রয়েছে কারণ এগুলি শেল সিনট্যাক্সকে সহজ করে দেয়, কোডের কয়েকটি ব্লক যেমন লুপগুলি, যৌগিক কমান্ডগুলি, ব্রাঞ্চিং (যদি / কেস) বিবৃতি ইত্যাদির সিগন্যাল দেয় তবে তারা কমান্ডের বিবৃতি গঠনের অনুমতি দেয়, তবে নিজেরাই - কিছু করবেন না, এবং আসলে আপনি যেমন কীওয়ার্ড লিখুন, যদি for, until, case- শেল সম্পূর্ণ বিবৃতি, অন্যথায় আশা হবে - সিনট্যাক্স ত্রুটি:

$ for
bash: syntax error near unexpected token `newline'
$  

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

সাইড নোট

জিএনইউ সূচকটি [সংরক্ষিত শব্দ হিসাবে দেখায় , তবে এটি বাস্তবে অন্তর্নির্মিত কমান্ড। [[বিপরীতে একটি সংরক্ষিত শব্দ।

আরও দেখুন: কীওয়ার্ড, সংরক্ষিত শব্দ এবং বিল্টইনের মধ্যে পার্থক্য?

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