একটি বিল্টিন এবং কীওয়ার্ডের মধ্যে শক্তিশালী পার্থক্য রয়েছে, যেভাবে বাশ আপনার কোডটিকে বিশ্লেষণ করে। পার্থক্য সম্পর্কে কথা বলার আগে, আসুন সমস্ত কীওয়ার্ড এবং বিল্টিনগুলি তালিকাবদ্ধ করুন:
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
আপনি কি মনে করেন?
সত্যই, একটি বিল্টিন হ'ল একটি কমান্ডের মতো, এটি শেলের মধ্যে নির্মিত ছাড়া অন্যদিকে কীওয়ার্ড এমন একটি জিনিস যা পরিশীলিত আচরণের সুযোগ দেয়! আমরা বলতে পারি এটি শেলের ব্যাকরণের একটি অংশ।