গাইড

নতুনদের জন্য Bash স্ক্রিপ্ট: প্রথম স্ক্রিপ্ট, ভেরিয়েবল, শর্ত, লুপ ও cron

হালনাগাদ: · Skillaria.Top

Bash স্ক্রিপ্ট হলো shell কমান্ডের একটি টেক্সট ফাইল, যা #!/bin/bash লাইন দিয়ে শুরু হয়, chmod +x দিয়ে চালানোর অনুমতি পায় এবং ./script.sh হিসেবে চলে। স্ক্রিপ্টে ব্যবহৃত হয় ভেরিয়েবল, $1 ও $2 আর্গুমেন্ট, if শর্ত, for ও while লুপ; নির্ধারিত সময়ে নিয়মিত চালানো হয় crontab -e দিয়ে।

Bash স্ক্রিপ্ট হলো সাধারণ একটি টেক্সট ফাইল, যাতে এমন কমান্ড থাকে যা আপনি অন্যথায় টার্মিনালে একটি একটি করে লিখতেন। স্ক্রিপ্ট শুরু হয় #!/bin/bash শেবাং লাইন দিয়ে, chmod +x দিয়ে চালানোর অনুমতি পায় এবং ./script.sh হিসেবে চলে। নতুনদের জন্য এই bash স্ক্রিপ্ট গাইডে প্রথম লাইন থেকে নির্ধারিত সময়ে চালানো পর্যন্ত সব আছে: ভেরিয়েবল, আর্গুমেন্ট, শর্ত, লুপ, ত্রুটি সামলানো এবং cron।

এক মিনিটে প্রথম bash স্ক্রিপ্ট

যেকোনো এডিটরে ফাইল তৈরি করুন, যেমন nano-তে:

nano hello.sh
#!/bin/bash
# প্রথম স্ক্রিপ্ট: অভিবাদন ও সিস্টেমের কিছু তথ্য
echo "স্বাগতম, $USER!"
echo "আজ: $(date +%Y-%m-%d)"
echo "আপনি আছেন: $(pwd)"

সেভ করুন (Ctrl+O, Enter, Ctrl+X), চালানোর অনুমতি দিন, তারপর চালান:

$ chmod +x hello.sh
$ ./hello.sh
স্বাগতম, alice!
আজ: 2026-10-12
আপনি আছেন: /home/alice

# দিয়ে শুরু হওয়া লাইন হলো মন্তব্য। $(কমান্ড) কমান্ডের আউটপুট সরাসরি লাইনের ভেতরে বসিয়ে দেয়।

Shebang: প্রথম লাইনের কাজ

#!/bin/bash লাইনটি সিস্টেমকে বলে দেয় ফাইলটি কোন ইন্টারপ্রেটার দিয়ে চালাতে হবে। এটি না থাকলে যে শেল হাতের কাছে পাওয়া যায় সেটিই চালাবে, আর কিছু সিস্টেমে /bin/sh bash নয়, সরল dash — সেখানে কিছু গঠন কাজ করে না।

আরেকটি প্রচলিত রূপ হলো #!/usr/bin/env bash: এটি PATH-এ bash খোঁজে, যা কাজে আসে যখন bash /bin-এ নেই।

স্ক্রিপ্ট কীভাবে চালাবেন, এবং কেন ./

দুটি উপায় আছে:

  • ./hello.sh — শেবাং ও x অনুমতি লাগে। ./ উপসর্গ অপরিহার্য, কারণ বর্তমান ডিরেক্টরি PATH-এ থাকে না।
  • bash hello.sh — চালানোর অনুমতি লাগে না, কারণ ইন্টারপ্রেটার স্পষ্টভাবে লেখা।

./ ছাড়া command not found এবং chmod +x ছাড়া Permission denied দেখলে এই দুটি কারণই মূল। নিজের স্ক্রিপ্ট যেকোনো জায়গা থেকে নাম দিয়ে ডাকতে চাইলে সেটি ~/bin বা /usr/local/bin-এ রাখুন।

ভেরিয়েবল

ভেরিয়েবল তৈরি হয় =-এর দুই পাশে ফাঁকা না রেখে, আর পড়া হয় $ দিয়ে:

#!/bin/bash
name="backup"
dir="/var/backups"
today=$(date +%F)

echo "ফাইল: ${dir}/${name}-${today}.tar.gz"

কার্লি ব্র্যাকেট ভেরিয়েবলের নামকে আশেপাশের লেখা থেকে আলাদা করে। name = "backup" লিখলে ভুল হবে: bash name নামের একটি কমান্ড চালাতে চাইবে।

