কম্পিউটার টিউটোরিয়াল

ব্যাশ প্রোগ্রামিং নিপুণতা: লজিক্যাল অপারেটর ও শেল এক্সপ্যানশন ব্যাখ্যা

ব্যাশ একটি শক্তিশালী প্রোগ্রামিং ভাষা, যা কমান্ড লাইন এবং শেল স্ক্রিপ্টে ব্যবহারের জন্য आदর্শভাবে ডিজাইন করা হয়েছে। এই তিন-অংশের সিরিজ (যা আমার তিন-খণ্ডের লিনাক্স সেলফ-স্টাডি কোর্সের উপর ভিত্তি করে) কমান্ড-লাইন ইন্টারফেস (সিএলআই) এ ব্যাশকে একটি প্রোগ্রামিং ভাষা হিসেবে ব্যবহার করার কৌশলগুলি অন্বেষণ করে।

প্রথম আর্টিকেলে ব্যাশের সাথে সহজ কমান্ড-লাইন প্রোগ্রামিং, ভেরিয়েবল এবং কন্ট্রোল অপারেটর ব্যবহার নিয়ে আলোচনা করা হয়েছে। এই দ্বিতীয় আর্টিকেলে ফাইল, স্ট্রিং, সংখ্যাসূচক এবং বিবিধ লজিক্যাল অপারেটর প্রকারগুলি নিয়ে আলোচনা করা হয়েছে যা এক্সিকিউশন-ফ্লো কন্ট্রোল লজিক প্রদান করে এবং ব্যাশে বিভিন্ন ধরণের শেল এক্সপ্যানশন। সিরিজের তৃতীয় এবং চূড়ান্ত আর্টিকেলে for, while, এবং until লুপগুলি নিয়ে আলোচনা করা হবে যা পুনরাবৃত্তি অপারেশন সক্ষম করে।

লজিক্যাল অপারেটর হল একটি প্রোগ্রামে সিদ্ধান্ত গ্রহণের ভিত্তি এবং সেগুলোর ভিত্তিতে বিভিন্ন ইনস্ট্রাকশন সেট এক্সিকিউট করা। এটাকে কখনও কখনও ফ্লো কন্ট্রোল বলা হয়।

লজিক্যাল অপারেটর

ব্যাশে একটি বিশাল সেট লজিক্যাল অপারেটর রয়েছে যা কন্ডিশনাল এক্সপ্রেশনে ব্যবহার করা যেতে পারে। if কন্ট্রোল স্ট্রাকচারের সবচেয়ে বেসিক ফর্ম একটি শর্ত পরীক্ষা করে এবং যদি শর্তটি সত্য হয় তবে প্রোগ্রাম স্টেটমেন্টের একটি তালিকা এক্সিকিউট করে। তিনটি ধরনের অপারেটর রয়েছে: ফাইল, সংখ্যাসূচক, এবং অ-সংখ্যাসূচক অপারেটর। প্রতিটি অপারেটর সত্য (০) রিটার্ন করে যদি শর্ত পূরণ হয় এবং মিথ্যা (১) যদি শর্ত পূরণ না হয়।

এই তুলনামূলক অপারেটরদের ফাংশনাল সিনট্যাক্স হল এক বা দুটি আর্গুমেন্ট সাথে একটি অপারেটর যা স্কোয়ার ব্র্যাকেটের মধ্যে রাখা হয়, তারপর প্রোগ্রাম স্টেটমেন্টের একটি তালিকা যা শর্ত সত্য হলে এক্সিকিউট হয়, এবং একটি ঐচ্ছিক তালিকা যা শর্ত মিথ্যা হলে এক্সিকিউট হয়:

if [ arg1 operator arg2 ] ; then list
অথবা
if [ arg1 operator arg2 ] ; then list ; else list ; fi

তুলনায় স্পেসগুলো আপনাকμένηভাবে প্রয়োজন। একক স্কোয়ার ব্র্যাকেট, [ এবং ], হল প্রাচীন ব্যাশ সিম্বল যা test কমান্ডের সমতুল্য:

if test arg1 operator arg2 ; then list

এছাড়াও একটি আরও সাম্প্রতিক সিনট্যাক্স রয়েছে যা কিছু সুবিধা দেয় এবং কিছু সিস্টেম অ্যাডমিন পছন্দ করে। এই ফর্ম্যাটটি কিছুটা কমpatible with different versions of Bash and other shells, such as ksh (the Korn shell). It looks like:

