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

Bash ফাংশন মাস্টার করুন: শেল স্ক্রিপ্টিং-এ গভীরে যান (পার্ট VI)

ফাংশন যেকোনো প্রোগ্রামিং ল্যাঙ্গুয়েজে একটি গুরুত্বপূর্ণ ভূমিকা পালন করে। অনেক আসল প্রোগ্রামিং ল্যাঙ্গুয়েজের মতো, bash-এও ফাংশন থাকে যা সীমিত বাস্তবায়নে ব্যবহৃত হয়।

ফাংশন কী?

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

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

কেন ফাংশন লিখি?

  1. কোড পুনরায় ব্যবহার করতে সাহায্য করে।
  2. প্রোগ্রামের পঠনযোগ্যতা উন্নত করে।
  3. প্রোগ্রামের ভিতরে ভেরিয়েবলের দক্ষ ব্যবহার নিশ্চিত করে।
  4. প্রোগ্রামটি অংশ অংশে টেস্ট করতে দেয়।
  5. প্রোগ্রামকে সাব-স্টেপের একটি গুচ্ছ হিসেবে প্রদর্শন করে।

শেল স্ক্রিপ্টে ফাংশন

শেল স্ক্রিপ্টে ফাংশন লেখার সাধারণ সিনট্যাক্স নিচের способগুলো রয়েছে।

function func_name {
    ... commands ...
}
or
func_name ( ) {
    ... commands ...
}
Opening curly braces can also be used in the second line as well.
func_name ( ) {
    ... commands ...
}

আপনি সবসময় এই ফাংশন ব্লকে যেকোনো বৈধ কমান্ড লিখতে আজাদ, যেভাবে আমরা সাধারণত শেল স্ক্রিপ্টে করি। এখন একটি ছোট ফাংশন নিয়ে একটি সিম্পল স্ক্রিপ্ট লিখতে চেষ্টা করি।

#!/bin/bash
call_echo ( ) {
    echo 'This is inside function'
}
op=$1
if [ $# -ne 1 ]; then
    echo "Usage: $0 <1/0>"
else
    if [ $1 = 0 ] ; then
        echo 'This is outside function'
    elif [ $1 = 1 ] ; then
        call_echo
    else
        echo 'Invalid argument'
    fi
fi
exit 0

ফাংশন ডেফিনিশন অবশ্যই প্রথম কলের আগে থাকতে হবে। 'ফাংশন ডিক্লেয়ার করা' এর কোনো ধারণা নেই কল করার আগে। এবং আমরা সবসময় ফাংশন ভিতরে ফাংশন নেস্ট করতে পারি।

নোট:- খালি ফাংশন লিখা সবসময় সিনট্যাক্স এরর দেয়।

যখন একই ফাংশন একাধিক বার ডিফাইন করা হয়, চূড়ান্ত ভার্সনটি হলো যা ইনভোক করা হয়। একটি উদাহরণ নেই।

#!/bin/bash
func_same ( ) {
    echo 'First definition'
}
func_same ( ) {
    echo 'Second definition'
}
func_same
exit 0

প্যারামিটার নেওয়া এবং মান রিটার্ন করা ফাংশন

প্যারামিটার নেওয়া এবং মান রিটার্ন করা ফাংশন নিয়ে গভীরে যাই। একটি ফাংশন থেকে মান রিটার্ন করতে আমরা 'return' শেল বিল্টইন ব্যবহার করি। সিনট্যাক্স নিচের মত।

func_name ( ) {
    ... commands ...
    return $ret_val
}

সেরকম, আমরা ফাংশনগুলিতে আর্গুমেন্ট পাস করতে পারি স্পেস দিয়ে আলাদা করে নিচের মত করে।

func_name $arg_1 $arg_2 $arg_3

ফাংশনের ভিতরে আমরা আর্গুমেন্টগুলো ক্রম대로 $1, $2, $3 ইত্যাদি হিসেবে অ্যাক্সেস করতে পারি। দুটি ইন্টিজারের ম্যাক্সিমাম বের করার জন্য ফাংশন ব্যবহার করে নিচের উদাহরণ স্ক্রিপ্টটি দেখুন আরও স্পষ্টতা পেতে।

#!/bin/bash
USG_ERR=7
max_two ( ) {
    if [ "$1" -eq "$2" ] ; then
        echo 'Equal'
        exit 0
    elif [ "$1" -gt "$2" ] ; then
        echo $1
    else
        echo $2
    fi
}
err_str ( ) {
    echo "Usage: $0  "
    exit $USG_ERR
}
NUM_1=$1
NUM_2=$2
x
if [ $# -ne 2 ] ; then
    err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
    if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then
        max_two $NUM_1 $NUM_2
    else
        err_str
    fi
else
    err_str
fi
exit 0

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

#!/bin/bash
USG_ERR=7
ret_val=
max_two ( ) {
    if [ "$1" -eq "$2" ] ; then
        echo 'Equal'
        exit 0
    elif [ "$1" -gt "$2" ] ; then
        ret_val=$1
    else
        ret_val=$2
    fi
}
err_str ( ) {
    echo "Usage: $0  "
    exit $USG_ERR
}
NUM_1=$1
NUM_2=$2
if [ $# -ne 2 ] ; then
    err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
    if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then
        max_two $NUM_1 $NUM_2
        echo $ret_val
    else
        err_str
    fi
else
    err_str
fi
exit 0

এখন পূর্বের শেল স্ক্রিপ্টিং সিরিজে ব্যাখ্যায়িত কিছু আকর্ষণীয় সমস্যা ফাংশন ব্যবহার করে সমাধান করার চেষ্টা করুন।

  1. বেসিক লিনাক্স শেল স্ক্রিপ্টিং ল্যাঙ্গুয়েজ টিপস বোঝা – পার্ট I
  2. লিনাক্স নতুনদের শেল প্রোগ্রামিং শেখাতে ৫টি শেল স্ক্রিপ্ট – পার্ট II
  3. লিনাক্স BASH স্ক্রিপ্টিংর জগতে সৈলিং – পার্ট III
  4. লিনাক্স শেল প্রোগ্রামিংর গাণিতিক দিক – পার্ট IV
  5. শেল স্ক্রিপ্টিং ল্যাঙ্গুয়েজে গাণিতিক এক্সপ্রেশন ক্যালকুলেট করা – পার্ট V

আমি ফাংশনাল ফিচার যেমন লোকাল ভেরিয়েবল ব্যবহার, রিকার্সন ইত্যাদি নিয়ে আরও গভীর অন্তর্দৃষ্টির সাথে ফিরে আসব। কমেন্টের সাথে আপডেটেড থাকুন।

  1. ShellCheck: বাশ স্ক্রিপ্টের ত্রুটি সনাক্ত ও সংশোধন করুন রিয়েল-টাইম সতর্কতা ও সুপারিশের সাথে

  2. শেল ইনিশিয়ালাইজেশন ফাইল ও ইউজার প্রোফাইল মास্টার করুন: লিনাক্স অ্যাডমিনের জন্য গাইড

  3. কাস্টম শেল ফাংশন ও লাইব্রেরি মাস্টার করুন: লিনাক্স ব্যবহারকারীদের জন্য প্র্যাকটিক্যাল গাইড

  4. ব্যাশ শেল ফাংশন মাস্টার করুন: ৬টি প্র্যাক্টিক্যাল উদাহরণ ও টিপস