উদ্ধৃতি চিহ্নের গুরুত্ব

দ্বিতীয় উদ্ধৃতি চিহ্নের ভেতরে ভেরিয়েবল তার মান দিয়ে বদলায়, একক উদ্ধৃতিতে বদলায় না। ভেরিয়েবল প্রায় সব সময় দ্বিতীয় উদ্ধৃতিতে লিখুন, নইলে স্পেসযুক্ত ফাইলের নাম দুটি আর্গুমেন্টে ভেঙে যাবে।

file="আমার রিপোর্ট.txt"
rm $file      # ভুল: "আমার" ও "রিপোর্ট.txt" মুছতে চাইবে
rm "$file"    # সঠিক
echo '$HOME'  # হুবহু $HOME লেখা দেখাবে
echo "$HOME"  # /home/alice দেখাবে

এনভায়রনমেন্ট ভেরিয়েবল

$HOME, $USER, $PATH-এর মতো ভেরিয়েবল সিস্টেম দেয়। নিজের ভেরিয়েবল export দিয়ে চাইল্ড প্রসেসে পাঠানো যায়। স্থায়ী এনভায়রনমেন্ট সেটিংস রাখা হয় ~/.bashrc বা ~/.profile-এ।

স্ক্রিপ্টের আর্গুমেন্ট

চালানোর সময় দেওয়া মানগুলো পাওয়া যায় $1, $2 ইত্যাদি হিসেবে।

ভেরিয়েবলযা ধারণ করে
$0স্ক্রিপ্টের নাম
$1, $2…প্রথম, দ্বিতীয় আর্গুমেন্ট
$#আর্গুমেন্টের সংখ্যা
"$@"সব আর্গুমেন্ট আলাদাভাবে
$?শেষ কমান্ডের এক্সিট কোড
$$বর্তমান স্ক্রিপ্টের PID
#!/bin/bash
echo "স্ক্রিপ্ট $0 পেয়েছে $# টি আর্গুমেন্ট"
echo "প্রথমটি: $1"
$ ./args.sh nginx 80
স্ক্রিপ্ট ./args.sh পেয়েছে 2 টি আর্গুমেন্ট
প্রথমটি: nginx

ব্যবহারকারীর ইনপুট পড়া হয় read কমান্ড দিয়ে: read -p "নাম লিখুন: " name।

if শর্ত

প্রতিটি কমান্ড একটি এক্সিট কোড ফেরত দেয়: 0 মানে সফল, অন্য যেকোনো মান মানে ব্যর্থ। if গঠন এই কোডটি পরীক্ষা করে। তুলনার জন্য ব্যবহৃত হয় [[ ... ]], এবং বন্ধনীর ভেতরে স্পেস বাধ্যতামূলক।

#!/bin/bash
if [[ $# -eq 0 ]]; then
    echo "ব্যবহার: $0 <ডিরেক্টরি>"
    exit 1
fi

if [[ -d "$1" ]]; then
    echo "ডিরেক্টরি $1 আছে"
elif [[ -f "$1" ]]; then
    echo "$1 একটি ফাইল, ডিরেক্টরি নয়"
else
    echo "$1 খুঁজে পাওয়া যায়নি"
fi
পরীক্ষাঅর্থ
-f fileসাধারণ ফাইল আছে
-d dirডিরেক্টরি আছে
-e pathপাথ আছে
-x fileফাইল চালানো যায়
-z "$var" / -n "$var"স্ট্রিং খালি / খালি নয়
"$a" == "$b", !=স্ট্রিং তুলনা
-eq -ne -lt -le -gt -geসংখ্যা তুলনা

যেকোনো কমান্ডের ফলাফল সরাসরি পরীক্ষা করাও যায়:

if systemctl is-active --quiet nginx; then
    echo "nginx চলছে"
else
    echo "nginx বন্ধ"
fi

অনেক বিকল্পের জন্য case সুবিধাজনক:

case "$1" in
    start)   echo "শুরু হচ্ছে" ;;
    stop)    echo "বন্ধ হচ্ছে" ;;
    *)       echo "অজানা কমান্ড: $1"; exit 1 ;;
esac

for ও while লুপ

for: একটি তালিকা ঘোরানো

for host in web1 web2 db1; do
    echo "পরীক্ষা করছি $host"
    ping -c 1 -W 1 "$host" > /dev/null && echo "  পৌঁছানো যাচ্ছে" || echo "  পৌঁছানো যাচ্ছে না"
done