if [[ arg1 operator arg2 ]] ; then list

ফাইল অপারেটর

ফাইল অপারেটর হল ব্যাশের মধ্যে একটি শক্তিশালী লজিক্যাল অপারেটর সেট। নিচের টেবিলে (Figure 1) ২০টিরও বেশি অপারেটর তালিকাভুক্ত করা আছে যা ব্যাশ ফাইলের ওপর সম্পাদন করতে পারে। আমি আমার স্ক্রিপ্টগুলিতে এগুলোpretty frequently ব্যবহার করি।

অপারেটর বিবরণ
-a filename সত্য যদি ফাইলটি বিদ্যমান থাকে; এটি খালি হতে পারে বা কিছু কন্টেন্ট থাকতে পারে, কিন্তু যতক্ষণ এটি আছে, এটি সত্য হবে
-b filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং একটি ব্লক স্পেশাল ফাইল হয় যেমন হার্ড ড্রাইভ /dev/sda বা /dev/sda1
-c filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং একটি ক্যারেক্টার স্পেশাল ফাইল হয় যেমন TTY ডিভাইস /dev/TTY1
-d filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং একটি ডিরেক্টরি হয়
-e filename সত্য যদি ফাইলটি বিদ্যমান থাকে; এটি উপরের -a এর মতোই
-f filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং একটি রেগুলার ফাইল হয়, ডিরেক্টরি, ডিভাইস স্পেশাল ফাইল, বা লিংক নয়
-g filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং set-group-id, SETGID সেট থাকে
-h filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং একটি সিম্বোলিক লিংক হয়
-k filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং এর "sticky" বিট সেট থাকে
-p filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং একটি নেমড পাইপ (FIFO) হয়
-r filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং পঠনযোগ্য হয়, অর্থাৎ এর রিড বিট সেট থাকে
-s filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং এর আকার শূন্য বড় হয়; একটি ফাইল যা আছে কিন্তু আকার শূন্য, সেটি মিথ্যা রিটার্ন করবে
-t fd সত্য যদি ফাইল ডেস্ক্রিপ্টর fd খোলা থাকে এবং একটি টার্মিনালকে রেফার করে
-u filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং এর set-user-id বিট সেট থাকে
-w filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং লিখনযোগ্য হয়
-x filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং এক্সিকিউটেবল হয়
-G filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং ইফেক্টিভ গ্রুপ আইডি দ্বারা স্বামित्व করা হয়
-L filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং একটি সিম্বোলিক লিংক হয়
-N filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং এটি শেষ পড়া হওয়ার পর থেকে মডিফাইড হয়েছে
-O filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং ইফেক্টিভ ইউজার আইডি দ্বারা স্বামিত্ব করা হয়
-S filename সত্য যদি ফাইলটি বিদ্যমান থাকে এবং একটি সকেট হয়
file1 -ef file2 সত্য যদি file1 এবং file2 একই ডিভাইস এবং iNode নম্বরকে রেফার করে
file1 -nt file2 সত্য যদি file1 file2-এর চেয়ে নতুন হয় (মডিফিকেশন তারিখ অনুযায়ী), অথবা file1 আছে কিন্তু file2 নেই
file1 -ot file2 সত্য যদি file1 file2-এর চেয়ে পুরনো হয়, অথবা file2 আছে কিন্তু file1 নেই

Figure 1: ব্যাশ ফাইল অপারেটরসমূহ

উদাহরণস্বরূপ, একটি ফাইলের অস্তিত্ব পরীক্ষা করুন:

[student@studentvm1 testdir]$ File="TestFile1" ; if [ -e $File ] ; then echo "The file $File exists." ; else echo "The file $File does not exist." ; fi
The file TestFile1 does not exist.
[student@studentvm1 testdir]$

এখন TestFile1 নামে একটি ফাইল তৈরি করুন পরীক্ষার জন্য। এখনও এতে কোনো ডেটা থাকতে হবে না:

[student@studentvm1 testdir]$ touch TestFile1

$File ভেরিয়েবলের মান পরিবর্তন করা সহজ, বরং একাধিক জায়গায় ফাইলের নামের টেক্সট স্ট্রিং ব্যবহার করার চেয়ে:

[student@studentvm1 testdir]$ File="TestFile1" ; if [ -e $File ] ; then echo "The file $File exists." ; else echo "The file $File does not exist." ; fi
The file TestFile1 exists.
[student@studentvm1 testdir]$