for file in /var/log/*.log; do
    echo "$file: $(wc -l < "$file") লাইন"
done

for i in {1..5}; do
    echo "চেষ্টা $i"
done

while: শর্ত সত্য থাকা পর্যন্ত

ক্লাসিক উদাহরণ হলো ফাইল লাইন ধরে ধরে পড়া:

while read -r user; do
    echo "ব্যবহারকারী: $user"
done < users.txt

এবং সার্ভিস চালু হওয়ার অপেক্ষা:

count=0
until curl -sf http://localhost:8080/health > /dev/null; do
    count=$((count + 1))
    if [[ $count -ge 10 ]]; then
        echo "সার্ভিস চালু হয়নি"
        exit 1
    fi
    sleep 3
done
echo "সার্ভিস প্রস্তুত"

bash-এ গাণিতিক হিসাব লেখা হয় দ্বিগুণ বন্ধনীতে: $((a + b))। এটি শুধু পূর্ণসংখ্যার সঙ্গে কাজ করে।

ফাংশন

বারবার ব্যবহৃত কোড ফাংশনে রাখা হয়। ফাংশনের ভেতরে আর্গুমেন্ট একই $1, $2, আর local ভেরিয়েবলকে বাইরে যেতে দেয় না।

log() {
    local level="$1"; shift
    echo "$(date '+%F %T') [$level] $*"
}

log INFO "ব্যাকআপ শুরু করছি"
log ERROR "ডিস্কে জায়গা নেই"

ত্রুটি সামলানো: set -euo pipefail

ডিফল্টভাবে bash ব্যর্থ কমান্ডের পরেও চলতে থাকে — ফলে ব্যাকআপ স্ক্রিপ্ট কিছু কপি না করেও "সফল" হয়ে যেতে পারে। স্ক্রিপ্টের শুরুতে কড়া মোড যোগ করা রীতি:

#!/bin/bash
set -euo pipefail
  • -e — প্রথম ত্রুটিতেই থেমে যাওয়া।
  • -u — অঘোষিত ভেরিয়েবল ব্যবহার করা ত্রুটি বলে গণ্য (খালি DIR-এ rm -rf "$DIR/"-এর বিপদ থেকে রক্ষা)।
  • -o pipefail — পাইপলাইনের যেকোনো অংশ ব্যর্থ হলে পুরো পাইপলাইন ব্যর্থ।

ডিবাগ করতে স্ক্রিপ্টটি bash -x script.sh দিয়ে চালান: bash প্রতিটি কমান্ড চালানোর আগে তা ছাপবে। চালানোর আগে সাধারণ ভুল খুঁজতে shellcheck ব্যবহার করুন।

বাস্তব উদাহরণ: ব্যাকআপ স্ক্রিপ্ট

#!/bin/bash
set -euo pipefail

SRC="${1:-/var/www}"
DST="/var/backups/site"
KEEP_DAYS=7
STAMP=$(date +%F_%H-%M)

mkdir -p "$DST"
tar -czf "$DST/site-$STAMP.tar.gz" -C "$(dirname "$SRC")" "$(basename "$SRC")"
echo "আর্কাইভ তৈরি হয়েছে: $DST/site-$STAMP.tar.gz"

# KEEP_DAYS দিনের পুরোনো আর্কাইভ মুছুন
find "$DST" -name "site-*.tar.gz" -mtime +"$KEEP_DAYS" -delete

${1:-/var/www} মানে "প্রথম আর্গুমেন্ট, আর না থাকলে /var/www"। স্ক্রিপ্টটি /usr/local/bin/backup-site.sh নামে সেভ করুন এবং চালানোযোগ্য করুন: sudo chmod +x /usr/local/bin/backup-site.sh।

নির্ধারিত সময়ে চালানো: cron

Cron হলো সময়সূচি অনুযায়ী কমান্ড চালানোর সার্ভিস। ব্যবহারকারীর কাজ সম্পাদনা হয় crontab -e দিয়ে, দেখা যায় crontab -l দিয়ে, আর root-এর কাজের জন্য sudo crontab -e।

একটি কাজের লাইনে পাঁচটি সময়ের ঘর ও তারপর কমান্ড থাকে:

# মিনিট ঘণ্টা মাসের_দিন মাস সপ্তাহের_দিন কমান্ড
30 2 * * * /usr/local/bin/backup-site.sh >> /var/log/backup.log 2>&1
সময়সূচিকখন চলে
*/5 * * * *প্রতি ৫ মিনিটে
0 * * * *প্রতি ঘণ্টার শুরুতে
30 2 * * *প্রতিদিন ০২:৩০-এ
0 9 * * 1-5কর্মদিবসে ০৯:০০-এ
0 3 1 * *প্রতি মাসের ১ তারিখে ০৩:০০-এ
@rebootবুট হওয়ার পর একবার

হাতে চললেও cron-এ কেন চলে না

  • ভিন্ন পরিবেশ। Cron কাজ চালায় ন্যূনতম PATH ও ~/.bashrc ছাড়া। কমান্ড ও ফাইলের সম্পূর্ণ পাথ লিখুন, অথবা crontab-এর শুরুতে PATH সেট করুন।
  • ভিন্ন কাজের ডিরেক্টরি। কাজ শুরু হয় হোম ডিরেক্টরি থেকে, স্ক্রিপ্ট যেখানে আছে সেখান থেকে নয়। অ্যাবসোলিউট পাথ ব্যবহার করুন।
  • % চিহ্ন। crontab-এ % মানে নতুন লাইন, তাই কাজের লাইনে সরাসরি date +%F লিখলে \% লিখতে হয়। কমান্ডটি স্ক্রিপ্টে সরিয়ে নেওয়া সহজ।
  • আউটপুট হারায়। আউটপুট লগ ফাইলে পাঠান (>> ফাইল 2>&1), নইলে ত্রুটি দেখা যাবে না। Cron-এর কার্যক্রম দেখা যায় journalctl -u cron দিয়ে (RHEL-ভিত্তিক সিস্টেমে সার্ভিসের নাম crond)।

systemd-সমৃদ্ধ সিস্টেমে systemd timer cron-এর বিকল্প: এর আউটপুট journal-এ যায় এবং ছুটে যাওয়া চালনা পূরণ করা যায়।

সংক্ষেপে

নতুনদের bash স্ক্রিপ্ট মানে #!/bin/bash শেবাং, চালানোর অনুমতি ও কমান্ডের একটি ক্রম। উদ্ধৃতিযুক্ত ভেরিয়েবল, if দিয়ে আর্গুমেন্ট যাচাই, for ও while লুপ এবং set -euo pipefail কড়া মোড যোগ করুন — তাহলে আপনি একটি নির্ভরযোগ্য অটোমেশন টুল পাবেন, যা cron নির্ধারিত সময়ে চালাতে পারে। bash স্ক্রিপ্ট, পরিবেশ ও cron লিনাক্স কোর্সে হাতে-কলমে শেখানো হয়।

সাধারণ প্রশ্ন

bash ও sh-এর পার্থক্য কী?

sh একটি সাধারণ POSIX শেল, আর bash তার সম্প্রসারিত সংস্করণ যাতে অ্যারে, দ্বিগুণ বন্ধনী ও আরও সুবিধা আছে। bash-এর গঠন ব্যবহার করা স্ক্রিপ্ট অবশ্যই bash দিয়ে চালাতে হবে, sh দিয়ে নয়।

bash স্ক্রিপ্টের এক্সটেনশন কী হওয়া উচিত?

লিনাক্স এক্সটেনশন দেখে না; ইন্টারপ্রেটার ঠিক হয় শেবাং দিয়ে। .sh এক্সটেনশন শুধু একটি রীতি, যাতে মানুষ বোঝে এটি স্ক্রিপ্ট।

স্ক্রিপ্টে পাসওয়ার্ড নিরাপদে কীভাবে দেব?

আর্গুমেন্ট হিসেবে দেবেন না, কারণ ps-এ অন্য ব্যবহারকারীরা আর্গুমেন্ট দেখতে পায়। 600 অনুমতির ফাইল থেকে এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করুন, অথবা read -s দিয়ে না দেখিয়ে ইনপুট নিন।

স্ক্রিপ্ট root হিসেবে চলছে কি না কীভাবে যাচাই করব?

ব্যবহারকারীর ID-কে শূন্যের সঙ্গে তুলনা করুন: if [[ $EUID -ne 0 ]]; then echo "root দরকার"; exit 1; fi।

SSH থেকে বেরিয়ে গেলেও স্ক্রিপ্ট যেন থেমে না যায়, পটভূমিতে কীভাবে চালাব?

nohup ./script.sh & ব্যবহার করুন, অথবা tmux বা screen সেশনে চালান; স্থায়ী ব্যবহারের জন্য স্ক্রিপ্টটিকে systemd সার্ভিস বানান।

ভিডিওতে বিষয়টি শিখুন

“Linux: с нуля до уверенного администрирования” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।

কোর্সে যান