এখন একটি পরীক্ষা চালান যেন জানা যায় একটি ফাইল আছে কিনা এবং এর নন-জিরো দৈর্ঘ্য আছে কিনা, অর্থাৎ এতে ডেটা আছে কিনা। আপনি তিনটি শর্ত পরীক্ষা করতে চান: ১. ফাইলটি নেই; ২. ফাইলটি আছে কিন্তু খালি; এবং ৩. ফাইলটি আছে এবং ডেটা ধারণ করে। তাই আপনাকে আরও জটিল পরীক্ষার সেট দরকার—elif স্টানজা ব্যবহার করুন if-elif-else কনস্ট্রাক্টে সকল শর্ত পরীক্ষা করার জন্য:

[student@studentvm1 testdir]$ File="TestFile1" ; if [ -s $File ] ; then echo "$File exists and contains data." ; fi
[student@studentvm1 testdir]$

এই ক্ষেত্রে, ফাইলটি আছে কিন্তু কোনো ডেটা নেই। কিছু ডেটা যোগ করুন এবং আবার চেষ্টা করুন:

[student@studentvm1 testdir]$ File="TestFile1" ; echo "This is file $File" > $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; fi
TestFile1 exists and contains data.
[student@studentvm1 testdir]$

এটি কাজ করে, কিন্তু এটি শুধুমাত্র তিনটি সম্ভাব্য শর্তের একটি জন্য সঠিক। একটি else স্টানজা যোগ করুন যাতে কিছুটা বেশি সঠিক হয়, এবং ফাইলটি ডিলিট করুন যাতে আপনি নতুন কোডটি সম্পূর্ণরূপে পরীক্ষা করতে পারেন:

[student@studentvm1 testdir]$ File="TestFile1" ; rm $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; else echo "$File does not exist or is empty." ; fi
TestFile1 does not exist or is empty.

এখন একটি খালি ফাইল তৈরি করুন পরীক্ষার জন্য:

[student@studentvm1 testdir]$ File="TestFile1" ; touch $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; else echo "$File does not exist or is empty." ; fi
TestFile1 does not exist or is empty.

ফাইলে কিছু কন্টেন্ট যোগ করুন এবং আবার পরীক্ষা করুন:

[student@studentvm1 testdir]$ File="TestFile1" ; echo "This is file $File" > $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; else echo "$File does not exist or is empty." ; fi
TestFile1 exists and contains data.

এখন elif স্টানজা যোগ করুন একটি নন-এক্সিস্টেন্ট ফাইল এবং একটি খালি ফাইলের মধ্যে পার্থক্য করতে:

[student@studentvm1 testdir]$ File="TestFile1" ; touch $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; elif [ -e $File ] ; then echo "$File exists and is empty." ; else echo "$File does not exist." ; fi
TestFile1 exists and is empty.
[student@studentvm1 testdir]$ File="TestFile1" ; echo "This is $File" > $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; elif [ -e $File ] ; then echo "$File exists and is empty." ; else echo "$File does not exist." ; fi
TestFile1 exists and contains data.
[student@studentvm1 testdir]$

এখন আপনার কাছে একটি ব্যাশ সিএলআই প্রোগ্রাম আছে যা এই তিনটি ভিন্ন শর্তের জন্য পরীক্ষা করতে পারে… কিন্তু সম্ভাবনাগুলো অসীম।

যদি আপনি প্রোগ্রাম স্টেটমেন্টগুলিকে একটি স্ক্রিপ্টের মতো সাজান যেটি আপনি একটি ফাইলে সংরক্ষণ করতে পারেন, তবে আরও জটিল কম্পাউন্ড কমান্ডের লজিক স্ট্রাকচার বোঝা সহজ হয়। Figure 2-এ দেখানো হয়েছে এটি কীভাবে দেখাবে। if-elif-else স্ট্রাকচারের প্রতিটি স্টানজাতে প্রোগ্রাম স্টেটমেন্টের ইন্ডেন্টেশন লজিক স্পষ্ট করতে সাহায্য করে।

File="TestFile1"
echo "This is $File" > $File
if [ -s $File ]
then
echo "$File exists and contains data."
elif [ -e $File ]
then
echo "$File exists and is empty."
else
echo "$File does not exist."
fi

Figure 2: কমান্ড লাইন প্রোগ্রামটি স্ক্রিপ্টের মতো পুনর্লিখিত

এত জটিল লজিক অধিকাংশ সিএলআই প্রোগ্রামের জন্য অনেক লম্বা। যদিও যেকোনো লিনাক্স বা ব্যাশ বিল্ট-ইন কমান্ড সিএলআই প্রোগ্রামে ব্যবহার করা যায়, সিএলআই প্রোগ্রাম যত লম্বা এবং জটিল হয়, তত সাশুত একটি স্ক্রিপ্ট তৈরি করা যা একটি ফাইলে সংরক্ষিত থাকে এবং যেকোনো সময় এক্সিকিউট করা যায়।

স্ট্রিং তুলনার অপারেটর

স্ট্রিং তুলনার অপারেটর অ্যালফানিউমেরিক ক্যারেক্টার স্ট্রিংগুলোর তুলনা সক্ষম করে। এই অপারেটরগুলো قليلًا, যা Figure 3-এ তালিকাভুক্ত।

অপারেটর বিবরণ
-z string সত্য যদি স্ট্রিংয়ের দৈর্ঘ্য শূন্য হয়
-n string সত্য যদি স্ট্রিংয়ের দৈর্ঘ্য নন-জিরো হয়
string1 == string2

অথবা

string1 = string2
সত্য যদি স্ট্রিংগুলো সমান হয়; POSIX সম্মতির জন্য test কমান্ডের সাথে একক = ব্যবহার করা উচিত। [[ কমান্ডের সাথে ব্যবহৃত হলে, এটি প্যাটার্ন ম্যাচিং করে।
string1 != string2 সত্য যদি স্ট্রিংগুলো সমান না হয়
string1 < string2 সত্য যদি string1 লেক্সিকোগ্রাফিক্যালি string2-এর আগে সর্ট হয় (লোকেল-স্পেসিফিক সর্টিং সিকোয়েন্স রেফার করে)
string1 > string2 সত্য যদি string1 লেক্সিকোগ্রাফিক্যালি string2-এর পরে সর্ট হয়

Figure 3: ব্যাশ স্ট্রিং লজিক্যাল অপারেটর

প্রথমে স্ট্রিং দৈর্ঘ্য দেখুন। তুলনায় $MyVar এর চারদিকে কোটেশন থাকতে হবে যেন তুলনা কাজ করে। (আপনাকে এখনও ~/testdir-এ কাজ করা উচিত।)

[student@studentvm1 testdir]$ MyVar="" ; if [ -z "" ] ; then echo "MyVar is zero length." ; else echo "MyVar contains data" ; fi
MyVar is zero length.
[student@studentvm1 testdir]$ MyVar="Random text" ; if [ -z "" ] ; then echo "MyVar is zero length." ; else echo "MyVar contains data" ; fi
MyVar is zero length.

আপনি এভাবেও করতে পারেন:

[student@studentvm1 testdir]$ MyVar="Random text" ; if [ -n "$MyVar" ] ; then echo "MyVar contains data." ; else echo "MyVar is zero length" ; fi
MyVar contains data.
[student@studentvm1 testdir]$ MyVar="" ; if [ -n "$MyVar" ] ; then echo "MyVar contains data." ; else echo "MyVar is zero length" ; fi
MyVar is zero length

কখনও কখনও আপনাকে একটি স্ট্রিং এর সঠিক দৈর্ঘ্য জানতে হতে পারে। এটি একটি তুলনা নয়, কিন্তু সম্পর্কিত। দুর্ভাগ্যক্রমে, স্ট্রিং দৈর্ঘ্য নির্ধারণ করার কোনো সহজ উপায় নেই। এক-दুটি উপায় আছে, কিন্তু আমি মনে করি expr (evaluate expression) কমান্ড ব্যবহার করা সহজ। expr-এর ম্যান পেজ পড়ুন আরও জানতে। নোট করুন যে আপনি যে স্ট্রিং বা ভেরিয়েবল টেস্ট করছেন তার চারদিকে কোটেশন রিকোয়ার্ড।

[student@studentvm1 testdir]$ MyVar="" ; expr length "$MyVar"
0
[student@studentvm1 testdir]$ MyVar="How long is this?" ; expr length "$MyVar"
17
[student@studentvm1 testdir]$ expr length "We can also find the length of a literal string as well as a variable."
70

তুলনা অপারেটর সংক্রান্ত, আমি আমার স্ক্রিপ্টগুলিতে অনেক টেস্ট করি যেন জানা যায় দুটি স্ট্রিং সমান (অর্থাৎ অভিন্ন) কিনা। আমি এই তুলনা অপারেটরের নন-POSIX ভার্সন ব্যবহার করি:

[student@studentvm1 testdir]$ Var1="Hello World" ; Var2="Hello World" ; if [ "$Var1" == "$Var2" ] ; then echo "Var1 matches Var2" ; else echo "Var1 and Var2 do not match." ; fi
Var1 matches Var2
[student@studentvm1 testdir]$ Var1="Hello World" ; Var2="Hello world" ; if [ "$Var1" == "$Var2" ] ; then echo "Var1 matches Var2" ; else echo "Var1 and Var2 do not match." ; fi
Var1 and Var2 do not match.

এই অপারেটরগুলো নিজে আज़মায়ে দেখুন।

সংখ্যাসূচক তুলনার অপারেটর

সংখ্যাসূচক অপারেটর দুটি সংখ্যাসূচক আর্গুমেন্টের মধ্যে তুলনা করে। অন্যান্য অপারেটর ক্লাসের মতো, অধিকাংশ বোঝা সহজ।

অপারেটর বিবরণ
arg1 -eq arg2 সত্য যদি arg1 arg2-এর সমান হয়
arg1 -ne arg2 সত্য যদি arg1 arg2-এর সমান না হয়
arg1 -lt arg2 সত্য যদি arg1 arg2-এর চেয়ে ছোট হয়
arg1 -le arg2 সত্য যদি arg1 arg2-এর চেয়ে ছোট বা সমান হয়
arg1 -gt arg2 সত্য যদি arg1 arg2-এর চেয়ে বড় হয়
arg1 -ge arg2 সত্য যদি arg1 arg2-এর চেয়ে বড় বা সমান হয়

Figure 4: ব্যাশ সংখ্যাসূচক তুলনার লজিক্যাল অপারেটর

এখানে কিছু সহজ উদাহরণ। প্রথম উদাহরণে ভেরিয়েবল $X কে ১ সেট করা হয়, তারপর টেস্ট করা হয় $X ১-এর সমান কিনা। দ্বিতীয় উদাহরণে, X ০ সেট করা হয়, তাই তুলনা সত্য নয়।

[student@studentvm1 testdir]$ X=1 ; if [ $X -eq 1 ] ; then echo "X equals 1" ; else echo "X does not equal 1" ; fi
X equals 1
[student@studentvm1 testdir]$ X=0 ; if [ $X -eq 1 ] ; then echo "X equals 1" ; else echo "X does not equal 1" ; fi
X does not equal 1
[student@studentvm1 testdir]$

নিজে আরও কিছু পরীক্ষা করুন।

বিবিধ অপারেটর

এই বিবিধ অপারেটরগুলো দেখায় একটি শেল অপশন সেট আছে কিনা বা একটি শেল ভেরিয়েবলের মান আছে কিনা, কিন্তু এটি ভেরিয়েবলের মান খুঁজে বের করে না, শুধু যেনে আছে কিনা।

অপারেটর বিবরণ
-o optname সত্য যদি শেল অপশন optname সক্রিয় থাকে (ব্যাশ ম্যান পেজের বিল্ট-ইন সেট কমান্ডের -o অপশনের অধীনে অপশন لیস্ট দেখুন)
-v varname সত্য যদি শেল ভেরিয়েবল varname সেট থাকে (এসাইন করা হয়েছে)
-R varname সত্য যদি শেল ভেরিয়েবল varname সেট থাকে এবং একটি নাম রেফারেন্স হয়

Figure 5: বিবিধ ব্যাশ লজিক্যাল অপারেটর

নিজে পরীক্ষা করুন এই অপারেটরগুলো।

এক্সপ্যানশন (Expansions)

ব্যাশ অনেক ধরনের এক্সপ্যানশন এবং সাবস্টিটিউশন সমর্থন করে যা খুবই উপকারী হতে পারে। ব্যাশ ম্যান পেজ অনুযায়ী, ব্যাশের সাতটি ফর্মের এক্সপ্যানশন আছে। এই আর্টিকেলে পাঁচটি দেখা হবে: টিল্ড এক্সপ্যানশন, অ্যারিথমেটিক এক্সপ্যানশন, পাথনেম এক্সপ্যানশন, ব্রেস এক্সপ্যানশন, এবং কমান্ড সাবস্টিটিউশন।

ব্রেস এক্সপ্যানশন

ব্রেস এক্সপ্যানশন নির্বিচারে স্ট্রিং জেনারেট করার একটি পদ্ধতি। (এই টুলটি নিচে スペシャル প্যাটার্ন ক্যারেক্টার দিয়ে পরীক্ষার জন্য অনেক ফাইল তৈরি করতে ব্যবহৃত হয়েছে।) ব্রেস এক্সপ্যানশন ব্যবহার করা যায় নির্বিচারে স্ট্রিংয়ের তালিকা জেনারেট করতে এবং সেগুলো একটি নির্দিষ্ট স্থানে একটি এনক্লোজিং স্ট্যাটিক স্ট্রিং-এর ভেতরে বা স্ট্যাটিক স্ট্রিং-এর দুটি প্রান্তে ইনসার্ট করতে। এটি ভিজ্যুয়ালাইজ করা কঠিন হতে পারে, তাই সরাসরি করলে ভালো।

প্রথমে, ব্রেস এক্সপ্যানশন কী করে:

[student@studentvm1 testdir]$ echo {string1,string2,string3}
string1 string2 string3

এটা খুব উপকারী না। কিন্তু একটু ভিন্নভাবে ব্যবহার করলে কী হয়:

[student@studentvm1 testdir]$ echo "Hello "{David,Jen,Rikki,Jason}.
Hello David. Hello Jen. Hello Rikki. Hello Jason.

এটা কিছুটা উপকারী লাগছে—এটি খুব টাইপিং বাঁচাতে পারে। এখন এটি চেষ্টা করুন:

[student@studentvm1 testdir]$ echo b{ed,olt,ar}s
beds bolts bars

আরও উদাহরণ দিতে পারতাম, কিন্তু আপনি ধারণা পেয়ে গেছেন।

টিল্ড এক্সপ্যানশন

অ্যर्जুয়্যাবলি, সবচেয়ে সাধারণ এক্সপ্যানশন হল টিল্ড (~) এক্সপ্যানশন। যখন আপনি cd ~/Documents এর মতো কমান্ডে এটি ব্যবহার করেন, তবে ব্যাশ শেল এটি ইউজারের ফুল হোম ডিরেক্টরির শর্টকাট হিসেবে এক্সপ্যান্ড করে।

টিল্ড এক্সপ্যানশনের প্রভাব देखने এই ব্যাশ প্রোগ্রামগুলো ব্যবহার করুন:

[student@studentvm1 testdir]$ echo ~
/home/student
[student@studentvm1 testdir]$ echo ~/Documents
/home/student/Documents
[student@studentvm1 testdir]$ Var1=~/Documents ; echo $Var1 ; cd $Var1
/home/student/Documents
[student@studentvm1 Documents]$

পাথনেম এক্সপ্যানশন

পাথনেম এক্সপ্যানশন হল ফাইল-গ্লোবিং প্যাটার্ন, ? এবং * ক্যারেক্টার ব্যবহার করে, ম্যাচ হওয়া ডিরেক্টরির পূর্ণ নামে এক্সপ্যান্ড করার একটি ফ্যান্সি টার্ম। ফাইল গ্লোবিং হল স্পেশাল প্যাটার্ন ক্যারেক্টার যা ফাইল নাম, ডিরেক্টরি, এবং অন্যান্য স্ট্রিং ম্যাচ করার время উল্লেখযোগ্য লচিলতা প্রদান করে। এই স্পেশাল প্যাটার্ন ক্যারেক্টারগুলো একটি স্ট্রিং-এ একক, একাধিক, বা নির্দিষ্ট ক্যারেক্টার ম্যাচ করার অনুমতি দেয়।

  • ? — স্ট্রিং-এ নির্দিষ্ট লোকেশনে যেকোনো একটি ক্যারেক্টার ম্যাচ করে
  • * — স্ট্রিং-এ নির্দিষ্ট লোকেশনে শূন্য বা অধিক যেকোনো ক্যারেক্টার ম্যাচ করে

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

[student@studentvm1 testdir]$ ls 
chapter6 cpuHog.dos dmesg1.txt Documents Music softlink1 testdir6 Videos
chapter7 cpuHog.Linux dmesg2.txt Downloads Pictures Templates testdir
testdir cpuHog.mac dmesg3.txt file005 Public testdir tmp
cpuHog Desktop dmesg.txt link3 random.txt testdir1 umask.test
[student@studentvm1 testdir]$

এখন Do দিয়ে শুরু হওয়া ডিরেক্টরিগুলো লিস্ট করুন, testdir/Documents, এবং testdir/Downloads:

Documents:
Directory01 file07 file15 test02 test10 test20 testfile13 TextFiles
Directory02 file08 file16 test03 test11 testfile01 testfile14
file01 file09 file17 test04 test12 testfile04 testfile15
file02 file10 file18 test05 test13 testfile05 testfile16
file03 file11 file19 test06 test14 testfile09 testfile17
file04 file12 file20 test07 test15 testfile10 testfile18
file05 file13 Student1.txt test08 test16 testfile11 testfile19
file06 file14 test01 test09 test18 testfile12 testfile20

Downloads:
[student@studentvm1 testdir]$

এটি আপনি যা চেয়েছিলেন তা করলো না। এটা Do দিয়ে শুরু হওয়া ডিরেক্টরিগুলোর কন্টেন্ট লিস্ট করলো। শুধু ডিরেক্টরিগুলো লিস্ট করতে, তাদের কন্টেন্ট না, -d অপশন ব্যবহার করুন।

[student@studentvm1 testdir]$ ls -d Do*
Documents Downloads
[student@studentvm1 testdir]$

দুই কেসেই, ব্যাশ শেল Do* প্যাটার্নকে সেই دوটি ডিরেক্টরির নামগুলিতে এক্সপ্যান্ড করলো যা প্যাটার্নটি ম্যাচ করে। কিন্তু যদি প্যাটার্ন ম্যাচ করে এমন ফাইলও থাকে?

[student@studentvm1 testdir]$ touch Downtown ; ls -d Do*
Documents Downloads Downtown
[student@studentvm1 testdir]$

এটি ফাইলটিও দেখাচ্ছে। তাই প্যাটার্ন ম্যাচ করা যেকোনো ফাইলও তার পূর্ণ নামে এক্সপ্যান্ড হয়।

কমান্ড সাবস্টিটিউশন

কমান্ড সাবস্টিটিউশন হল এক্সপ্যানশনের একটি ফর্ম যা একটি কমান্ডের STDOUT ডেটা স্ট্রিমকে অন্য কমান্ডের আর্গুমেন্ট হিসেবে ব্যবহার করার অনুমতি দেয়; উদাহরণস্বরূপ, একটি লুপে প্রসেস করার আইটেমের তালিকা হিসেবে। ব্যাশ ম্যান পেজ বলেছে: "Command substitution allows the output of a command to replace the command name." আমি এটিকে সঠিক মনে করি যদিও একটু অস্পষ্ট।

এটির দুটি ফর্ম আছে, `command` এবং $(command)। পুরানো ফর্মে ব্যাকটিক (`) ব্যবহার করা হয়, যেখানে কমান্ডের ভেতরে ব্যাকস্ল্যাশ (\) এর আক্ষরিক অর্থ রক্ষা হয়। কিন্তু নতুন প্যারেনথেটিক্যাল ফর্মে, ব্যাকস্ল্যাশ তার স্পেশাল ক্যারেক্টারের অর্থ নেয়। নোট করুন যে প্যারেনথেটিক্যাল ফর্মে শুধু একক প্যারেনথেসিস ব্যবহার হয় কমান্ড স্টেটমেন্ট খোলা ও বন্ধ করার জন্য।

আমি সিএলআই প্রোগ্রাম এবং স্ক্রিপ্টে এই ক্ষমতা usein ব্যবহার করি যেখানে একটি কমান্ডের ফলাফল অন্য কমান্ডের আর্গুমেন্ট হিসেবে ব্যবহার করা হয়।

একটি খুব সহজ উদাহরণ দিয়ে শুরু করুন যাতে উভয় ফর্মের ব্যবহার দেখানো হয় (আরেকবার নিশ্চিত করুন testdir হল PWD):

[student@studentvm1 testdir]$ echo "Todays date is `date`"
Todays date is Sun Apr 7 14:42:46 EDT 2019
[student@studentvm1 testdir]$ echo "Todays date is $(date)"
Todays date is Sun Apr 7 14:42:59 EDT 2019
[student@studentvm1 testdir]$

seq ইউটিলিটির -w অপশন জেনারেট হওয়া সংখ্যাগুলোর সামনে লিডিং জিরো যোগ করে যাতে সেগুলো সব একই প্রস্থের হয়, অর্থাৎ ভ্যালু নির্বিশেষে একই সংখ্যক ডিজিট থাকে। এটা সংখ্যাসূচক ক্রমে সর্ট করার জন্য সহজ করে দেয়।

seq ইউটিলিটি সংখ্যার একটি সিকোয়েন্স জেনারেট করতে ব্যবহৃত হয়:

[student@studentvm1 testdir]$ seq 5
1
2
3
4
5
[student@studentvm1 testdir]$ echo `seq 5`
1 2 3 4 5
[student@studentvm1 testdir]$

এখন আপনি কিছুটা বেশি উপকারী কিছু করতে পারেন, যেমন পরীক্ষার জন্য বড় সংখ্যক খালি ফাইল তৈরি:

[student@studentvm1 testdir]$ for I in $(seq -w 5000) ; do touch file-$I ; done

এই ব্যবহারে, স্টেটমেন্ট seq -w 5000 ১ থেকে ৫,০০০ পর্যন্ত সংখ্যার একটি তালিকা জেনারেট করে। কমান্ড সাবস্টিটিউশন for স্টেটমেন্টের অংশ হিসেবে ব্যবহার করে, সংখ্যার তালিকাটি for স্টেটমেন্ট দ্বারা ফাইল নামের সংখ্যাসূচক অংশ জেনারেট করতে ব্যবহৃত হয়।

অ্যারিথমেটিক এক্সপ্যানশন

ব্যাশ ইন্টিজার ম্যাথ পারফর্ম করতে পারে, কিন্তু এটি কিছুটা জটিল (যা আপনি শীঘ্রই দেখবেন)। অ্যারিথমেটিক এক্সপ্যানশনের সিনট্যাক্স হল $((arithmetic-expression)), ডবল প্যারেনথেসিস ব্যবহার করে এক্সপ্রেশন খোলা ও বন্ধ করার জন্য।

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

আরেকবার কিছু সহজ কিছু দিয়ে শুরু করুন:

[student@studentvm1 testdir]$ echo $((1+1))
2
[student@studentvm1 testdir]$ Var1=5 ; Var2=7 ; Var3=$((Var1*Var2)) ; echo "Var 3 = $Var3"
Var 3 = 35

নিচের ডিভিশনের ফলাফল শূন্য হবে কারণ ফলাফল একের চেয়ে ছোট একটি ডেসিম্যাল ভ্যালু হবে:

[student@studentvm1 testdir]$ Var1=5 ; Var2=7 ; Var3=$((Var1/Var2)) ; echo "Var 3 = $Var3"
Var 3 = 0

এখানে একটি সহজ ক্যালকুলেশন যা আমি প্রায়শই স্ক্রিপ্ট বা সিএলআই প্রোগ্রামে করি যেন জানা যায় একটি লিনাক্স হোস্টে মোট ভার্চুয়াল মেমরি কত। free কমান্ড সেই ডেটা দেয় না:

[student@studentvm1 testdir]$ RAM=`free | grep ^Mem | awk '{print $2}'` ; Swap=`free | grep ^Swap | awk '{print $2}'` ; echo "RAM = $RAM and Swap = $Swap" ; echo "Total Virtual memory is $((RAM+Swap))" ;
RAM = 4037080 and Swap = 6291452
Total Virtual memory is 10328532

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

আমি ব্যাশ অ্যারিথমেটিক এক্সপ্যানশন মূলত স্ক্রিপ্টে সিস্টেম রিসোর্স পরিমাণ চেক করতে এবং ফলাফলের উপর ভিত্তি করে প্রোগ্রাম এক্সিকিউশন পথ বেছে নেওয়ার জন্য ব্যবহার করি।

সারসংক্ষেপ

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

সিরিজের তৃতীয় আর্টিকেলে পুনরাবৃত্তি অপারেশন انجامের জন্য লুপের ব্যবহার অন্বেষণ করা হবে।

  1. ফাইল খোলার জন্য ডিফল্ট প্রোগ্রাম পরিবর্তন করার পদ্ধতি

  2. Tkinter প্রোগ্রাম প্যাকেজ করে অন্যদের সাথে শেয়ার করার পদ্ধতি

  3. বাশে স্পেসসহ ফাইলনেম হ্যান্ডেল করার পদ্ধতি

  4. Windows সফটওয়্যার ম্যানেজমেন্ট মাস্টার করুন: Scoop দিয়ে অ্যাপ ইনস্টল ও আপডেট করুন