٪80 تخفیف

دانلود کتاب آموزشی حرفه ای اسکریپت نویسی در لینوکس جلد اول

دسته‌بندی: برچسب: تاریخ به روز رسانی: 6 دی 1404 تعداد بازدید: 557 بازدید
ویژگی های محصول: پشتیبانی واتساپ

قیمت اصلی: ۲,۰۰۰,۰۰۰ تومان بود.قیمت فعلی: ۴۰۰,۰۰۰ تومان.

torobpay
هر قسط با ترب‌پی: ۱۰۰,۰۰۰ تومان
۴ قسط ماهانه. بدون سود، چک و ضامن.

دوره آموزشی Mastering Linux Shell Scripting به شما کمک می‌کند تا با استفاده از اسکریپت‌نویسی شل در لینوکس مهارت پیدا کنید. این دوره برای افرادی که به دنبال اتوماسیون کارها، مدیریت سیستم و بهینه‌سازی فرآیندهای لینوکس از طریق اسکریپت‌های شل هستند، طراحی شده است. در این دوره شما اصول و مفاهیم پیشرفته اسکریپت‌نویسی شل را یاد خواهید گرفت و قادر خواهید بود تا وظایف پیچیده را به‌صورت خودکار و کارآمد در سیستم‌های لینوکسی انجام دهید.

سرفصل‌های دوره آموزشی Mastering Linux Shell Scripting:

 

بخش 1. مقدمه‌ای بر Shell Scripting

 

فصل 1. تعریف Shell

  • Shell چیست و چه نقشی در سیستم‌عامل دارد؟
  • ارتباط Shell با هسته (Kernel) سیستم‌عامل.
  • تفاوت بین Shell و Terminal.

فصل 2. انواع Shell

  • معرفی انواع شل‌های رایج:
    • Bash (Bourne Again Shell)
    • Zsh (Z Shell)
    • Ksh (Korn Shell)
    • Fish (Friendly Interactive Shell)
  • مقایسه شل‌های مختلف و کاربردهای آن‌ها.
  • دلایل انتخاب Bash به‌عنوان شل پیش‌فرض برای اسکریپت‌نویسی.

فصل 3. ویژگی‌های Shell Scripting

  • مزایای استفاده از Shell Scripting:
    • اتوماسیون وظایف تکراری.
    • بهینه‌سازی فرآیندها.
    • مدیریت آسان سیستم.
  • تفاوت بین اسکریپت‌نویسی شل و زبان‌های برنامه‌نویسی.

فصل 4. ساختار اولیه یک اسکریپت شل

  • معرفی Shebang (#!/bin/bash) و نقش آن.
  • ایجاد اولین فایل اسکریپت شل.
  • اصول نام‌گذاری و ذخیره اسکریپت‌ها با پسوند .sh.

فصل 5. اجرای اسکریپت شل

  • اعطای مجوز اجرایی به اسکریپت با استفاده از دستور chmod.
  • روش‌های مختلف اجرای اسکریپت:
    • اجرای مستقیم با نام فایل (./script.sh).
    • اجرای اسکریپت از طریق شل (bash script.sh).
  • بررسی خطاهای رایج در اجرای اسکریپت‌ها.

فصل 6. انواع اسکریپت‌ها

  • معرفی سه نوع اصلی اسکریپت‌های شل:
    • Batch Scripts: اجرای یک‌باره وظایف از پیش‌تعریف‌شده.
    • Interactive Scripts: دریافت ورودی از کاربر در حین اجرا.
    • Non-Interactive Scripts: اجرای خودکار بدون نیاز به ورودی.

فصل 7. ملاحظات اولیه در Shell Scripting

  • انتخاب ویرایشگر متن مناسب برای نوشتن اسکریپت:
    • Vim، Nano، Emacs و غیره.
  • مدیریت مسیر فایل‌های اسکریپت.
  • نکات اولیه برای نوشتن اسکریپت‌های خوانا و کارآمد.

بخش 2. نحوه نوشتن اسکریپت‌های شل

 

فصل 1. مقدمه‌ای بر اسکریپت‌نویسی شل

  • تعریف اسکریپت شل و کاربردهای آن.
  • معرفی تفاوت بین دستورات ساده و اسکریپت‌های چندخطی.

فصل 2. ایجاد فایل اسکریپت

  • نحوه ایجاد فایل اسکریپت با استفاده از دستور touch یا سایر ابزارها.
  • استفاده از ویرایشگرهای متنی (مانند vim, nano, gedit) برای ویرایش فایل‌ها.

فصل 3. استفاده از Shebang (#!/bin/bash)

  • توضیح مفهوم Shebang و کاربرد آن.
  • نحوه مشخص کردن مفسر (مانند bash, sh, یا zsh) برای اجرای اسکریپت.

فصل 4. نوشتن اولین اسکریپت ساده

  • ایجاد یک اسکریپت ساده برای چاپ متن با دستور echo.
  • اجرای اسکریپت با استفاده از دستور bash scriptname.sh یا ./scriptname.sh.

فصل 5. مجوزهای اجرایی

  • توضیح مفهوم مجوزهای اجرایی در لینوکس.
  • استفاده از دستور chmod +x scriptname.sh برای فعال‌سازی قابلیت اجرا.
  • بررسی مجوزهای فایل با استفاده از دستور ls -l.

فصل 6. افزودن کامنت‌ها به اسکریپت

  • استفاده از نماد # برای اضافه کردن توضیحات و مستندسازی کد.
  • اهمیت کامنت‌گذاری در خوانایی و نگهداری کد.

فصل 6. ساختار اصلی یک اسکریپت شل

  • تعریف بخش‌های اصلی اسکریپت شامل:
    • تعریف متغیرها.
    • دستورات اصلی.
    • حلقه‌ها و شرط‌ها.
  • سازماندهی اسکریپت به صورت منطقی و خوانا.

فصل 7. اجرای اسکریپت و اشکال‌زدایی اولیه

  • نحوه اجرای اسکریپت و بررسی خطاهای احتمالی.
  • استفاده از گزینه bash -x scriptname.sh برای دنبال کردن دستورات در حین اجرا.
  • رفع مشکلات رایج مانند دسترسی یا خطاهای سینتکس.

فصل 8. تعامل با کاربر

  • استفاده از دستور read برای گرفتن ورودی از کاربر.
  • چاپ پیغام‌ها و توضیحات برای کاربر با استفاده از دستور echo.

بخش 3. متغیرها و نوع داده‌ها در شل

 

فصل 1. مبانی متغیرها در شل

  • تعریف متغیرها: نحوه تعریف متغیرها در اسکریپت شل.
  • قوانین نام‌گذاری متغیرها: کاراکترهای مجاز و ساختار صحیح نام‌گذاری.
  • تعریف متغیرهای پویا (Dynamic Variables).

فصل 2. استفاده از متغیرها

  • مقداردهی به متغیرها: مثال‌های ساده و پیشرفته.
  • دسترسی به مقدار متغیرها با $.
  • تغییر مقادیر متغیرها و تأثیر آن در برنامه.

فصل 3. انواع متغیرها

  • متغیرهای محلی (Local Variables): تعریف و محدودیت‌های آن‌ها.
  • متغیرهای محیطی (Environment Variables): متغیرهای سیستم و نحوه استفاده از آن‌ها.
  • متغیرهای تعریف‌شده توسط کاربر: مقایسه با متغیرهای پیش‌فرض سیستم.

فصل 4. مدیریت نوع داده‌ها در شل

  • داده‌های رشته‌ای: نحوه مدیریت رشته‌ها.
  • داده‌های عددی: عملیات ریاضی روی اعداد.
  • آرایه‌ها:
    • تعریف آرایه‌ها در شل.
    • دسترسی به اعضای آرایه.
    • اضافه و حذف عناصر از آرایه.
  • متغیرهای چند بعدی (در صورت پشتیبانی توسط شل خاص).

فصل 5. ابزارها و دستورات مرتبط با متغیرها

  • استفاده از دستورات declare و typeset برای تعیین نوع متغیرها.
  • محدود کردن مقادیر متغیرها با استفاده از readonly.
  • حذف متغیرها با دستور unset.

فصل 6. گسترش متغیرها

  • گسترش مقدار متغیرها: ${variable}.
  • مقدار پیش‌فرض برای متغیرها: ${variable:-default}.
  • بررسی وجود متغیرها: ${variable:+value}.
  • تغییر مقدار متغیرها در هنگام استفاده: ${variable:=new_value}.

فصل 7. مدیریت متغیرهای خاص در شل

  • متغیرهای خاص مانند $0, $1, $#, $?, $$.
  • کاربرد هر متغیر خاص در سناریوهای عملی.

فصل 8. عیب‌یابی و اشکال‌زدایی متغیرها

  • استفاده از set -u برای هشدار در مورد متغیرهای تعریف‌نشده.
  • نحوه شناسایی مشکلات مرتبط با متغیرها در اسکریپت‌ها.

بخش 4. عملگرها و دستورات شرطی

 

فصل 1. مقدمه‌ای بر عملگرها در شل

  • آشنایی با عملگرهای ریاضی، منطقی، مقایسه‌ای، و رشته‌ای
  • استفاده از عملگرهای فایل برای بررسی خصوصیات فایل‌ها

فصل 2. دستورات شرطی اصلی

  • ساختار دستور if-else
  • استفاده از elif برای بررسی شرایط چندگانه
  • دستور case برای جایگزینی شرط‌های پیچیده

فصل 3. مقایسه و ارزیابی شرط‌ها

  • مقایسه اعداد و رشته‌ها
  • ترکیب شرط‌ها با عملگرهای منطقی (&&, ||)
  • استفاده از شرط‌های تو در تو

فصل 4. مدیریت خطاها در اسکریپت‌ها

  • بررسی خروجی دستورات با $?
  • استفاده از دستور || و && برای مدیریت خطاها

بخش 5. حلقه‌ها (Loops)

 

فصل 1. مقدمه ای از حلقه‌ها

  • معرفی حلقه‌ها و نقش آنها در اسکریپت‌نویسی.

فصل 2. انواع حلقه‌ها در شل

  • حلقه for
  • حلقه while
  • حلقه until

فصل 3. کنترل جریان در حلقه‌ها

  • دستور break
  • دستور continue

فصل 4. حلقه‌های تو در تو

  • تعریف و کاربردها.

فصل 5. کار با لیست‌ها و داده‌ها در حلقه‌ها

  • پردازش فایل‌ها و داده‌ها با حلقه‌ها.

فصل 6. کاربردهای عملی حلقه‌ها

  • موارد استفاده رایج در وظایف اتوماسیون.

فصل 7. بهینه‌سازی حلقه‌ها

  • نکات برای افزایش کارایی.

بخش 6. توابع و آرگومان‌ها

 

فصل 1. تعریف توابع

  • مفهوم توابع در شل اسکریپت.
  • نحوه تعریف یک تابع با استفاده از کلمات کلیدی function و بدون آن.
  • قواعد نام‌گذاری توابع در شل.
  • تفاوت بین تعریف تابع با پرانتز و بدون پرانتز.

فصل 2. فراخوانی توابع

  • روش‌های فراخوانی توابع در اسکریپت.
  • اجرای توابع با آرگومان‌های مختلف.
  • نحوه دسترسی به مقدار بازگشتی توابع.

فصل 3. پارامترها و آرگومان‌ها در توابع

  • استفاده از $1, $2, ... برای دسترسی به آرگومان‌های ورودی.
  • تعداد آرگومان‌ها با استفاده از $#.
  • لیست کامل آرگومان‌ها با $@ و $*.
  • تفاوت بین $@ و $*.

فصل 4. مقدار بازگشتی توابع

  • استفاده از return برای بازگرداندن مقادیر عددی.
  • بازگشت مقادیر متنی با استفاده از echo.
  • بررسی مقدار بازگشتی توابع با $?.

فصل 5. محدوده متغیرها در توابع

  • متغیرهای محلی (local) و متغیرهای سراسری.
  • نحوه تعریف متغیرهای محلی در توابع.
  • دسترسی به متغیرهای سراسری در توابع.

فصل 6. استفاده از توابع کتابخانه‌ای

  • تعریف و ذخیره توابع در فایل‌های جداگانه.
  • نحوه import فایل توابع با استفاده از source یا ..
  • استفاده مجدد از توابع در پروژه‌های مختلف.

فصل 7. توابع بازگشتی (Recursive Functions)

  • تعریف و استفاده از توابع بازگشتی.
  • کاربردهای توابع بازگشتی در شل.
  • محدودیت‌ها و مشکلات احتمالی در توابع بازگشتی.

فصل 8. مدیریت آرگومان‌های خط فرمان

  • نحوه پردازش آرگومان‌های ورودی اسکریپت.
  • استفاده از getopts برای مدیریت آرگومان‌ها.
  • تعریف فلگ‌های (flags) مختلف برای اسکریپت‌ها.
  • نمایش پیام‌های راهنما (help) با آرگومان --help.

فصل 9. کاربردهای عملی توابع و آرگومان‌ها

  • نوشتن توابع عمومی برای اجرای دستورات متداول.
  • نوشتن توابع برای پردازش فایل‌ها و داده‌ها.
  • طراحی توابع برای مدیریت خطاها و گزارش‌دهی.

بخش 7. ورودی و خروجی در شل

 

فصل 1. خواندن ورودی از کاربر

  • استفاده از دستور read برای گرفتن ورودی از کاربر.
  • تنظیم مقدار پیش‌فرض برای ورودی‌های خالی.
  • خواندن چندین متغیر در یک خط.

فصل 2. نوشتن خروجی به کنسول یا فایل

  • استفاده از echo برای چاپ متن و متغیرها.
  • قالب‌بندی خروجی با استفاده از printf.
  • نوشتن خروجی به فایل با استفاده از > یا >>.
  • تغییر رفتار نوشتن خروجی با کاراکترهای کنترلی مانند \n، \t.

فصل 3. ریدایرکشن (Redirection)

  • هدایت خروجی استاندارد به فایل: command > file.
  • افزودن خروجی به انتهای فایل: command >> file.
  • هدایت خطاهای استاندارد به فایل: command 2> file.
  • هدایت همزمان خروجی و خطا به یک فایل: command > file 2>&1.

فصل 4. پایپینگ (Piping)

  • انتقال خروجی یک دستور به عنوان ورودی دستور دیگر با استفاده از |.
  • استفاده از پایپ برای ترکیب دستورات مانند grep، awk، و sort.

فصل 5. تعامل با فایل‌ها

  • خواندن محتویات یک فایل با استفاده از cat یا less.
  • خواندن فایل خط به خط در یک حلقه با استفاده از while و <.
  • پردازش هر خط فایل با دستورات شل.

فصل 6. خواندن چندین خط از فایل

  • استفاده از دستور read با گزینه‌های مختلف برای پردازش چندین خط.
  • مدیریت خطوط طولانی با استفاده از IFS.

فصل 7. نوشتن داده‌ها در فایل‌های موقتی

  • ایجاد فایل‌های موقتی با استفاده از دستورات mktemp و tempfile.
  • نوشتن خروجی در فایل موقتی و بازیابی آن.
  • پاک کردن فایل‌های موقتی پس از استفاده.

فصل 8. کار با ورودی‌های استاندارد (stdin)

  • دریافت ورودی از کاربر به‌صورت مستقیم از کنسول.
  • پردازش ورودی با دستورات read، cat و grep.

فصل 9. کار با خروجی‌های استاندارد (stdout)

  • ذخیره خروجی دستورات در متغیرها.
  • انتقال خروجی به فایل‌ها یا دستورات دیگر.

فصل 10. مدیریت خطاها در ورودی و خروجی

  • هدایت خطاهای استاندارد به فایل برای اشکال‌زدایی.
  • استفاده از دستورات try-catch شبیه‌سازی شده در شل.
[cdb_course_lessons title=”بخش 1. مقدمه‌ای بر Shell Scripting”][cdb_course_lesson title=”فصل 1. تعریف Shell”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”Shell چیست و چه نقشی در سیستم‌عامل دارد؟” subtitle=”توضیحات کامل”]شل (Shell) یک رابط بین کاربر و هسته (Kernel) سیستم‌عامل است که امکان اجرای دستورات و مدیریت منابع سیستم را فراهم می‌کند. در واقع، شل به کاربران این اجازه را می‌دهد که با تایپ دستورات خاصی، سیستم‌عامل را کنترل کرده و عملیات مختلفی مانند مدیریت فایل‌ها، اجرای برنامه‌ها، پردازش داده‌ها و تنظیمات سیستم را انجام دهند.

شل می‌تواند به دو صورت تعاملی (Interactive) و غیرتعاملی (Non-Interactive) اجرا شود:

  • حالت تعاملی: کاربر دستورات را در محیط شل تایپ می‌کند و بلافاصله خروجی را مشاهده می‌کند.
  • حالت غیرتعاملی: دستورات در قالب یک اسکریپت نوشته می‌شوند و به‌طور خودکار اجرا می‌شوند.

ارتباط Shell با هسته (Kernel) سیستم‌عامل

در سیستم‌عامل‌های مبتنی بر یونیکس و لینوکس، شل یک لایه واسط بین کاربر و هسته سیستم‌عامل (Kernel) است. کاربران به‌طور مستقیم با کرنل تعامل ندارند، بلکه از طریق شل دستورات را وارد کرده و پردازش‌های مورد نظر را اجرا می‌کنند.

نحوه ارتباط شل و کرنل
  1. کاربر دستور را در شل وارد می‌کند.
  2. شل دستور را پردازش کرده و به کرنل ارسال می‌کند.
  3. کرنل دستور را اجرا کرده و خروجی را به شل بازمی‌گرداند.
  4. شل خروجی را به کاربر نمایش می‌دهد.

🔹 برای مشاهده اطلاعات کرنل سیستم می‌توانید از دستور زیر استفاده کنید:

uname -a

🔹 برای بررسی نسخه دقیق کرنل:

cat /proc/version

تفاوت بین Shell و Terminal

بسیاری از کاربران، شل و ترمینال (Terminal) را به‌اشتباه معادل یکدیگر در نظر می‌گیرند، اما این دو مفهوم متفاوتی دارند:

مفهوم توضیح
Shell یک برنامه نرم‌افزاری است که وظیفه پردازش دستورات کاربر را بر عهده دارد. مانند Bash، Zsh، و Fish.
Terminal یک محیط گرافیکی یا متنی برای تعامل با شل است. مانند GNOME Terminal، Konsole، و XTerm.

📌 مثال کاربردی
برای مشاهده شل فعلی که در حال اجراست، می‌توانید از دستور زیر استفاده کنید:

echo $SHELL

این دستور مسیر شل فعلی شما را نمایش می‌دهد، مثلاً:

/bin/bash

اگر بخواهید لیستی از شل‌های نصب‌شده روی سیستم را مشاهده کنید، این دستور را اجرا کنید:

cat /etc/shells

خروجی نمونه:

/bin/sh
/bin/bash
/usr/bin/zsh

این لیست نشان می‌دهد که سیستم شما از شل‌های مختلفی پشتیبانی می‌کند.


جمع بندی

شل یک رابط بین کاربر و کرنل سیستم‌عامل است که امکان اجرای دستورات، مدیریت فایل‌ها و انجام عملیات مختلف را فراهم می‌کند. برخلاف ترمینال که یک محیط برای تعامل با شل است، شل خود یک مفسر دستورات است. کاربران می‌توانند از طریق شل، سیستم را کنترل کرده و از امکانات پیشرفته آن برای اجرای خودکار وظایف استفاده کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”ارتباط Shell با هسته (Kernel) سیستم‌عامل” subtitle=”توضیحات کامل”]شل (Shell) یک واسط بین کاربر و هسته (Kernel) سیستم‌عامل است. کاربران نمی‌توانند مستقیماً با کرنل ارتباط برقرار کنند، زیرا کرنل مسئول کنترل سخت‌افزار، مدیریت منابع و اجرای فرآیندها است. شل این مشکل را حل می‌کند و دستورات کاربر را گرفته و آن‌ها را به کرنل ارسال می‌کند.


نحوه تعامل Shell با Kernel

روند ارتباط بین شل و کرنل به‌صورت زیر است:

  1. کاربر دستور را وارد می‌کند (مثلاً ls -l /home).
  2. شل دستور را پردازش کرده و آن را به کرنل ارسال می‌کند.
  3. کرنل دستور را اجرا کرده و نتیجه را به شل بازمی‌گرداند.
  4. شل خروجی را به کاربر نمایش می‌دهد.

📌 مثال عملی:
برای بررسی نسخه کرنل سیستم، از دستور زیر استفاده کنید:

uname -r

خروجی نمونه:

5.15.0-84-generic

نقش Kernel در اجرای دستورات Shell

کرنل مدیریت اصلی سیستم‌عامل را بر عهده دارد. برخی از مهم‌ترین وظایف کرنل هنگام اجرای دستورات از طریق شل عبارت‌اند از:

🔹 مدیریت پردازش‌ها (Process Management)
کرنل اجرای برنامه‌ها را کنترل می‌کند. مثلاً زمانی که یک دستور اجرا می‌شود، کرنل یک پردازش (Process) ایجاد می‌کند. برای مشاهده پردازش‌های در حال اجرا از دستور زیر استفاده کنید:

ps aux

🔹 مدیریت حافظه (Memory Management)
کرنل حافظه موردنیاز برای اجرای پردازش‌ها را تخصیص داده و آزاد می‌کند. برای مشاهده اطلاعات مربوط به حافظه، می‌توانید از دستور زیر استفاده کنید:

free -h

🔹 مدیریت فایل‌ها (File System Management)
کرنل مسئول خواندن، نوشتن و مدیریت فایل‌ها است. برای مشاهده اطلاعات مربوط به استفاده از دیسک، این دستور را اجرا کنید:

df -h

🔹 مدیریت دستگاه‌ها (Device Management)
کرنل ورودی‌ها و خروجی‌های سخت‌افزاری مانند دیسک‌ها، پرینترها و کیبورد را کنترل می‌کند. برای مشاهده دستگاه‌های متصل، از این دستور استفاده کنید:

lsblk

مثال کاربردی از تعامل Shell و Kernel

فرض کنید می‌خواهید یک فایل جدید ایجاد کنید، محتوا در آن بنویسید و سپس محتوای آن را مشاهده کنید:

  1. ایجاد فایل جدید:
    touch myfile.txt
    
  2. نوشتن در فایل:
    echo "Hello, Kernel!" > myfile.txt
    
  3. خواندن محتوای فایل:
    cat myfile.txt
    

    خروجی:

    Hello, Kernel!
    

در این فرآیند:

  • شل دستورات را دریافت کرد.
  • کرنل پردازش‌های لازم را اجرا کرد (ایجاد فایل، نوشتن و خواندن).
  • شل خروجی را به کاربر نمایش داد.

جمع بندی

شل و کرنل دو بخش اساسی در سیستم‌عامل هستند که با یکدیگر تعامل دارند. شل دستورات را از کاربر دریافت کرده و به کرنل ارسال می‌کند، و کرنل آن‌ها را اجرا کرده و نتیجه را برمی‌گرداند. این ارتباط برای اجرای برنامه‌ها، مدیریت فایل‌ها، کنترل سخت‌افزار و تخصیص منابع ضروری است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تفاوت بین Shell و Terminal” subtitle=”توضیحات کامل”]در سیستم‌عامل‌های مبتنی بر یونیکس و لینوکس، Shell و Terminal دو مفهوم مرتبط اما متفاوت هستند. در حالی که بسیاری از کاربران این دو را به‌جای یکدیگر به کار می‌برند، اما وظایف و نقش‌های جداگانه‌ای دارند.


تعریف Shell

شل (Shell) یک برنامه‌ی خط فرمانی است که به‌عنوان واسط بین کاربر و کرنل سیستم‌عامل عمل می‌کند. این برنامه دستورات را دریافت کرده، پردازش می‌کند و آن‌ها را برای اجرا به کرنل می‌فرستد.

🔹 ویژگی‌های Shell:
✅ دریافت دستورات از کاربر و ارسال به کرنل
✅ پشتیبانی از اسکریپت‌نویسی برای اجرای خودکار دستورات
✅ امکان اجرای دستورات به‌صورت تعاملی یا در قالب یک فایل اسکریپت

📌 مثال از اجرای دستور در Shell:

echo "Hello, Shell!"

خروجی:

Hello, Shell!

چند نوع Shell پرکاربرد:

  • Bash (Bourne Again Shell) – رایج‌ترین شل در لینوکس
  • Zsh (Z Shell) – دارای امکانات پیشرفته‌تر نسبت به Bash
  • Fish (Friendly Interactive Shell) – کاربرپسندتر با پیشنهادات هوشمند
  • Ksh (Korn Shell) – برای کاربردهای اسکریپت‌نویسی

تعریف Terminal

ترمینال (Terminal) یک واسط گرافیکی یا متنی است که امکان ارتباط کاربر با Shell را فراهم می‌کند. به‌عبارت‌دیگر، ترمینال محیطی است که در آن می‌توان دستورات را به Shell ارسال کرد.

🔹 ویژگی‌های Terminal:
✅ یک رابط کاربری برای دسترسی به شل
✅ امکان اجرای چندین جلسه شل در تب‌های مختلف
✅ برخی ترمینال‌ها از قابلیت سفارشی‌سازی و افزودنی‌ها پشتیبانی می‌کنند

📌 چند نمونه از Terminalهای محبوب:

  • GNOME Terminal – در توزیع‌های مبتنی بر GNOME
  • Konsole – در محیط دسکتاپ KDE
  • Alacritty – یک ترمینال سریع و سبک
  • Terminator – دارای قابلیت تقسیم پنجره و مدیریت بهتر تب‌ها

تفاوت‌های کلیدی بین Shell و Terminal

مقایسه Shell Terminal
تعریف یک برنامه که دستورات را پردازش کرده و به کرنل ارسال می‌کند محیطی برای تعامل با Shell
نقش واسط بین کاربر و کرنل واسط بین کاربر و Shell
مثال‌ها Bash, Zsh, Fish, Ksh GNOME Terminal, Konsole, Alacritty
وظیفه اصلی اجرای دستورات و اسکریپت‌ها نمایش خروجی و دریافت ورودی از کاربر

مثال عملی برای درک تفاوت Shell و Terminal

1️⃣ باز کردن Terminal

  • در لینوکس: Ctrl + Alt + T
  • در macOS: استفاده از Terminal.app
  • در ویندوز: استفاده از Windows Terminal یا PowerShell

2️⃣ اجرای یک شل خاص در Terminal
ابتدا نوع شل فعلی را بررسی کنید:

echo $SHELL

خروجی نمونه:

/bin/bash

حالا می‌توانید به یک شل دیگر تغییر دهید، مثلاً Zsh را اجرا کنید:

zsh

حالا در محیط Zsh هستید. برای بازگشت به Bash می‌توانید دستور زیر را اجرا کنید:

bash

جمع بندی

🔹 Shell یک برنامه است که دستورات را اجرا کرده و با کرنل در ارتباط است.
🔹 Terminal محیطی است که به شما امکان استفاده از Shell را می‌دهد.
🔹 Shell بدون Terminal می‌تواند اجرا شود (مثلاً در اسکریپت‌های خودکار)، اما Terminal بدون Shell کاربردی ندارد.
🔹 ترمینال تنها یک ابزار برای دسترسی به شل است و خود وظیفه پردازش دستورات را ندارد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. انواع Shell”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی انواع شل‌های رایج” subtitle=”توضیحات کامل”]سیستم‌های مبتنی بر یونیکس و لینوکس از شل‌های مختلفی برای اجرای دستورات و تعامل با کرنل استفاده می‌کنند. هر شل دارای قابلیت‌ها و ویژگی‌های خاصی است که آن را برای کاربران یا اسکریپت‌نویسی مناسب‌تر می‌کند. در این بخش، رایج‌ترین شل‌ها یعنی Bash، Zsh، Ksh و Fish را معرفی کرده و ویژگی‌های کلیدی آن‌ها را بررسی می‌کنیم.


Bash (Bourne Again Shell)

Bash رایج‌ترین و پراستفاده‌ترین شل در سیستم‌عامل‌های لینوکس و مک است. این شل به‌عنوان نسخه‌ای بهبودیافته از Bourne Shell (sh) طراحی شده و امکانات بیشتری از جمله تاریخچه دستورات، تکمیل خودکار، مدیریت متغیرها و توابع داخلی را ارائه می‌دهد.

🔹 ویژگی‌های کلیدی:
✅ پشتیبانی از تاریخچه دستورات (history)
✅ امکان تکمیل خودکار (TAB completion)
✅ قابلیت‌های پیشرفته برای اسکریپت‌نویسی
✅ امکان مدیریت فرآیندها (مثل fg, bg, jobs)

📌 نصب Bash (در صورت نیاز):
در اکثر توزیع‌های لینوکسی Bash به‌صورت پیش‌فرض نصب است، اما در صورت نیاز می‌توان آن را نصب کرد:

sudo apt install bash       # در Debian/Ubuntu
sudo yum install bash       # در RHEL/CentOS
sudo pacman -S bash         # در Arch Linux

📌 تغییر شل پیش‌فرض به Bash:

chsh -s /bin/bash

📌 اجرای Bash به‌صورت موقت:

bash

Zsh (Z Shell)

Zsh یک شل پیشرفته‌تر از Bash است که امکانات قدرتمندی مانند پیشنهاد خودکار دستورات، تصحیح تایپی، هایلایت دستورات و پلاگین‌های توسعه‌یافته دارد. بسیاری از کاربران حرفه‌ای لینوکس و مک از Zsh به دلیل امکانات بیشتر آن استفاده می‌کنند.

🔹 ویژگی‌های کلیدی:
✅ قابلیت تکمیل خودکار هوشمند و سریع‌تر از Bash
✅ تصحیح تایپی دستورات اشتباه
✅ پشتیبانی از Oh My Zsh (مدیریت افزونه‌ها و تم‌ها)
✅ قابلیت‌های پیشرفته در مدیریت تاریخچه دستورات

📌 نصب Zsh:

sudo apt install zsh        # در Debian/Ubuntu
sudo yum install zsh        # در RHEL/CentOS
sudo pacman -S zsh          # در Arch Linux

📌 تغییر شل پیش‌فرض به Zsh:

chsh -s /bin/zsh

📌 نصب Oh My Zsh برای مدیریت بهتر Zsh:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

📌 اجرای Zsh به‌صورت موقت:

zsh

Ksh (Korn Shell)

Ksh یکی از شل‌های قدیمی اما قدرتمند است که برای سرورها و اسکریپت‌نویسی سطح بالا بسیار مناسب است. این شل توسط David Korn در آزمایشگاه Bell توسعه داده شده و بسیاری از ویژگی‌های Bash و Zsh را دارد.

🔹 ویژگی‌های کلیدی:
✅ اجرای سریع‌تر نسبت به Bash در برخی سناریوها
✅ پشتیبانی از توابع داخلی و آرایه‌ها
✅ قابلیت اجرای دستورات پس‌زمینه و مدیریت پیشرفته‌تر فرآیندها

📌 نصب Ksh:

sudo apt install ksh        # در Debian/Ubuntu
sudo yum install ksh        # در RHEL/CentOS
sudo pacman -S ksh          # در Arch Linux

📌 تغییر شل پیش‌فرض به Ksh:

chsh -s /bin/ksh

📌 اجرای Ksh به‌صورت موقت:

ksh

Fish (Friendly Interactive Shell)

Fish یک شل مدرن و کاربرپسند است که تجربه‌ی بهتری نسبت به Bash و Zsh ارائه می‌دهد. این شل دارای رابط کاربری رنگی، پیشنهادات دستورات زنده و تنظیمات ساده‌تری است.

🔹 ویژگی‌های کلیدی:
✅ پیشنهاد خودکار دستورات هنگام تایپ
✅ پشتیبانی داخلی از رنگ‌بندی دستورات
✅ عدم نیاز به تنظیمات پیچیده پس از نصب
✅ پشتیبانی از Web-based configuration برای تنظیمات گرافیکی

📌 نصب Fish:

sudo apt install fish       # در Debian/Ubuntu
sudo yum install fish       # در RHEL/CentOS
sudo pacman -S fish         # در Arch Linux

📌 تغییر شل پیش‌فرض به Fish:

chsh -s /usr/bin/fish

📌 اجرای Fish به‌صورت موقت:

fish

مقایسه کلی انواع شل‌ها

ویژگی Bash Zsh Ksh Fish
رایج‌ترین استفاده پیش‌فرض در بیشتر توزیع‌ها جایگزین پیشرفته‌تر Bash استفاده در سرورها و اسکریپت‌نویسی رابط کاربری مدرن و کاربرپسند
پیشنهاد خودکار خیر بله خیر بله (بهترین پیشنهادها)
تصحیح تایپی خیر بله خیر بله
رنگ‌بندی دستورات خیر بله (با پلاگین) خیر بله (پیش‌فرض)
مدیریت پلاگین‌ها محدود بله (با Oh My Zsh) محدود خیر (اما افزونه‌های زیادی دارد)

جمع بندی

🔹 Bash پرکاربردترین شل است که در اکثر توزیع‌های لینوکس به‌صورت پیش‌فرض وجود دارد.
🔹 Zsh نسخه‌ای پیشرفته‌تر از Bash است که قابلیت‌های جذابی مثل تکمیل خودکار بهتر و تصحیح تایپی دارد.
🔹 Ksh یک شل سریع و پایدار است که بیشتر در سرورها و اسکریپت‌نویسی استفاده می‌شود.
🔹 Fish یک شل مدرن با پیشنهادات زنده و رابط گرافیکی پیشرفته است که برای کاربران تازه‌کار و حرفه‌ای‌ها مناسب است.

📌 اگر به دنبال یک شل پایدار و عمومی هستید، Bash مناسب است.
📌 اگر قابلیت‌های بیشتری نیاز دارید، Zsh با Oh My Zsh انتخاب خوبی است.
📌 اگر برای سرورها و اسکریپت‌های سطح بالا کار می‌کنید، Ksh پیشنهاد می‌شود.
📌 اگر محیطی زیبا، کاربرپسند و مدرن می‌خواهید، Fish گزینه مناسبی است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”دلایل انتخاب Bash به‌عنوان شل پیش‌فرض برای اسکریپت‌نویسی” subtitle=”توضیحات کامل”]Bash (Bourne Again Shell) یکی از رایج‌ترین و پرکاربردترین شل‌ها در دنیای لینوکس و یونیکس است که برای مدیریت سیستم، اجرای دستورات و اسکریپت‌نویسی به‌طور گسترده استفاده می‌شود. بسیاری از توزیع‌های لینوکسی، Bash را به‌عنوان شل پیش‌فرض انتخاب کرده‌اند، زیرا ترکیبی از سادگی، قابلیت‌های قدرتمند، سازگاری گسترده و پشتیبانی از اسکریپت‌های پوسته‌ای استاندارد را ارائه می‌دهد. در ادامه به دلایل اصلی انتخاب Bash برای اسکریپت‌نویسی می‌پردازیم.


۱. پشتیبانی گسترده و پیش‌فرض بودن در اکثر سیستم‌ها

🔹 Bash به‌عنوان شل پیش‌فرض در اکثر توزیع‌های لینوکسی مانند Ubuntu، Debian، CentOS، Fedora و macOS نصب شده است.
🔹 در سرورها و محیط‌های ابری، اغلب Bash در دسترس است، بنابراین نیازی به نصب شل‌های دیگر وجود ندارد.
🔹 بسیاری از ابزارهای DevOps، اتوماسیون سرور و مدیریت سیستم‌ها از Bash به‌عنوان شل اصلی پشتیبانی می‌کنند.

📌 بررسی نسخه Bash روی سیستم:

bash --version

📌 بررسی شل پیش‌فرض سیستم:

echo $SHELL

📌 تغییر شل پیش‌فرض به Bash (در صورت نیاز):

chsh -s /bin/bash

۲. پشتیبانی از استاندارد POSIX و سازگاری بالا

🔹 Bash سازگاری بالایی با استاندارد POSIX دارد، به همین دلیل اسکریپت‌های نوشته‌شده در آن در اکثر سیستم‌های یونیکسی و لینوکسی بدون تغییر اجرا می‌شوند.
🔹 برخلاف برخی از شل‌های دیگر مانند Fish که ساختار متفاوتی دارند، اسکریپت‌های Bash روی اکثر سیستم‌ها بدون نیاز به اصلاح اجرا می‌شوند.

📌 اجرای اسکریپت POSIX در Bash:

#!/bin/bash
echo "Hello, POSIX-compatible script!"

📌 بررسی سازگاری POSIX در شل فعلی:

sh --version

۳. سادگی و خوانایی در اسکریپت‌نویسی

🔹 Bash دارای یک نحو (Syntax) ساده و خوانا است که آن را برای کاربران مبتدی و حرفه‌ای قابل استفاده می‌کند.
🔹 ساختار آن شباهت زیادی به زبان‌های برنامه‌نویسی مانند C و Python دارد، بنابراین یادگیری و استفاده از آن آسان است.

📌 نمونه‌ای از اسکریپت ساده در Bash:

#!/bin/bash
name="Ali"
echo "Hello, $name!"

📌 اجرای اسکریپت:

chmod +x script.sh
./script.sh

۴. پشتیبانی قوی از متغیرها، آرایه‌ها و کنترل جریان

🔹 Bash از متغیرها و آرایه‌ها پشتیبانی می‌کند که در مدیریت داده‌ها بسیار کاربردی است.
🔹 همچنین دارای دستورات شرطی (if, case)، حلقه‌ها (for, while) و توابع است که در اسکریپت‌نویسی به‌شدت مفید هستند.

📌 مثال: استفاده از متغیرها و حلقه for در Bash

#!/bin/bash
names=("Ali" "Sara" "Reza")

for name in "${names[@]}"; do
    echo "Hello, $name!"
done

📌 اجرای اسکریپت:

bash script.sh

۵. مدیریت فرآیندها و اتوماسیون در Bash

🔹 Bash ابزارهای قدرتمندی برای اجرای دستورات به‌صورت پس‌زمینه (&)، متوقف کردن (kill)، و مدیریت فرآیندها (jobs, fg, bg) دارد.
🔹 این ویژگی‌ها برای مدیریت پردازش‌های سرور و اجرای وظایف خودکار بسیار مهم هستند.

📌 اجرای فرآیند در پس‌زمینه:

sleep 60 &

📌 نمایش لیست فرآیندهای در حال اجرا:

jobs

📌 متوقف کردن یک فرآیند خاص:

kill <PID>

📌 اجرای یک فرآیند متوقف‌شده در پس‌زمینه:

bg %1

۶. قابلیت‌های پیشرفته مانند Pipe و Redirection

🔹 Bash به‌خوبی از مکانیزم‌های انتقال داده بین دستورات (Pipe |) و تغییر مسیر ورودی/خروجی (>, <, >>) پشتیبانی می‌کند.
🔹 این قابلیت‌ها در مدیریت داده‌ها و پردازش‌های خط فرمان بسیار مفید هستند.

📌 ارسال خروجی یک دستور به ورودی دستور دیگر:

ls -l | grep "txt"

📌 ذخیره خروجی در یک فایل:

echo "Log entry" >> log.txt

📌 خواندن ورودی از یک فایل و پردازش آن:

cat file.txt | while read line; do echo "Line: $line"; done

۷. امنیت و پایداری بالا

🔹 Bash به دلیل بررسی دقیق ورودی‌ها و اجرای امن دستورات، یکی از شل‌های پایدار و ایمن محسوب می‌شود.
🔹 از مکانیزم‌های کنترل دسترسی (sudo, chmod, chown) و متغیرهای محیطی (export) پشتیبانی می‌کند.

📌 مثال: تغییر سطح دسترسی فایل در Bash

chmod 700 script.sh  # فقط مالک اجرا کند

📌 اجرای دستورات با سطح دسترسی Root:

sudo apt update

۸. پشتیبانی از تعاملات تعاملی و غیرتعاملی

🔹 Bash قابلیت اجرای دستورات به‌صورت تعاملی (Interactive) و اسکریپتی (Non-Interactive) را دارد.
🔹 این ویژگی باعث می‌شود که Bash برای مدیریت سیستم، اجرای دستورات دستی و اجرای اسکریپت‌های خودکار مناسب باشد.

📌 اجرای Bash در حالت تعاملی:

bash

📌 اجرای Bash در حالت غیرتعاملی:

bash script.sh

جمع بندی

🔹 Bash به‌عنوان شل پیش‌فرض برای اسکریپت‌نویسی انتخاب شده است، زیرا:
✅ در اکثر توزیع‌های لینوکس و یونیکس به‌طور پیش‌فرض نصب است.
سازگاری بالایی با POSIX دارد و روی اکثر سیستم‌ها بدون مشکل اجرا می‌شود.
سادگی و خوانایی در اسکریپت‌نویسی را ارائه می‌دهد.
از متغیرها، آرایه‌ها، حلقه‌ها و دستورات شرطی پشتیبانی می‌کند.
✅ دارای مدیریت پیشرفته فرآیندها، لوله‌گذاری (Pipe) و تغییر مسیر ورودی/خروجی است.
پایدار، امن و مناسب برای اجرای وظایف خودکار و مدیریت سرورها می‌باشد.

📌 نتیجه نهایی:
اگر به دنبال یک شل پایدار، قدرتمند و سازگار برای اسکریپت‌نویسی هستید، Bash بهترین انتخاب است.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. ویژگی‌های Shell Scripting”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مزایای استفاده از Shell Scripting” subtitle=”توضیحات کامل”]Shell Scripting یکی از مهم‌ترین و پرکاربردترین مهارت‌ها در مدیریت سیستم‌های لینوکس و یونیکس است. با استفاده از اسکریپت‌نویسی در شل، می‌توان وظایف تکراری را خودکارسازی کرد، فرآیندها را بهینه‌سازی نمود و مدیریت سیستم را ساده‌تر کرد. این قابلیت‌ها باعث افزایش بهره‌وری، کاهش خطاها و صرفه‌جویی در زمان می‌شوند. در ادامه به بررسی مزایای اصلی Shell Scripting می‌پردازیم.


۱. اتوماسیون وظایف تکراری

🔹 بسیاری از وظایف مدیریت سیستم، مانند بکاپ‌گیری، مدیریت کاربران، بررسی وضعیت سرویس‌ها، و به‌روزرسانی‌ها، به‌صورت مداوم انجام می‌شوند.
🔹 با استفاده از Shell Scripting، می‌توان این وظایف را خودکارسازی کرد و نیاز به اجرای دستی آن‌ها را کاهش داد.
🔹 اتوماسیون از بروز خطای انسانی جلوگیری کرده و باعث افزایش دقت می‌شود.

📌 مثال: اسکریپت بکاپ خودکار فایل‌های مهم

#!/bin/bash

backup_dir="/backup"
source_dir="/home/user/Documents"

# ایجاد دایرکتوری بکاپ در صورت عدم وجود
mkdir -p "$backup_dir"

# کپی فایل‌ها به دایرکتوری بکاپ
cp -r "$source_dir" "$backup_dir"

echo "پشتیبان‌گیری انجام شد!"

📌 اجرای اسکریپت:

bash backup.sh

📌 زمان‌بندی اجرای خودکار این اسکریپت هر روز ساعت ۲ بامداد (با cron):

crontab -e

اضافه کردن خط زیر در فایل crontab:

0 2 * * * /path/to/backup.sh

🔹 این تنظیم باعث می‌شود که اسکریپت هر روز رأس ساعت ۲ بامداد اجرا شود.


۲. بهینه‌سازی فرآیندها

🔹 اجرای دستی چندین دستور به‌صورت متوالی زمان‌بر و مستعد خطا است.
🔹 Shell Scripting امکان اجرای چندین دستور به‌صورت خودکار و بهینه را فراهم می‌کند.
🔹 با استفاده از لوله‌گذاری (|) و تغییر مسیر (>, >>)، می‌توان خروجی دستورات را بهینه‌تر مدیریت کرد.

📌 مثال: یافتن بزرگ‌ترین فایل‌ها در یک دایرکتوری و ذخیره نتایج در یک فایل:

#!/bin/bash

directory="/var/log"
output_file="largest_files.txt"

# پیدا کردن ۵ فایل بزرگ و ذخیره در فایل خروجی
du -ah "$directory" | sort -rh | head -n 5 > "$output_file"

echo "فایل‌های بزرگ‌تر در $output_file ذخیره شدند."

📌 اجرای اسکریپت:

bash find_large_files.sh

🔹 این اسکریپت ۵ فایل بزرگ را در دایرکتوری مشخص‌شده پیدا کرده و در فایل largest_files.txt ذخیره می‌کند.


۳. مدیریت آسان سیستم

🔹 Shell Scripting امکان مدیریت کاربران، نظارت بر عملکرد سیستم و بررسی وضعیت سرویس‌ها را ساده‌تر می‌کند.
🔹 با استفاده از اسکریپت‌ها، می‌توان سیستم را به‌صورت خودکار مانیتور کرد و در صورت وقوع مشکل، اعلان دریافت کرد.

📌 مثال: بررسی وضعیت سرویس‌های مهم و ارسال اعلان در صورت عدم اجرا

#!/bin/bash

services=("nginx" "mysql" "ssh")

for service in "${services[@]}"; do
    if ! systemctl is-active --quiet "$service"; then
        echo "⚠️  هشدار: سرویس $service متوقف شده است!"
    fi
done

📌 اجرای اسکریپت:

bash check_services.sh

📌 افزودن این اسکریپت به cron برای اجرای خودکار هر ۱۰ دقیقه:

*/10 * * * * /path/to/check_services.sh

🔹 این اسکریپت هر ۱۰ دقیقه بررسی می‌کند که آیا سرویس‌های مهم در حال اجرا هستند یا خیر.


۴. کاهش مصرف منابع و بهبود کارایی

🔹 اسکریپت‌های Shell نسبت به برنامه‌های گرافیکی و ابزارهای سنگین، منابع کمتری مصرف می‌کنند.
🔹 این ویژگی باعث می‌شود که در سرورها، پردازش‌های زمان‌بر و وظایف سنگین به‌صورت بهینه اجرا شوند.

📌 مثال: حذف فایل‌های موقت قدیمی برای آزادسازی فضای دیسک

#!/bin/bash

# حذف فایل‌های قدیمی‌تر از ۷ روز در دایرکتوری tmp
find /tmp -type f -mtime +7 -exec rm -f {} \;

echo "پاکسازی فایل‌های موقت انجام شد."

📌 زمان‌بندی این اسکریپت برای اجرا هر هفته:

0 0 * * 7 /path/to/cleanup.sh

🔹 این کار باعث جلوگیری از پر شدن فضای دیسک و بهبود عملکرد سرور می‌شود.


۵. قابلیت یکپارچه‌سازی با ابزارهای دیگر

🔹 Shell Scripting به‌راحتی با ابزارهای مدیریتی مانند Ansible، Docker، Git و Kubernetes ترکیب می‌شود.
🔹 این قابلیت باعث می‌شود که Shell Scripting در مدیریت سرورها و توسعه نرم‌افزار نقش کلیدی داشته باشد.

📌 مثال: اجرای یک کانتینر Docker از طریق اسکریپت

#!/bin/bash

container_name="my_app"

# بررسی اجرای کانتینر
if ! docker ps | grep -q "$container_name"; then
    echo "در حال راه‌اندازی کانتینر..."
    docker run -d --name "$container_name" nginx
else
    echo "کانتینر از قبل در حال اجرا است."
fi

📌 اجرای اسکریپت:

bash start_container.sh

🔹 این اسکریپت بررسی می‌کند که آیا کانتینر اجرا شده است یا خیر و در صورت نیاز آن را راه‌اندازی می‌کند.


جمع بندی

Shell Scripting یک ابزار قدرتمند برای مدیریت سیستم، اتوماسیون و بهینه‌سازی فرآیندها است.
اتوماسیون وظایف تکراری باعث صرفه‌جویی در زمان و کاهش خطاهای انسانی می‌شود.
بهینه‌سازی فرآیندها از طریق اجرای بهینه دستورات و کاهش مصرف منابع امکان‌پذیر است.
مدیریت سیستم با استفاده از اسکریپت‌های ساده و کارآمد، آسان‌تر می‌شود.
Shell Scripting امکان ترکیب با ابزارهای DevOps و مدیریت سرورها را دارد.

📌 نتیجه نهایی:
اگر به دنبال یک روش سریع، کارآمد و انعطاف‌پذیر برای مدیریت سیستم‌ها و خودکارسازی وظایف هستید، Shell Scripting بهترین راه‌حل است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تفاوت بین اسکریپت‌نویسی شل و زبان‌های برنامه‌نویسی” subtitle=”توضیحات کامل”]اسکریپت‌نویسی شل و زبان‌های برنامه‌نویسی هر دو برای خودکارسازی وظایف و پردازش داده‌ها استفاده می‌شوند، اما از نظر ساختار، کاربرد و عملکرد تفاوت‌های اساسی دارند. در این بخش، تفاوت‌های کلیدی بین Shell Scripting و زبان‌های برنامه‌نویسی مانند Python، C، Java و دیگر زبان‌های سطح بالا را بررسی می‌کنیم.


۱. تفاوت در هدف و کاربرد

ویژگی Shell Scripting زبان‌های برنامه‌نویسی
هدف اصلی مدیریت و خودکارسازی وظایف در سیستم‌عامل توسعه نرم‌افزارها و برنامه‌های مستقل
کاربرد رایج اجرای دستورات سیستم‌عامل، اتوماسیون و مدیریت سرورها ایجاد نرم‌افزارهای کاربردی، بازی‌ها و وب‌سایت‌ها
تعامل با سیستم‌عامل مستقیماً با کرنل و ابزارهای سیستم‌عامل در ارتباط است نیاز به APIهای سیستم برای تعامل با سیستم‌عامل

Shell Scripting برای مدیریت سیستم و اجرای دستورات سریع در محیط سیستم‌عامل طراحی شده است.
✅ زبان‌های برنامه‌نویسی مانند Python یا C برای ایجاد برنامه‌های کاربردی و توسعه نرم‌افزار مناسب‌تر هستند.

📌 مثال: ایجاد یک فایل در Shell و Python
🔹 در Shell Scripting:

#!/bin/bash
touch myfile.txt
echo "فایل ایجاد شد."

🔹 در Python:

with open("myfile.txt", "w") as file:
    file.write("فایل ایجاد شد.")

✅ در Shell Scripting مستقیماً از دستورات سیستم‌عامل استفاده می‌شود، در حالی که در Python باید از توابع داخلی زبان استفاده کرد.


۲. تفاوت در نحوه اجرا (Interpreter vs Compiler)

🔹 Shell Scripting یک زبان تفسیری (Interpreted) است و خط به خط اجرا می‌شود.
🔹 بسیاری از زبان‌های برنامه‌نویسی مانند C و Java کامپایلری (Compiled) هستند و باید قبل از اجرا به کد ماشین ترجمه شوند.

📌 مثال: اجرای یک اسکریپت در Shell و Python
🔹 در Shell Scripting:

bash myscript.sh

🔹 در C:

gcc myprogram.c -o myprogram
./myprogram

✅ در زبان‌های کامپایلری مانند C، برنامه ابتدا باید کامپایل شود، اما در Shell Scripting، کد مستقیماً اجرا می‌شود.


۳. تفاوت در سرعت و عملکرد

زبان‌های برنامه‌نویسی کامپایلری مانند C و Java سریع‌تر از Shell Scripting هستند، زیرا مستقیماً به کد ماشین ترجمه می‌شوند.
Shell Scripting برای وظایف سبک و مدیریت سیستم بهینه است، اما برای پردازش‌های سنگین سرعت کمتری دارد.

📌 مثال: اجرای یک حلقه برای شمارش ۱ تا ۱۰۰۰۰
🔹 در Shell Scripting (کندتر):

#!/bin/bash
for i in {1..10000}; do
  echo $i > /dev/null
done

🔹 در Python (سریع‌تر):

for i in range(1, 10001):
    pass

✅ اجرای حلقه در Python سریع‌تر است، زیرا Python پردازش داده‌ها را بهینه‌تر انجام می‌دهد.


۴. تفاوت در امکانات و قابلیت‌ها

ویژگی Shell Scripting زبان‌های برنامه‌نویسی
ساختار داده‌ها محدود (متغیرهای ساده، آرایه‌ها) غنی (لیست، دیکشنری، کلاس و شی‌گرایی)
کتابخانه‌ها و ماژول‌ها محدود (استفاده از ابزارهای خط فرمان) گسترده (هزاران کتابخانه در پایتون و جاوا)
شی‌گرایی پشتیبانی نمی‌شود پشتیبانی کامل (در Java، Python و C++)

زبان‌های برنامه‌نویسی انعطاف‌پذیرتر هستند و برای پروژه‌های بزرگ و برنامه‌نویسی شی‌گرا مناسب‌اند.
Shell Scripting برای اجرای سریع دستورات سیستم‌عامل کافی است اما برای برنامه‌های پیچیده محدودیت دارد.

📌 مثال: کار با لیست‌ها در Shell و Python
🔹 در Shell Scripting:

#!/bin/bash
array=(apple banana cherry)
echo "مورد دوم: ${array[1]}"

🔹 در Python:

fruits = ["apple", "banana", "cherry"]
print("مورد دوم:", fruits[1])

✅ Python از ساختارهای داده‌ای پیشرفته‌تری پشتیبانی می‌کند.


۵. تفاوت در قابلیت چندسکویی (Cross-Platform)

Shell Scripting بیشتر مخصوص لینوکس و یونیکس است و روی ویندوز به‌صورت پیش‌فرض اجرا نمی‌شود.
زبان‌های برنامه‌نویسی مانند Python و Java در همه سیستم‌عامل‌ها اجرا می‌شوند.

📌 مثال: اجرای یک برنامه در پلتفرم‌های مختلف
🔹 Shell Scripting (فقط لینوکس و مک):

#!/bin/bash
echo "Hello, World!"

🔹 Python (ویندوز، لینوکس، مک):

print("Hello, World!")

Python روی ویندوز، لینوکس و مک قابل اجرا است، اما Shell Scripting به ابزارهای جانبی برای اجرا در ویندوز نیاز دارد.


۶. ترکیب Shell Scripting با زبان‌های برنامه‌نویسی

در بسیاری از پروژه‌ها، Shell Scripting و زبان‌های برنامه‌نویسی در کنار هم استفاده می‌شوند.
Python، Perl و Ruby می‌توانند اسکریپت‌های Shell را اجرا کنند.

📌 مثال: اجرای یک دستور Shell در Python

import subprocess
subprocess.run(["ls", "-l"])

✅ در این کد، Python از subprocess برای اجرای دستورات Shell استفاده می‌کند.


جمع بندی

Shell Scripting برای اجرای دستورات سریع در سیستم‌عامل و خودکارسازی وظایف ایده‌آل است.
زبان‌های برنامه‌نویسی مانند Python، C و Java برای توسعه نرم‌افزارهای پیچیده‌تر مناسب‌اند.
Shell Scripting کندتر و محدودتر از زبان‌های برنامه‌نویسی است، اما برای مدیریت سیستم‌ها بسیار مفید است.
در پروژه‌های حرفه‌ای، ترکیب Shell Scripting با زبان‌های برنامه‌نویسی باعث افزایش انعطاف‌پذیری می‌شود.

📌 نتیجه نهایی:
اگر به دنبال خودکارسازی وظایف در سیستم‌عامل هستید، از Shell Scripting استفاده کنید.
اگر قصد دارید یک نرم‌افزار کاربردی توسعه دهید، زبان‌های برنامه‌نویسی مانند Python و Java گزینه بهتری هستند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. ساختار اولیه یک اسکریپت شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی Shebang (#!/bin/bash) و نقش آن” subtitle=”توضیحات کامل”]هنگام اجرای یک اسکریپت در سیستم‌عامل‌های مبتنی بر یونیکس (مانند لینوکس و macOS)، سیستم باید بداند که با کدام مفسر (Interpreter) باید کد را اجرا کند. Shebang یک مکانیزم در ابتدای اسکریپت است که این موضوع را مشخص می‌کند.


۱. Shebang چیست؟

Shebang یک خط ویژه در ابتدای اسکریپت‌های Shell است که تعیین می‌کند کدام مفسر باید کد را اجرا کند.
این خط به‌صورت زیر نوشته می‌شود:

#!/path/to/interpreter

معمول‌ترین مقدار برای اسکریپت‌های Bash این است:

#!/bin/bash

در اینجا:

  • #! (Shebang) یک علامت ویژه است که نشان می‌دهد این فایل باید توسط یک مفسر اجرا شود.
  • /bin/bash مسیر مفسر Bash است که اسکریپت را اجرا می‌کند.

۲. نقش Shebang در اسکریپت‌های Shell

تعیین مفسر مناسب: بدون Shebang، سیستم متوجه نمی‌شود که اسکریپت باید با Bash، Python یا زبان دیگری اجرا شود.
عدم نیاز به مشخص کردن مفسر هنگام اجرا: اگر Shebang وجود داشته باشد، می‌توان اسکریپت را مستقیماً اجرا کرد.
سازگاری بهتر در محیط‌های مختلف: استفاده از Shebang باعث می‌شود اسکریپت‌ها در سیستم‌های مختلف به‌درستی اجرا شوند.

📌 مثال: اجرای یک اسکریپت با و بدون Shebang

🔹 بدون Shebang:

echo "Hello, World!"

اجرای این اسکریپت نیاز به مشخص کردن مفسر دارد:

bash script.sh

🔹 با Shebang (#!/bin/bash)

#!/bin/bash
echo "Hello, World!"

در این حالت، می‌توان مستقیماً اسکریپت را اجرا کرد:

chmod +x script.sh  # مجوز اجرای اسکریپت
./script.sh         # اجرای مستقیم اسکریپت

۳. انواع مختلف Shebang و مقایسه آن‌ها

بسته به نوع اسکریپت، می‌توان از مفسرهای مختلف در Shebang استفاده کرد:

Shebang مفسر کاربرد
#!/bin/bash Bash رایج‌ترین شل برای اسکریپت‌نویسی
#!/bin/sh Shell (sh) نسخه ساده‌تر و عمومی‌تر
#!/bin/zsh Z Shell (Zsh) ویژگی‌های پیشرفته‌تر نسبت به Bash
#!/usr/bin/python3 Python 3 اجرای اسکریپت‌های پایتون
#!/usr/bin/env perl Perl اجرای اسکریپت‌های Perl

📌 مثال: استفاده از Python به‌جای Bash در Shebang

#!/usr/bin/python3
print("Hello, World!")

✅ این اسکریپت مستقیماً با Python 3 اجرا می‌شود.


۴. استفاده از #!/usr/bin/env به‌جای مسیر مستقیم مفسر

گاهی اوقات ممکن است مسیر مفسر در سیستم‌های مختلف متفاوت باشد. برای سازگاری بیشتر، می‌توان از env استفاده کرد:

#!/usr/bin/env bash

✅ این روش مسیر مفسر را از متغیرهای محیطی سیستم پیدا می‌کند و تضمین می‌کند که اسکریپت روی همه سیستم‌ها اجرا شود.

📌 مقایسه دو روش:

روش مزایا معایب
#!/bin/bash اجرای سریع‌تر، مسیر ثابت ممکن است در برخی سیستم‌ها مسیر متفاوت باشد
#!/usr/bin/env bash سازگاری بیشتر با سیستم‌های مختلف ممکن است کمی کندتر باشد

۵. بررسی Shebang در یک اسکریپت

برای بررسی اینکه آیا یک اسکریپت به‌درستی از Shebang استفاده می‌کند یا نه، می‌توان از دستور head استفاده کرد:

head -n 1 script.sh

📌 مثال خروجی:

#!/bin/bash

✅ این خروجی نشان می‌دهد که اسکریپت از Bash به‌عنوان مفسر استفاده می‌کند.


جمع بندی

Shebang (#!) مشخص می‌کند که کدام مفسر باید اسکریپت را اجرا کند.
#!/bin/bash رایج‌ترین Shebang برای اسکریپت‌های Bash است.
استفاده از #!/usr/bin/env bash باعث سازگاری بیشتر در سیستم‌های مختلف می‌شود.
Shebang اجرای مستقیم اسکریپت را بدون نیاز به مشخص کردن مفسر امکان‌پذیر می‌کند.
بدون Shebang، باید مفسر را به‌صورت دستی هنگام اجرا مشخص کرد.

📌 نتیجه نهایی:
اگر اسکریپت شما برای مدیریت سیستم و اجرای دستورات خودکار طراحی شده، حتماً از Shebang برای تعیین مفسر استفاده کنید تا اجرای آن سریع‌تر و ساده‌تر شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”ایجاد اولین فایل اسکریپت شل” subtitle=”توضیحات کامل”]در این قسمت، نحوه ایجاد یک اسکریپت ساده در شل را بررسی می‌کنیم. این اسکریپت شامل ایجاد فایل، نوشتن کد، دادن مجوز اجرا و اجرای آن خواهد بود.


۱. ایجاد یک فایل اسکریپت جدید

برای ایجاد یک اسکریپت شل، مراحل زیر را دنبال کنید:

مرحله ۱: ایجاد یک فایل اسکریپت
با استفاده از ویرایشگر nano (یا هر ویرایشگر دیگر مانند vim یا touch)، یک فایل جدید ایجاد کنید:

nano myscript.sh

یا با دستور زیر یک فایل خالی بسازید:

touch myscript.sh

مرحله ۲: افزودن Shebang (#!)
فایل را باز کرده و خط زیر را به آن اضافه کنید:

#!/bin/bash

📌 این خط مشخص می‌کند که این اسکریپت باید با Bash اجرا شود.

مرحله ۳: نوشتن دستورات اسکریپت
چند دستور ساده به فایل اضافه کنید:

#!/bin/bash

echo "Hello, World!"
echo "این اولین اسکریپت شل من است."

مرحله ۴: ذخیره و خروج از ویرایشگر
در nano، برای ذخیره و خروج:

  1. CTRL + X را فشار دهید.
  2. کلید Y را بزنید تا تغییرات ذخیره شوند.
  3. کلید Enter را فشار دهید تا از ویرایشگر خارج شوید.

۲. دادن مجوز اجرای اسکریپت

پس از ایجاد فایل، باید به آن مجوز اجرا بدهید. این کار را با دستور زیر انجام دهید:

chmod +x myscript.sh

📌 این دستور اجازه اجرای اسکریپت را می‌دهد.


۳. اجرای اسکریپت شل

روش ۱: اجرای مستقیم

./myscript.sh

روش ۲: اجرای با bash

bash myscript.sh

📌 روش اول فقط در صورتی کار می‌کند که اسکریپت مجوز اجرا (+x) داشته باشد، اما روش دوم نیازی به این مجوز ندارد.


۴. بررسی خروجی اسکریپت

پس از اجرا، خروجی زیر را خواهید دید:

Hello, World!
این اولین اسکریپت شل من است.

✅ این یعنی اسکریپت شما به‌درستی اجرا شده است! 🎉


۵. اضافه کردن ورودی از کاربر

برای گرفتن ورودی از کاربر، از دستور read استفاده کنید. فایل را ویرایش کرده و کد زیر را به آن اضافه کنید:

#!/bin/bash

echo "نام شما چیست؟"
read name
echo "سلام، $name! به دنیای Shell Scripting خوش آمدی."

🚀 اجرای مجدد اسکریپت:

./myscript.sh

📌 نمونه خروجی:

نام شما چیست؟
علی
سلام، علی! به دنیای Shell Scripting خوش آمدی.

جمع بندی

یک فایل اسکریپت شل با استفاده از nano یا touch ایجاد کردیم.
Shebang (#!/bin/bash) را برای مشخص کردن مفسر اضافه کردیم.
یک اسکریپت ساده نوشتیم که پیام نمایش می‌دهد.
مجوز اجرا را با chmod +x تنظیم کردیم.
اسکریپت را با ./myscript.sh و bash myscript.sh اجرا کردیم.
یک ورودی از کاربر گرفتیم و آن را در خروجی نمایش دادیم.

📌 نتیجه: حالا شما اولین اسکریپت شل خود را نوشته و اجرا کرده‌اید! 🚀[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”اصول نام‌گذاری و ذخیره اسکریپت‌ها با پسوند .sh” subtitle=”توضیحات کامل”]در این قسمت، اهمیت نام‌گذاری اسکریپت‌های شل، استانداردهای مربوط به آن، و نحوه ذخیره صحیح این فایل‌ها را بررسی می‌کنیم.


۱. چرا از پسوند .sh استفاده می‌کنیم؟

تشخیص آسان: پسوند .sh مشخص می‌کند که این فایل یک اسکریپت شل است.
سازگاری با ابزارها: برخی ویرایشگرها و سیستم‌ها، فایل‌های .sh را به‌عنوان اسکریپت شناسایی می‌کنند.
قابلیت خوانایی: پسوند .sh کمک می‌کند تا کاربران بدانند این فایل چه کاربردی دارد.

📌 نکته: در لینوکس، پسوند .sh الزامی نیست، اما توصیه می‌شود برای شفافیت بیشتر از آن استفاده کنید.


۲. استانداردهای نام‌گذاری اسکریپت‌های شل

📌 هنگام نام‌گذاری اسکریپت‌ها، به نکات زیر توجه کنید:

از نام‌های توصیفی استفاده کنید.
نام‌های عمومی مانند script.sh مناسب نیستند.
از حروف کوچک و خط زیر (_) برای جدا کردن کلمات استفاده کنید.
از فاصله (space) و کاراکترهای خاص (!@#$%^&*()) در نام‌ها استفاده نکنید.
در صورت نیاز، می‌توانید از - برای جدا کردن کلمات استفاده کنید.

📌 مثال‌های صحیح:

backup_script.sh
database_backup.sh
user_management.sh

📌 مثال‌های نادرست:

backup script.sh  (فضای خالی دارد ❌)
backup!script.sh  (کاراکتر خاص ❌)
Script.SH         (حروف بزرگ ❌)

۳. نحوه ذخیره اسکریپت در مسیر مناسب

✅ برای مدیریت بهتر اسکریپت‌ها، بهتر است آن‌ها را در یک دایرکتوری خاص نگهداری کنید.

🔹 ذخیره در /usr/local/bin/ (برای اجرای عمومی):

sudo mv my_script.sh /usr/local/bin/

🔹 ذخیره در ~/scripts/ (دایرکتوری شخصی کاربر):

mkdir -p ~/scripts
mv my_script.sh ~/scripts/

🔹 افزودن مسیر ~/scripts/ به PATH:

export PATH=$PATH:~/scripts

📌 با این کار، می‌توان اسکریپت را از هر جایی اجرا کرد.


۴. ایجاد و ذخیره اسکریپت نمونه

ایجاد یک اسکریپت جدید با nano

nano my_first_script.sh

افزودن محتوای اسکریپت

#!/bin/bash

echo "این اولین اسکریپت من است!"

ذخیره و خروج:
در nano، دکمه‌های CTRL + X را بزنید، سپس Y را تایپ کرده و Enter بزنید.

دادن مجوز اجرا:

chmod +x my_first_script.sh

اجرای اسکریپت:

./my_first_script.sh

📌 خروجی:

این اولین اسکریپت من است!

جمع‌بندی

استفاده از پسوند .sh برای تشخیص آسان‌تر اسکریپت‌ها توصیه می‌شود.
نام‌گذاری استاندارد شامل استفاده از حروف کوچک، _ و - است.
بهتر است اسکریپت‌ها را در مسیرهای مشخص مانند ~/scripts/ یا /usr/local/bin/ ذخیره کنیم.
دادن مجوز اجرا با chmod +x و اجرای اسکریپت با ./script.sh ضروری است.

📌 نتیجه: اکنون می‌دانید چطور اسکریپت‌های شل را به‌درستی نام‌گذاری و ذخیره کنید! 🚀[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. اجرای اسکریپت شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”اعطای مجوز اجرایی به اسکریپت با استفاده از دستور chmod” subtitle=”توضیحات کامل”]برای اجرای یک اسکریپت در لینوکس، ابتدا باید مجوز اجرایی به آن داده شود. این کار با استفاده از دستور chmod انجام می‌شود. در ادامه روش‌های مختلف تنظیم مجوز اجرا برای اسکریپت‌ها را بررسی می‌کنیم.


بررسی مجوزهای یک فایل

قبل از اعمال تغییرات، می‌توان مجوزهای فعلی فایل را با دستور زیر بررسی کرد:

ls -l my_script.sh

📌 خروجی نمونه:

-rw-r--r--  1 user user  42 Feb 21 10:00 my_script.sh

در این حالت، فایل فقط قابل خواندن و نوشتن است اما قابل اجرا نیست.


دادن مجوز اجرایی به یک اسکریپت

🔹 برای دادن مجوز اجرایی به مالک فایل (کاربری که اسکریپت را ایجاد کرده است):

chmod u+x my_script.sh

🔹 برای دادن مجوز اجرایی به همه کاربران (مالک، گروه و سایر کاربران):

chmod +x my_script.sh

🔹 برای دادن مجوز فقط به گروه و سایر کاربران:

chmod go+x my_script.sh

📌 بررسی مجدد مجوزها:

ls -l my_script.sh

📌 خروجی پس از اعطای مجوز اجرایی:

-rwxr-xr-x  1 user user  42 Feb 21 10:00 my_script.sh

اکنون اسکریپت قابل اجرا است.


اجرای اسکریپت پس از اعطای مجوز

✅ اگر اسکریپت در دایرکتوری جاری (.) قرار دارد:

./my_script.sh

✅ اگر در مسیر /usr/local/bin/ ذخیره شده باشد:

my_script.sh

(در این حالت، اسکریپت را می‌توان از هر جایی اجرا کرد.)


حذف مجوز اجرایی (در صورت نیاز)

برای غیرفعال کردن قابلیت اجرا:

chmod -x my_script.sh

اکنون این فایل دیگر به‌عنوان یک اسکریپت اجرایی شناخته نمی‌شود.


جمع‌بندی

✅ برای اجرای یک اسکریپت، باید مجوز اجرایی به آن داده شود.
✅ دستور chmod +x فایل را به یک اسکریپت قابل اجرا تبدیل می‌کند.
✅ می‌توان سطح دسترسی را برای مالک (u)، گروه (g) و سایر کاربران (o) مشخص کرد.
✅ پس از تنظیم مجوز، اسکریپت را می‌توان با ./script.sh یا از مسیرهای تعریف‌شده اجرا کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”روش‌های مختلف اجرای اسکریپت در لینوکس” subtitle=”توضیحات کامل”]در لینوکس، چندین روش برای اجرای اسکریپت‌های شل وجود دارد که هر کدام کاربرد خاص خود را دارند. در ادامه روش‌های مختلف اجرا را بررسی می‌کنیم.


اجرای مستقیم با نام فایل (./script.sh)

یکی از رایج‌ترین روش‌ها اجرای مستقیم اسکریپت است. برای این کار ابتدا باید به اسکریپت مجوز اجرایی داده شود:

chmod +x script.sh

سپس می‌توان آن را با این دستور اجرا کرد:

./script.sh

📌 نکات مهم:

  • این روش اسکریپت را در یک ساب‌شل (Subshell) اجرا می‌کند، به این معنی که تغییرات انجام‌شده در متغیرهای محیطی فقط درون اسکریپت اعمال می‌شوند و روی شل اصلی تأثیر نمی‌گذارند.
  • برای اجرای اسکریپت از مسیر جاری (./)، باید حتماً در همان دایرکتوری باشید.

اجرای اسکریپت از طریق شل (bash script.sh)

می‌توان اسکریپت را به‌طور مستقیم توسط یک شل مشخص اجرا کرد. به‌عنوان مثال، برای اجرای یک اسکریپت با bash:

bash script.sh

📌 تفاوت با روش قبل:

  • نیازی به اعطای مجوز اجرایی (chmod +x) نیست.
  • در این روش، اسکریپت در یک فرآیند جدید از bash اجرا می‌شود.
  • این روش مناسب زمانی است که می‌خواهید اسکریپت را با یک شل خاص اجرا کنید.

مثال اجرای اسکریپت با sh:

sh script.sh

اجرای اسکریپت با source یا . (اجرای درون همان شل)

اگر بخواهید اسکریپت را در همان محیط شل فعلی اجرا کنید (بدون ایجاد یک ساب‌شل جدید)، از source یا . استفاده کنید:

source script.sh
# یا معادل آن:
. script.sh

📌 کاربرد:

  • زمانی که اسکریپت شامل تغییرات روی متغیرهای محیطی باشد و بخواهید این تغییرات درون همان شل اعمال شوند.
  • برای بارگذاری فایل‌های پیکربندی.

مثال:

export VAR="Hello"
./script.sh
echo $VAR   # مقدار تغییر نمی‌کند

source script.sh
echo $VAR   # مقدار تغییر کرده است

اجرای اسکریپت با مسیر کامل

اگر اسکریپت در مسیر /home/user/scripts/script.sh قرار دارد، می‌توان مستقیماً با مسیر کامل آن را اجرا کرد:

/home/user/scripts/script.sh

یا اگر اسکریپت در /usr/local/bin/ باشد و این مسیر در PATH تعریف شده باشد، می‌توان فقط با نام آن اجرا کرد:

script.sh

اجرای اسکریپت در یک شل متفاوت (Zsh, Ksh, etc.)

برای اجرای یک اسکریپت در یک شل دیگر، کافی است آن شل را مشخص کنید:

zsh script.sh
ksh script.sh

این روش زمانی مفید است که می‌خواهید اسکریپت را در محیطی غیر از bash اجرا کنید.


جمع‌بندی

اجرای مستقیم (./script.sh) → نیاز به مجوز اجرایی دارد و اسکریپت را در یک ساب‌شل اجرا می‌کند.
اجرای با شل (bash script.sh) → نیازی به مجوز اجرایی ندارد و اسکریپت در یک فرآیند جدید اجرا می‌شود.
اجرای با source یا . → اسکریپت در همان شل اجرا می‌شود و تغییرات محیطی حفظ می‌شوند.
اجرای با مسیر کامل → بدون نیاز به تغییر مسیر دایرکتوری، مستقیماً از هرجایی اجرا می‌شود.
اجرای با شل‌های دیگر (zsh script.sh) → امکان اجرای اسکریپت در محیط‌های دیگر مانند Zsh و Ksh را فراهم می‌کند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی خطاهای رایج در اجرای اسکریپت‌ها” subtitle=”توضیحات کامل”]در هنگام اجرای اسکریپت‌های شل، ممکن است با انواع مختلفی از خطاها روبه‌رو شوید. این خطاها می‌توانند ناشی از مجوزهای نادرست، اشتباه در سینتکس، نبودن فایل موردنظر یا خطاهای منطقی باشند. در این قسمت، رایج‌ترین خطاها و روش‌های رفع آن‌ها بررسی می‌شود.


۱. خطای “Permission Denied” (عدم مجوز اجرا)

پیام خطا:

bash: ./script.sh: Permission denied

📌 علت:

  • اسکریپت دارای مجوز اجرایی نیست.
  • فایل متعلق به کاربری است که دسترسی به اجرای آن ندارد.

🔹 راه‌حل:
برای اعطای مجوز اجرایی به اسکریپت، از دستور زیر استفاده کنید:

chmod +x script.sh

اگر همچنان اجرا نمی‌شود، بررسی کنید که کاربر مجوز لازم را دارد:

ls -l script.sh

اگر فایل متعلق به کاربر دیگری است، می‌توان مالکیت آن را تغییر داد:

sudo chown $USER script.sh

۲. خطای “No such file or directory” (فایل یا دایرکتوری وجود ندارد)

پیام خطا:

bash: ./script.sh: No such file or directory

📌 علت:

  • فایل اسکریپت در مسیر مشخص‌شده وجود ندارد.
  • شل موردنظر برای اجرا در shebang (#!/bin/bash) وجود ندارد یا به اشتباه نوشته شده است.

🔹 راه‌حل:
۱. بررسی کنید که اسکریپت در مسیر موردنظر قرار دارد:

ls -l script.sh

۲. در صورت نیاز، مسیر اسکریپت را مشخص کنید:

/path/to/script.sh

۳. اگر فایل دارای shebang نادرست است، مطمئن شوید که مسیر صحیح را استفاده کرده‌اید. مسیر صحیح را می‌توان با دستور زیر یافت:

which bash

سپس مقدار صحیح را در ابتدای اسکریپت قرار دهید:

#!/usr/bin/bash

۳. خطای “Command not found” (دستور یافت نشد)

پیام خطا:

script.sh: line 3: somecommand: command not found

📌 علت:

  • دستور موردنظر در سیستم نصب نیست.
  • نام دستور اشتباه تایپ شده است.
  • مسیر دستور در متغیر PATH تعریف نشده است.

🔹 راه‌حل:
۱. بررسی کنید که آیا دستور در سیستم وجود دارد:

which somecommand

۲. اگر خروجی چیزی نمایش نداد، احتمالاً این ابزار نصب نیست. در این صورت آن را نصب کنید:

sudo apt install somecommand  # در اوبونتو و دبیان
sudo yum install somecommand  # در CentOS و RHEL

۳. اگر دستور در مسیر /usr/local/bin/ یا مسیر دیگری است، باید مسیر کامل آن را اجرا کنید:

/usr/local/bin/somecommand

۴. خطای “Syntax error” (خطای نحوی)

پیام خطا:

script.sh: line 5: syntax error near unexpected token `fi'

📌 علت:

  • اشتباه در نحوه نگارش شرط‌ها یا دستورات.
  • عدم تطابق if و fi، یا do و done.

🔹 راه‌حل:
۱. بررسی کنید که ساختار کد صحیح باشد. برای مثال، اگر از if استفاده شده است، fi نیز باید باشد:

if [ $var -eq 1 ]; then
    echo "Variable is 1"
fi

۲. برای بررسی وجود خطا در اسکریپت، از دستور bash -n استفاده کنید:

bash -n script.sh

این دستور بدون اجرای اسکریپت، خطاهای نحوی را بررسی می‌کند.


۵. خطای “Unexpected end of file” (پایان غیرمنتظره فایل)

پیام خطا:

script.sh: line 10: syntax error: unexpected end of file

📌 علت:

  • یکی از ساختارهای کنترلی (مثل if, case, while) به درستی بسته نشده است.
  • یک do, then یا fi جا افتاده است.

🔹 راه‌حل:
۱. بررسی کنید که دستورات if, for, while و case به درستی بسته شده باشند.
۲. از دستورات set -x یا echo برای دیباگ استفاده کنید:

set -x  # فعال‌سازی حالت دیباگ
./script.sh
set +x  # غیرفعال‌سازی حالت دیباگ

۶. خطای “Argument list too long” (طول لیست آرگومان‌ها بیش از حد مجاز است)

پیام خطا:

bash: /bin/ls: Argument list too long

📌 علت:

  • اجرای یک دستور با تعداد بسیار زیادی آرگومان، که از محدودیت ARG_MAX در سیستم فراتر رفته است.

🔹 راه‌حل:
۱. به جای ارسال همه فایل‌ها یکجا، از xargs استفاده کنید:

ls | xargs rm

۲. از find همراه با -exec استفاده کنید:

find . -name "*.log" -exec rm {} \;

۷. خطای “Out of memory” (کمبود حافظه)

📌 علت:

  • اسکریپت دارای یک حلقه بی‌پایان است که باعث مصرف بیش از حد حافظه می‌شود.
  • اجرای دستورات حجیم که مقدار زیادی رم مصرف می‌کنند.

🔹 راه‌حل:
۱. بررسی کنید که اسکریپت وارد یک حلقه بی‌پایان نشده باشد:

while true; do
    echo "Running..."
done

باید یک شرط خروج برای حلقه تنظیم شود.
۲. مقدار حافظه آزاد را بررسی کنید:

free -m

۳. فرآیندهای پرمصرف را پیدا کنید و در صورت نیاز متوقف کنید:

top
kill -9 PID

جمع‌بندی

Permission Denied → اعطای مجوز اجرایی با chmod +x script.sh.
No such file or directory → بررسی مسیر اسکریپت و shebang.
Command not found → بررسی وجود دستور و نصب آن.
Syntax error → بررسی و اصلاح سینتکس کد.
Unexpected end of file → بستن درست دستورات شرطی.
Argument list too long → استفاده از xargs یا find -exec.
Out of memory → بررسی مصرف حافظه و جلوگیری از حلقه‌های بی‌پایان.

با رعایت این نکات، اجرای اسکریپت‌های شل بدون خطا و با کارایی بالا انجام خواهد شد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. انواع اسکریپت‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی سه نوع اصلی اسکریپت‌های شل” subtitle=”توضیحات کامل”]اسکریپت‌های شل بر اساس نحوه اجرا و تعامل با کاربر به سه دسته اصلی تقسیم می‌شوند:

  1. Batch Scripts (اسکریپت‌های دسته‌ای)
  2. Interactive Scripts (اسکریپت‌های تعاملی)
  3. Non-Interactive Scripts (اسکریپت‌های غیرتعاملی)

هر یک از این انواع کاربرد خاص خود را دارند و در مدیریت سیستم‌های لینوکسی مورد استفاده قرار می‌گیرند. در ادامه، هر نوع را با مثال عملی توضیح می‌دهیم.


۱. Batch Scripts (اسکریپت‌های دسته‌ای)

📌 تعریف:
اسکریپت‌های دسته‌ای مجموعه‌ای از دستورات هستند که بدون نیاز به ورودی کاربر اجرا می‌شوند. این اسکریپت‌ها برای انجام وظایف از پیش تعریف‌شده، مانند پشتیبان‌گیری، حذف فایل‌های قدیمی و اجرای کران‌جاب‌ها استفاده می‌شوند.

🔹 ویژگی‌ها:

  • اجرا به‌صورت خودکار
  • عدم نیاز به تعامل با کاربر
  • قابل زمان‌بندی از طریق cron

🔹 مثال:
اسکریپتی که هر روز ساعت ۲ بامداد از /home/user/Documents نسخه پشتیبان تهیه کند.

#!/bin/bash

# مسیر مقصد برای پشتیبان‌گیری
BACKUP_DIR="/backup"
SOURCE_DIR="/home/user/Documents"

# ایجاد فایل پشتیبان
tar -czf "$BACKUP_DIR/backup_$(date +%F).tar.gz" "$SOURCE_DIR"

echo "پشتیبان‌گیری انجام شد: $(date)"

🔹 اجرای خودکار با cron
برای اجرای این اسکریپت هر روز ساعت ۲ بامداد:

crontab -e

سپس این خط را اضافه کنید:

0 2 * * * /path/to/script.sh

۲. Interactive Scripts (اسکریپت‌های تعاملی)

📌 تعریف:
اسکریپت‌های تعاملی در هنگام اجرا از کاربر ورودی دریافت می‌کنند. این نوع اسکریپت‌ها معمولاً برای عملیات مدیریتی و تستی استفاده می‌شوند.

🔹 ویژگی‌ها:

  • نیاز به ورودی کاربر
  • استفاده از read برای دریافت اطلاعات
  • مناسب برای اجرای دستورات خاص

🔹 مثال:
اسکریپتی که از کاربر نام و سن را دریافت کرده و پیامی متناسب نمایش دهد.

#!/bin/bash

# دریافت نام کاربر
read -p "لطفا نام خود را وارد کنید: " name

# دریافت سن کاربر
read -p "لطفا سن خود را وارد کنید: " age

# نمایش پیام
echo "سلام $name! شما $age ساله هستید."

🔹 اجرای اسکریپت:

bash interactive_script.sh

📌 ورودی و خروجی:

لطفا نام خود را وارد کنید: علی  
لطفا سن خود را وارد کنید: ۲۵  
سلام علی! شما ۲۵ ساله هستید.

۳. Non-Interactive Scripts (اسکریپت‌های غیرتعاملی)

📌 تعریف:
اسکریپت‌های غیرتعاملی بدون نیاز به ورودی مستقیم کاربر اجرا می‌شوند. این اسکریپت‌ها برای خودکارسازی وظایف و اجرای دستورات سیستمی بدون نیاز به نظارت مفید هستند.

🔹 ویژگی‌ها:

  • اجرای خودکار
  • معمولاً همراه با cron یا systemd
  • استفاده از ورودی‌های از پیش تعریف‌شده

🔹 مثال:
اسکریپتی که اطلاعات فضای دیسک را بدون نیاز به ورودی کاربر در فایلی ذخیره کند.

#!/bin/bash

LOG_FILE="/var/log/disk_usage.log"

# دریافت اطلاعات دیسک و ذخیره در فایل
df -h > "$LOG_FILE"

echo "اطلاعات دیسک ذخیره شد: $(date)" >> "$LOG_FILE"

🔹 اجرای خودکار با cron

0 * * * * /path/to/script.sh

📌 نتیجه:
هر ساعت یک‌بار، اطلاعات فضای دیسک در فایل /var/log/disk_usage.log ذخیره می‌شود.


جمع‌بندی

Batch Scripts → اجرای خودکار، بدون نیاز به ورودی (مثال: پشتیبان‌گیری).
Interactive Scripts → نیاز به ورودی کاربر، تعامل مستقیم (مثال: دریافت نام و سن).
Non-Interactive Scripts → اجرای خودکار، بدون نیاز به ورودی لحظه‌ای (مثال: ثبت اطلاعات دیسک).

این سه نوع اسکریپت، پایه‌های اصلی اسکریپت‌نویسی در لینوکس را تشکیل می‌دهند و در سناریوهای مختلف مدیریتی و خودکارسازی استفاده می‌شوند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 7. ملاحظات اولیه در Shell Scripting”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”انتخاب ویرایشگر متن مناسب برای نوشتن اسکریپت” subtitle=”توضیحات کامل”]برای نوشتن اسکریپت‌های شل، نیاز به یک ویرایشگر متن داریم که بتواند کدها را به‌درستی ویرایش و ذخیره کند. انتخاب ویرایشگر بستگی به سطح تجربه کاربر، نیازهای پروژه و قابلیت‌های مورد انتظار دارد. در این بخش، برخی از محبوب‌ترین ویرایشگرهای متنی برای اسکریپت‌نویسی را بررسی می‌کنیم.


۱. Vim

📌 تعریف:
Vim یک ویرایشگر قدرتمند و پیش‌فرض در اکثر توزیع‌های لینوکس است. این ویرایشگر به دلیل سرعت بالا، قابلیت‌های شخصی‌سازی و پشتیبانی از پلاگین‌ها، یکی از محبوب‌ترین انتخاب‌ها برای توسعه‌دهندگان حرفه‌ای محسوب می‌شود.

🔹 ویژگی‌ها:

  • دارای حالت‌های مختلف (معمولی، درج، دستوری)
  • قابلیت‌های گسترده برای جستجو و جایگزینی متن
  • پشتیبانی از پلاگین‌ها برای افزایش امکانات

🔹 نصب Vim (اگر از قبل نصب نیست)

sudo apt install vim    # برای اوبونتو و دبیان
sudo yum install vim    # برای سنت‌اواس و فدورا

🔹 ایجاد و ویرایش اسکریپت با Vim

vim script.sh

پس از باز شدن Vim:

  • برای ویرایش i را بزنید.
  • برای ذخیره و خروج، Esc سپس :wq را وارد کنید.

۲. Nano

📌 تعریف:
Nano یک ویرایشگر ساده و کاربرپسند است که برای مبتدیان گزینه مناسبی محسوب می‌شود. این ویرایشگر دارای کلیدهای میانبر مشخصی است و یادگیری آن آسان است.

🔹 ویژگی‌ها:

  • رابط کاربری ساده
  • کلیدهای میانبر برای ذخیره، خروج و ویرایش
  • مناسب برای کاربران تازه‌کار

🔹 نصب Nano (اگر از قبل نصب نیست)

sudo apt install nano

🔹 ایجاد و ویرایش اسکریپت با Nano

nano script.sh

پس از باز شدن Nano:

  • برای ویرایش، مستقیماً تایپ کنید.
  • برای ذخیره و خروج، Ctrl + X سپس Y و Enter را فشار دهید.

۳. Emacs

📌 تعریف:
Emacs یک ویرایشگر پیشرفته با امکاناتی مانند پشتیبانی از ماکروها، پلاگین‌ها و محیط چندکاره است.

🔹 ویژگی‌ها:

  • امکان شخصی‌سازی بالا
  • پشتیبانی از حالت‌های مختلف کدنویسی
  • دارای محیط کاربرپسندتر نسبت به Vim

🔹 نصب Emacs

sudo apt install emacs

🔹 ایجاد و ویرایش اسکریپت با Emacs

emacs script.sh

پس از باز شدن Emacs:

  • برای تایپ، مستقیماً شروع به نوشتن کنید.
  • برای ذخیره و خروج، Ctrl + X سپس Ctrl + S و Ctrl + X سپس Ctrl + C را فشار دهید.

۴. سایر ویرایشگرها

VS Code → دارای محیط گرافیکی، افزونه‌های قوی برای Bash.
Sublime Text → سبک و سریع، پشتیبانی از رنگ‌بندی کدها.
Gedit → مناسب برای کاربران گرافیکی در لینوکس.


جمع‌بندی

Vim → مناسب برای کاربران حرفه‌ای، سرعت بالا و قابلیت شخصی‌سازی.
Nano → ساده و کاربرپسند، مناسب برای مبتدیان.
Emacs → پرقدرت، با قابلیت‌های توسعه‌یافته.
VS Code، Sublime، Gedit → مناسب برای کاربران گرافیکی.

انتخاب ویرایشگر مناسب بستگی به نیاز و سطح تجربه شما دارد. اگر تازه‌کار هستید، Nano گزینه مناسبی است. اگر به دنبال قابلیت‌های پیشرفته هستید، Vim و Emacs انتخاب‌های بهتری خواهند بود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مدیریت مسیر فایل‌های اسکریپت” subtitle=”توضیحات کامل”]مدیریت مسیر فایل‌های اسکریپت در لینوکس و یونیکس اهمیت زیادی دارد، زیرا اجرای صحیح اسکریپت‌ها و دسترسی به فایل‌های موردنیاز به مسیرهای درست بستگی دارد. در این بخش، مفاهیم مسیرهای نسبی و مطلق، تنظیم متغیر PATH، اجرای اسکریپت از مسیرهای مختلف و مدیریت مسیرهای اسکریپت بررسی خواهد شد.


۱. تفاوت مسیرهای نسبی و مطلق

🔹 مسیر مطلق (Absolute Path):
یک مسیر مطلق همیشه از دایرکتوری ریشه (/) شروع می‌شود و به طور کامل مسیر فایل را مشخص می‌کند.

📌 مثال:

/home/user/scripts/myscript.sh

🔹 مسیر نسبی (Relative Path):
یک مسیر نسبی بر اساس موقعیت فعلی (Current Working Directory – CWD) تعیین می‌شود.

📌 مثال:

./myscript.sh
../scripts/myscript.sh

در اینجا:

  • ./myscript.sh → اسکریپت در همان دایرکتوری جاری اجرا می‌شود.
  • ../scripts/myscript.sh → اسکریپت در یک دایرکتوری بالاتر اجرا می‌شود.

🔹 نمایش مسیر دایرکتوری جاری:

pwd

۲. تنظیم و مدیریت PATH برای اجرای اسکریپت

🔹 متغیر محیطی PATH چیست؟
PATH لیستی از دایرکتوری‌هایی است که سیستم هنگام اجرای یک دستور بررسی می‌کند. اگر مسیر اسکریپت در PATH تنظیم نشده باشد، باید مسیر کامل آن را مشخص کنید.

🔹 نمایش مقدار PATH:

echo $PATH

🔹 اضافه کردن مسیر جدید به PATH:
مثلاً اگر اسکریپت‌های شما در /home/user/scripts/ ذخیره شده‌اند، می‌توانید این مسیر را به PATH اضافه کنید:

export PATH=$PATH:/home/user/scripts

🔸 نکته: این تغییر موقتی است و پس از خروج از شل از بین می‌رود.

🔹 برای دائمی کردن تغییر:
مسیر را به ~/.bashrc یا ~/.profile اضافه کنید:

echo 'export PATH=$PATH:/home/user/scripts' >> ~/.bashrc
source ~/.bashrc

۳. اجرای اسکریپت از مسیرهای مختلف

🔹 اجرای اسکریپت با مسیر مطلق:

/home/user/scripts/myscript.sh

🔹 اجرای اسکریپت با مسیر نسبی:

./myscript.sh

🔹 اجرای اسکریپت بدون نیاز به نوشتن مسیر (اگر در PATH باشد):

myscript.sh

🔹 اجرای اسکریپت با یک شل مشخص (مثلاً Bash):

bash myscript.sh

یا

sh myscript.sh

🔹 اجرا با سورس کردن (در همان شل فعلی اجرا شود، مثلاً برای تغییر متغیرها):

source myscript.sh

یا

. myscript.sh

۴. یافتن مسیر یک اسکریپت در حال اجرا

گاهی اوقات نیاز است که مسیر واقعی اسکریپت خود را از درون آن اسکریپت پیدا کنیم.

📌 دریافت مسیر کامل اسکریپت:

SCRIPT_PATH=$(realpath "$0")
echo "این اسکریپت در مسیر: $SCRIPT_PATH ذخیره شده است"

📌 دریافت دایرکتوری اسکریپت:

SCRIPT_DIR=$(dirname "$(realpath "$0")")
echo "دایرکتوری اسکریپت: $SCRIPT_DIR"

۵. تغییر مسیر کاری (Working Directory) داخل اسکریپت

اگر بخواهید اسکریپت در همان مسیری که قرار دارد اجرا شود، می‌توانید مسیر را تغییر دهید:

cd "$(dirname "$(realpath "$0")")"

این کار باعث می‌شود که اسکریپت همیشه در دایرکتوری خودش اجرا شود، بدون توجه به این‌که از کجا اجرا شده است.


۶. بررسی وجود فایل قبل از اجرا

📌 چک کردن اینکه آیا فایل اسکریپت وجود دارد یا نه:

if [ -f "/home/user/scripts/myscript.sh" ]; then
    echo "فایل وجود دارد، در حال اجرا..."
    /home/user/scripts/myscript.sh
else
    echo "فایل موردنظر پیدا نشد!"
fi

📌 چک کردن وجود دایرکتوری:

if [ -d "/home/user/scripts/" ]; then
    echo "دایرکتوری موجود است."
else
    echo "دایرکتوری یافت نشد!"
fi

جمع‌بندی

✅ مسیرهای مطلق همیشه از / شروع می‌شوند، اما مسیرهای نسبی بر اساس دایرکتوری جاری تنظیم می‌شوند.
✅ متغیر PATH مسیرهایی که شل برای یافتن اسکریپت‌ها بررسی می‌کند را مشخص می‌کند.
✅ برای اجرای یک اسکریپت می‌توان از روش‌های مختلفی مانند ./script.sh، bash script.sh یا source script.sh استفاده کرد.
✅ می‌توان مسیر واقعی یک اسکریپت را از داخل آن با realpath "$0" دریافت کرد.
✅ برای اجرای صحیح اسکریپت، اطمینان از وجود فایل یا دایرکتوری قبل از اجرا مهم است.

با رعایت این اصول، مدیریت مسیر اسکریپت‌ها در لینوکس آسان‌تر خواهد شد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”نکات اولیه برای نوشتن اسکریپت‌های خوانا و کارآمد” subtitle=”توضیحات کامل”]نوشتن اسکریپت‌های خوانا و کارآمد باعث افزایش بهره‌وری، کاهش خطاها و بهبود نگهداری کد می‌شود. در این بخش، مهم‌ترین نکاتی که برای بهینه‌سازی و خوانایی اسکریپت‌های شل باید رعایت شوند، بررسی می‌کنیم.


۱. استفاده از Shebang صحیح

اولین خط هر اسکریپت شل باید Shebang داشته باشد تا سیستم بفهمد کدام شل باید برای اجرای اسکریپت استفاده شود.

🔹 برای Bash:

#!/bin/bash

🔹 برای Sh (سازگاری بیشتر با سیستم‌های مختلف):

#!/bin/sh

🔹 برای اجرای خودکار شل پیش‌فرض سیستم:

#!/usr/bin/env bash

۲. استفاده از نام‌گذاری مناسب برای متغیرها

✅ از نام‌های معنادار برای متغیرها استفاده کنید تا کد خواناتر شود.
✅ از حروف بزرگ برای متغیرهای سراسری و حروف کوچک برای متغیرهای محلی استفاده کنید.

📌 مثال صحیح:

USERNAME="Ali"
SCRIPT_DIR="/home/user/scripts"

📌 مثال غلط:

a="Ali"
b="/home/user/scripts"

۳. افزودن توضیحات (کامنت‌گذاری صحیح)

✅ توضیحات واضحی برای بخش‌های مهم اسکریپت بنویسید.
✅ برای هر خط نیازی به کامنت نیست؛ فقط بخش‌های پیچیده را توضیح دهید.

📌 مثال:

#!/bin/bash

# این اسکریپت نام کاربر را دریافت و نمایش می‌دهد
echo "لطفاً نام خود را وارد کنید:"
read USERNAME
echo "سلام، $USERNAME!"

۴. رعایت قالب‌بندی مناسب (Indentation و Spacing)

✅ از فاصله‌گذاری مناسب برای افزایش خوانایی استفاده کنید.
✅ از تورفتگی (Indentation) مناسب برای بلاک‌های if, for, while و غیره استفاده کنید.

📌 مثال خوانا:

if [ "$USER" == "root" ]; then
    echo "شما کاربر ریشه هستید."
else
    echo "شما کاربر عادی هستید."
fi

📌 مثال نامناسب (کد فشرده و ناخوانا):

if [ "$USER" == "root" ]; then echo "شما کاربر ریشه هستید."; else echo "شما کاربر عادی هستید."; fi

۵. مدیریت خطاها و بررسی وضعیت اجرای دستورات

✅ همواره خروجی دستورات را بررسی کنید تا در صورت بروز خطا، رفتار مناسب داشته باشید.

📌 بررسی موفقیت یک دستور:

mkdir /tmp/test_directory
if [ $? -eq 0 ]; then
    echo "دایرکتوری با موفقیت ایجاد شد."
else
    echo "خطا در ایجاد دایرکتوری!"
fi

📌 روش کوتاه‌تر برای بررسی خطا:

mkdir /tmp/test_directory || echo "خطا در ایجاد دایرکتوری!"

📌 جلوگیری از توقف اسکریپت هنگام خطا:

set -e  # توقف اجرای اسکریپت در صورت وقوع خطا
set -u  # توقف اجرای اسکریپت در صورت استفاده از متغیر تعریف‌نشده

۶. استفاده از توابع برای جلوگیری از تکرار کد

✅ اگر بخشی از کد چندین بار استفاده می‌شود، آن را در یک تابع قرار دهید.
✅ این کار باعث افزایش خوانایی و کاهش خطاها می‌شود.

📌 مثال:

#!/bin/bash

# تعریف تابع نمایش پیام خوش‌آمدگویی
greet_user() {
    echo "سلام، $1! خوش آمدید."
}

# فراخوانی تابع با ورودی کاربر
greet_user "علی"
greet_user "رضا"

۷. استفاده از آرگومان‌های خط فرمان

✅ اسکریپت‌ها باید بتوانند ورودی‌ها را از خط فرمان دریافت کنند.
✅ از $1, $2, … برای دریافت آرگومان‌ها استفاده کنید.

📌 مثال:

#!/bin/bash

echo "نام شما: $1"
echo "سن شما: $2"

📌 اجرا:

./script.sh علی 25

📌 خروجی:

نام شما: علی
سن شما: 25

۸. استفاده از متغیرهای محیطی برای پایداری بیشتر

✅ بجای مقداردهی مستقیم، از متغیرهای محیطی استفاده کنید.
✅ بررسی کنید که متغیر مقدار داشته باشد، در غیر این صورت مقدار پیش‌فرض تعیین کنید.

📌 مثال:

USERNAME=${USERNAME:-"مهمان"}
echo "سلام، $USERNAME!"

۹. بهینه‌سازی حلقه‌ها و شرط‌ها

✅ از ساختارهای شرطی و حلقه‌ها بهینه استفاده کنید تا سرعت اسکریپت افزایش یابد.

📌 حلقه for:

for FILE in /home/user/*.txt; do
    echo "فایل: $FILE"
done

📌 حلقه while:

COUNT=1
while [ $COUNT -le 5 ]; do
    echo "عدد: $COUNT"
    ((COUNT++))
done

۱۰. مدیریت خروجی و لاگ‌گذاری

✅ اطلاعات مهم را در یک فایل لاگ ذخیره کنید تا بررسی آن‌ها در آینده راحت باشد.

📌 مثال:

LOG_FILE="/var/log/myscript.log"

echo "اجرای اسکریپت در $(date)" >> "$LOG_FILE"

جمع‌بندی

Shebang صحیح مشخص می‌کند که اسکریپت توسط چه شلی اجرا شود.
نام‌گذاری مناسب متغیرها خوانایی کد را افزایش می‌دهد.
کامنت‌گذاری صحیح باعث درک بهتر کد می‌شود.
قالب‌بندی مناسب کد را خواناتر می‌کند.
مدیریت خطاها از توقف ناگهانی اسکریپت جلوگیری می‌کند.
استفاده از توابع کد را ماژولارتر و خواناتر می‌کند.
مدیریت آرگومان‌ها ورودی‌های اسکریپت را انعطاف‌پذیرتر می‌کند.
بهینه‌سازی حلقه‌ها و شرط‌ها باعث افزایش کارایی می‌شود.
لاگ‌گذاری مناسب کمک می‌کند تا اجرای اسکریپت قابل ردیابی باشد.

با رعایت این نکات، اسکریپت‌های شل شما خواناتر، بهینه‌تر و کاربردی‌تر خواهند شد.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش 2. نحوه نوشتن اسکریپت‌های شل”][cdb_course_lesson title=”فصل 1. مقدمه‌ای بر اسکریپت‌نویسی شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تعریف اسکریپت شل و کاربردهای آن” subtitle=”توضیحات کامل”]اسکریپت شل (Shell Script) مجموعه‌ای از دستورات است که در یک فایل ذخیره شده و توسط شل سیستم‌عامل اجرا می‌شود. این اسکریپت‌ها به کاربران و مدیران سیستم اجازه می‌دهند تا وظایف تکراری را خودکار کنند، سیستم را مدیریت کنند، پردازش‌های پیچیده را ساده‌سازی کنند و تعامل بهتری با سیستم داشته باشند.

در این بخش، ابتدا تعریف دقیق اسکریپت شل را بررسی کرده، سپس به کاربردهای اصلی آن پرداخته و مثال‌های عملی ارائه خواهیم داد.


تعریف اسکریپت شل

یک اسکریپت شل شامل مجموعه‌ای از دستورات شل است که به ترتیب نوشته شده و توسط شل (Bash، Zsh، Ksh و …) اجرا می‌شود. این اسکریپت‌ها معمولاً دارای پسوند .sh هستند و می‌توانند عملیات مختلفی را به‌صورت خودکار انجام دهند.

🔹 ویژگی‌های اسکریپت شل:
✅ شامل دستورات خط فرمان (CLI) است.
✅ امکان اجرای خودکار وظایف را فراهم می‌کند.
✅ می‌تواند شامل ساختارهای شرطی (if)، حلقه‌ها (for, while)، توابع و متغیرها باشد.
✅ قابلیت تعامل با کاربران از طریق ورودی و خروجی دارد.
✅ به مدیران سیستم و توسعه‌دهندگان کمک می‌کند که مدیریت و نظارت بهتری بر سیستم داشته باشند.

📌 نمونه یک اسکریپت ساده:

#!/bin/bash
echo "سلام! این یک اسکریپت شل ساده است."

📌 نحوه اجرای اسکریپت:

chmod +x script.sh  # اعطای مجوز اجرایی
./script.sh         # اجرای اسکریپت

کاربردهای اسکریپت شل

اسکریپت‌های شل در مدیریت سیستم، خودکارسازی وظایف، پردازش داده‌ها، تعامل با کاربران و بسیاری از موارد دیگر استفاده می‌شوند. در ادامه، مهم‌ترین کاربردهای آن را بررسی می‌کنیم.


۱. اتوماسیون وظایف تکراری

✅ یکی از مهم‌ترین کاربردهای اسکریپت شل، خودکارسازی وظایف روزمره و تکراری است.
✅ این امر باعث صرفه‌جویی در زمان، کاهش خطای انسانی و افزایش بهره‌وری می‌شود.

📌 مثال: پشتیبان‌گیری خودکار از فایل‌ها

#!/bin/bash

SOURCE_DIR="/home/user/Documents"
BACKUP_DIR="/home/user/Backup"
DATE=$(date +%Y-%m-%d)

# ایجاد دایرکتوری بکاپ اگر وجود ندارد
mkdir -p "$BACKUP_DIR"

# کپی کردن فایل‌ها
cp -r "$SOURCE_DIR" "$BACKUP_DIR/backup-$DATE"

echo "پشتیبان‌گیری انجام شد!"

📌 اجرای اسکریپت در زمان‌بندی مشخص:
برای اجرای خودکار این اسکریپت می‌توان از کرون‌جاب (Cron Job) استفاده کرد:

crontab -e

افزودن خط زیر برای اجرای اسکریپت هر روز در ساعت ۲ بامداد:

0 2 * * * /home/user/backup_script.sh

۲. مدیریت و نظارت بر سیستم

مدیران سیستم (SysAdmins) از اسکریپت‌های شل برای مدیریت سرویس‌ها، بررسی وضعیت سیستم و اجرای وظایف خودکار استفاده می‌کنند.

📌 مثال: بررسی میزان فضای دیسک و ارسال هشدار در صورت کمبود فضا

#!/bin/bash

THRESHOLD=80  # حد آستانه فضای دیسک (٪)
USAGE=$(df / | grep / | awk '{print $5}' | sed 's/%//g')

if [ "$USAGE" -ge "$THRESHOLD" ]; then
    echo "هشدار: فضای دیسک پر شده است! میزان استفاده: $USAGE٪"
    # ارسال هشدار ایمیلی
    echo "فضای دیسک بیش از حد مجاز است!" | mail -s "Disk Alert" admin@example.com
fi

📌 اجرای خودکار این اسکریپت هر ساعت از طریق Cron:

0 * * * * /home/user/check_disk.sh

۳. پردازش و تحلیل داده‌ها

پردازش فایل‌های لاگ، تجزیه‌وتحلیل اطلاعات و استخراج داده‌ها از دیگر کاربردهای اسکریپت شل است.

📌 مثال: شمارش تعداد درخواست‌های یک سرور وب از فایل لاگ

#!/bin/bash

LOG_FILE="/var/log/nginx/access.log"

echo "تعداد درخواست‌ها در ۲۴ ساعت گذشته:"
grep "$(date --date='yesterday' +%Y-%m-%d)" "$LOG_FILE" | wc -l

۴. اجرای دستورات در چندین سرور (مدیریت سرورهای راه دور)

مدیران سیستم گاهی نیاز دارند دستورات را در چندین سرور اجرا کنند.
✅ می‌توان از SSH و اسکریپت شل برای اجرای همزمان دستورات در چندین سرور استفاده کرد.

📌 مثال: بررسی وضعیت یک سرویس در چندین سرور

#!/bin/bash

SERVERS=("192.168.1.10" "192.168.1.11" "192.168.1.12")

for SERVER in "${SERVERS[@]}"; do
    echo "بررسی سرویس در سرور: $SERVER"
    ssh user@$SERVER "systemctl status apache2"
done

۵. تعامل با کاربران از طریق ورودی و خروجی

اسکریپت‌های شل می‌توانند از کاربران ورودی دریافت کرده و براساس آن عمل کنند.

📌 مثال: دریافت نام کاربر و نمایش پیام خوش‌آمدگویی

#!/bin/bash

echo "لطفاً نام خود را وارد کنید:"
read USERNAME
echo "سلام، $USERNAME! خوش آمدید."

📌 اجرای اسکریپت و دریافت ورودی از کاربر:

لطفاً نام خود را وارد کنید:
علی
سلام، علی! خوش آمدید.

جمع‌بندی

اسکریپت شل مجموعه‌ای از دستورات است که در یک فایل ذخیره شده و توسط شل اجرا می‌شود.
اتوماسیون وظایف تکراری، مدیریت سیستم، پردازش داده‌ها و تعامل با کاربران از کاربردهای اصلی آن هستند.
با استفاده از کرون‌جاب می‌توان اسکریپت‌ها را زمان‌بندی کرد.
مدیران سیستم می‌توانند از اسکریپت شل برای بررسی سرورها و نظارت بر سرویس‌ها استفاده کنند.
امکان اجرای اسکریپت در چندین سرور و پردازش فایل‌های لاگ از دیگر کاربردهای آن است.
اسکریپت‌ها می‌توانند ورودی از کاربران دریافت کرده و براساس آن عملیات خاصی انجام دهند.

با یادگیری اسکریپت‌نویسی شل، می‌توان فرایندهای دستی و وقت‌گیر را خودکار کرد و بهره‌وری را افزایش داد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تفاوت بین دستورات ساده و اسکریپت‌های چندخطی” subtitle=”توضیحات کامل”]در شل لینوکس، می‌توان دستورات ساده را مستقیماً در خط فرمان اجرا کرد یا آن‌ها را در قالب یک اسکریپت چندخطی ذخیره و اجرا نمود. در این بخش، تفاوت بین این دو روش را بررسی خواهیم کرد و نشان می‌دهیم که چگونه اسکریپت‌های چندخطی به مدیریت و اجرای بهتر وظایف کمک می‌کنند.


دستورات ساده در خط فرمان (One-Liner Commands)

✅ دستورات ساده، همان دستورات تکی هستند که مستقیماً در ترمینال اجرا می‌شوند و نتیجه‌ی آن‌ها بلافاصله نمایش داده می‌شود.

📌 مثال ۱: نمایش فهرست فایل‌ها در دایرکتوری جاری

ls -l

📌 مثال ۲: نمایش تاریخ و زمان جاری

date

📌 مثال ۳: ایجاد یک فایل جدید و اضافه کردن محتوا به آن

echo "Hello, World!" > myfile.txt

این دستورات بدون نیاز به ذخیره در فایل اجرا می‌شوند و مناسب کارهای سریع و لحظه‌ای هستند.


اسکریپت‌های چندخطی (Multi-Line Scripts)

✅ وقتی چندین دستور باید به‌ترتیب اجرا شوند یا نیاز به شرایط، حلقه و پردازش داده‌ها داریم، از اسکریپت‌های چندخطی استفاده می‌کنیم.
✅ این اسکریپت‌ها در یک فایل ذخیره شده و بارها قابل اجرا هستند، برخلاف دستورات ساده که فقط یک‌بار اجرا می‌شوند.

📌 مثال ۱: اسکریپت چندخطی برای نمایش اطلاعات سیستم
محتوای فایل system-info.sh:

#!/bin/bash
echo "نام کاربر فعلی: $(whoami)"
echo "تاریخ و زمان: $(date)"
echo "فضای دیسک موجود:"
df -h

📌 اجرای اسکریپت:

bash system-info.sh

📌 نتیجه‌ی اجرا:

نام کاربر فعلی: ali
تاریخ و زمان: Wed Feb 21 14:30:00 UTC 2025
فضای دیسک موجود:
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       50G   20G   30G  40% /

مقایسه دستورات ساده و اسکریپت‌های چندخطی

ویژگی دستورات ساده (One-Liner) اسکریپت‌های چندخطی
اجرای سریع ✅ بله ❌ خیر (نیاز به ذخیره و اجرا)
مناسب وظایف پیچیده ❌ خیر ✅ بله
قابلیت استفاده مجدد ❌ خیر ✅ بله
خوانایی و مدیریت بهتر ❌ خیر ✅ بله
امکان استفاده از حلقه و شرط ❌ خیر ✅ بله

جمع بندی

دستورات ساده برای کارهای سریع و لحظه‌ای در خط فرمان استفاده می‌شوند.
اسکریپت‌های چندخطی برای اجرای مجموعه‌ای از دستورات به‌صورت خودکار و منظم کاربرد دارند.
✅ اگر نیاز به اتوماسیون، تکرارپذیری، یا انجام عملیات پیچیده دارید، استفاده از اسکریپت شل بهترین گزینه است.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. ایجاد فایل اسکریپت”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”نحوه ایجاد فایل اسکریپت با استفاده از دستور touch یا سایر ابزارها” subtitle=”توضیحات کامل”]برای ایجاد یک فایل اسکریپت در لینوکس، می‌توان از چندین روش مختلف استفاده کرد. در این بخش، نحوه ایجاد یک اسکریپت با دستور touch و سایر ویرایشگرهای متنی مانند nano، vim و echo را بررسی می‌کنیم.


ایجاد فایل اسکریپت با touch

دستور touch برای ایجاد یک فایل خالی استفاده می‌شود. این روش فقط فایل را ایجاد می‌کند و برای اضافه کردن کد به اسکریپت باید از یک ویرایشگر متنی استفاده کنیم.

📌 ایجاد یک اسکریپت جدید به نام myscript.sh

touch myscript.sh

📌 بررسی ایجاد شدن فایل:

ls -l myscript.sh

📌 نتیجه:

-rw-r--r-- 1 user user 0 Feb 21 15:00 myscript.sh

🔹 این فایل هنوز قابل اجرا نیست و باید مجوز اجرایی به آن داده شود.


ایجاد فایل اسکریپت و ویرایش همزمان با nano

ویرایشگر nano یک روش ساده برای ایجاد و ویرایش فایل‌های اسکریپت است.

📌 ایجاد و باز کردن یک اسکریپت جدید با nano

nano myscript.sh

📌 اضافه کردن محتوای اسکریپت در nano

#!/bin/bash
echo "Hello, this is my first script!"

📌 ذخیره و خروج از nano
۱. Ctrl + X (خروج)
۲. Y (برای تأیید ذخیره تغییرات)
۳. Enter (برای ذخیره فایل با همان نام)


ایجاد و ویرایش فایل اسکریپت با vim

✅ برای کسانی که به ویرایشگر vim مسلط هستند، می‌توان فایل را مستقیماً با این ابزار ایجاد و ویرایش کرد.

📌 ایجاد و باز کردن فایل:

vim myscript.sh

📌 ورود به حالت ویرایش (با فشردن i) و اضافه کردن کد:

#!/bin/bash
echo "This script is created using Vim."

📌 ذخیره و خروج:
۱. Esc (خروج از حالت ویرایش)
۲. :wq (ذخیره و خروج) و سپس Enter


ایجاد فایل اسکریپت با echo

اگر بخواهید بدون نیاز به ویرایشگر، یک اسکریپت ایجاد کنید، می‌توانید از echo و > استفاده کنید.

📌 ایجاد فایل و نوشتن محتوا در آن:

echo '#!/bin/bash' > myscript.sh
echo 'echo "Hello from my script!"' >> myscript.sh

📌 بررسی محتویات فایل:

cat myscript.sh

📌 نتیجه:

#!/bin/bash
echo "Hello from my script!"

اعطای مجوز اجرایی به فایل اسکریپت

✅ بعد از ایجاد اسکریپت، باید مجوز اجرایی به آن بدهیم تا قابل اجرا باشد.

📌 اعطای مجوز اجرایی به myscript.sh

chmod +x myscript.sh

📌 اجرای اسکریپت:

./myscript.sh

📌 خروجی:

Hello from my script!

جمع بندی

✅ برای ایجاد یک فایل اسکریپت می‌توان از روش‌های مختلفی استفاده کرد:

  • touch → فقط فایل را ایجاد می‌کند، برای ویرایش نیاز به ابزار دیگری دارد.
  • nano → ویرایشگر ساده و کاربردی برای اسکریپت‌نویسی.
  • vim → مناسب کاربران حرفه‌ای که با vim کار می‌کنند.
  • echo → ایجاد سریع فایل همراه با محتوا بدون نیاز به ویرایشگر.

✅ پس از ایجاد اسکریپت، باید مجوز اجرایی (chmod +x) به آن داده شود.
✅ اسکریپت را می‌توان با ./script.sh یا bash script.sh اجرا کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”استفاده از ویرایشگرهای متنی (مانند vim، nano، gedit) برای ویرایش فایل‌ها” subtitle=”توضیحات کامل”]در محیط لینوکس، برای ویرایش فایل‌های متنی و اسکریپت‌ها، ابزارهای متعددی در دسترس هستند. از میان آن‌ها، vim، nano و gedit محبوب‌ترین ویرایشگرها هستند که هرکدام مزایا و معایب خاص خود را دارند. در این بخش، نحوه استفاده از این ویرایشگرها برای ویرایش فایل‌های اسکریپت را بررسی می‌کنیم.


ویرایش فایل‌ها با nano

nano یک ویرایشگر ساده و کاربرپسند است که برای کاربران مبتدی و پیشرفته مناسب است. این ویرایشگر در تمامی توزیع‌های لینوکس به‌صورت پیش‌فرض وجود دارد.

📌 ایجاد و باز کردن یک فایل با nano

nano myscript.sh

📌 ویرایش متن در nano
بعد از باز شدن فایل، می‌توان کدهای زیر را در آن نوشت:

#!/bin/bash
echo "Hello from nano!"

📌 دستورات کاربردی در nano

دستور عملکرد
Ctrl + X خروج از ویرایشگر
Y + Enter ذخیره تغییرات و خروج
Ctrl + K حذف خط جاری
Ctrl + U جای‌گذاری متن کپی‌شده
Ctrl + W جستجو در متن

📌 خروج و ذخیره تغییرات در nano
۱. Ctrl + X (خروج)
۲. Y (تأیید ذخیره تغییرات)
۳. Enter (ذخیره با همان نام)


ویرایش فایل‌ها با vim

vim یک ویرایشگر قدرتمند و پیشرفته برای کاربران حرفه‌ای است. این ویرایشگر دارای حالت‌های مختلف مانند حالت ویرایش (Insert) و حالت فرمان (Command) است.

📌 باز کردن یک فایل با vim

vim myscript.sh

📌 ورود به حالت ویرایش و نوشتن متن در vim
۱. فشردن i (برای ورود به حالت ویرایش)
۲. نوشتن کد موردنظر

#!/bin/bash
echo "Hello from vim!"

۳. خروج از حالت ویرایش (Esc)
۴. ذخیره و خروج (:wq + Enter)

📌 دستورات کاربردی در vim

دستور عملکرد
i ورود به حالت ویرایش
Esc خروج از حالت ویرایش
:wq ذخیره و خروج
:q! خروج بدون ذخیره
dd حذف یک خط
u بازگردانی تغییرات (Undo)

📌 خروج و ذخیره تغییرات در vim
۱. فشردن Esc برای خروج از حالت ویرایش
2. نوشتن :wq و زدن Enter


ویرایش فایل‌ها با gedit

gedit یک ویرایشگر گرافیکی برای محیط GNOME است که برای کاربران دسکتاپ مناسب و کاربرپسند است.

📌 باز کردن فایل با gedit

gedit myscript.sh

📌 نوشتن کد در gedit

#!/bin/bash
echo "Hello from gedit!"

📌 ذخیره و خروج از gedit
۱. Ctrl + S (ذخیره تغییرات)
۲. Ctrl + Q (خروج از ویرایشگر)


مقایسه vim، nano و gedit

ویژگی‌ها nano vim gedit
رابط کاربری متنی و ساده متنی و حرفه‌ای گرافیکی و کاربرپسند
سطح کاربری مبتدی تا متوسط پیشرفته مبتدی تا متوسط
امکان جستجو ✅ دارد ✅ دارد ✅ دارد
پشتیبانی از Syntax Highlighting ❌ ندارد ✅ دارد ✅ دارد
امکان استفاده در ترمینال ✅ بله ✅ بله ❌ خیر
قابلیت Undo/Redo ✅ دارد ✅ دارد ✅ دارد
مناسب برای محیط سرور ✅ بله ✅ بله ❌ خیر

جمع‌بندی

nano ساده‌ترین ویرایشگر متنی برای کاربران مبتدی است.
vim یک ابزار حرفه‌ای و قدرتمند برای کاربران پیشرفته محسوب می‌شود.
gedit گزینه‌ای مناسب برای کاربران دسکتاپ و کسانی است که محیط گرافیکی را ترجیح می‌دهند.
✅ برای کار با سرور و سیستم‌های بدون رابط گرافیکی، nano و vim بهترین انتخاب‌ها هستند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. استفاده از Shebang (#!/bin/bash)”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”توضیح مفهوم Shebang و کاربرد آن” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، Shebang یکی از مهم‌ترین مفاهیمی است که باید به آن توجه داشت. این ویژگی به سیستم‌عامل کمک می‌کند تا بفهمد که اسکریپت باید با کدام مفسر اجرا شود.


Shebang چیست؟

Shebang یک خط ویژه در ابتدای فایل اسکریپت است که مشخص می‌کند اسکریپت باید با کدام مفسر اجرا شود. این خط با علامت #! شروع شده و مسیر مفسر موردنظر را مشخص می‌کند.

📌 ساختار کلی Shebang:

#!/path/to/interpreter

📌 مثال رایج برای اسکریپت‌های Bash:

#!/bin/bash
echo "Hello, World!"

در این مثال، #!/bin/bash مشخص می‌کند که این اسکریپت باید با Bash اجرا شود.


چرا Shebang مهم است؟

مشخص کردن مفسر: سیستم می‌فهمد که اسکریپت باید با چه برنامه‌ای اجرا شود.
کاهش خطاهای اجرا: اگر shebang نباشد، ممکن است سیستم مفسر نادرستی را برای اجرای اسکریپت انتخاب کند.
افزایش سازگاری: با استفاده از #!/usr/bin/env bash می‌توان اسکریپت را طوری نوشت که روی سیستم‌های مختلف کار کند.


روش‌های مختلف نوشتن Shebang

۱️⃣ استفاده از مسیر مستقیم مفسر (روش استاندارد)

#!/bin/bash

📌 این روش زمانی کاربرد دارد که مطمئن هستیم مفسر در مسیر مشخص شده قرار دارد.

۲️⃣ استفاده از env برای یافتن مفسر (روش توصیه‌شده برای پرتابل بودن اسکریپت‌ها)

#!/usr/bin/env bash

📌 این روش انعطاف‌پذیرتر است و در صورتی که bash در مسیر دیگری نصب شده باشد، همچنان اجرا خواهد شد.

۳️⃣ استفاده از مفسرهای دیگر
Shebang می‌تواند برای سایر زبان‌های اسکریپت‌نویسی هم استفاده شود:

Python

#!/usr/bin/env python3
print("Hello, Python!")

Perl

#!/usr/bin/perl
print "Hello, Perl!\n";

Awk

#!/usr/bin/awk -f
BEGIN { print "Hello, Awk!" }

Sh (Shell عمومی)

#!/bin/sh
echo "Hello from sh"

📌 تفاوت sh و bash این است که sh در اکثر سیستم‌ها به نسخه‌ای از Shell استاندارد اشاره دارد، اما ممکن است همه قابلیت‌های bash را نداشته باشد.


نحوه بررسی و اجرای اسکریپتی که Shebang دارد

📌 ایجاد یک اسکریپت نمونه

nano myscript.sh

📌 افزودن محتوای زیر به فایل

#!/bin/bash
echo "این یک اسکریپت Bash است!"

📌 دادن مجوز اجرایی به اسکریپت

chmod +x myscript.sh

📌 اجرای اسکریپت

./myscript.sh

✅ اگر Shebang به‌درستی تنظیم شده باشد، اسکریپت بدون مشکل اجرا خواهد شد.


جمع‌بندی

Shebang (#!) در ابتدای اسکریپت مشخص می‌کند که کدام مفسر باید آن را اجرا کند.
✅ استفاده از #!/bin/bash یا #!/usr/bin/env bash بهترین روش برای اجرای اسکریپت‌های Bash است.
✅ Shebang در سایر زبان‌های اسکریپت‌نویسی مانند Python، Perl، Awk و Sh نیز استفاده می‌شود.
بدون Shebang، اجرای اسکریپت ممکن است دچار مشکل شود، به‌ویژه اگر از طریق ./script.sh اجرا شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”نحوه مشخص کردن مفسر (مانند Bash, Sh, یا Zsh) برای اجرای اسکریپت” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، مفسر (Interpreter) برنامه‌ای است که کدهای اسکریپت را پردازش و اجرا می‌کند. مشخص کردن مفسر مناسب برای اسکریپت از اهمیت بالایی برخوردار است، زیرا هر شل (Shell) دارای ویژگی‌ها، قابلیت‌ها و سینتکس خاص خود است.


روش‌های مشخص کردن مفسر برای اجرای اسکریپت

۱. استفاده از Shebang (#!) در ابتدای اسکریپت

Shebang (#!) مشخص می‌کند که اسکریپت باید با چه مفسری اجرا شود. این روش متداول‌ترین راه برای تعیین مفسر است.

📌 مثال برای اجرای اسکریپت با bash

#!/bin/bash
echo "این اسکریپت با Bash اجرا می‌شود."

📌 مثال برای اجرای اسکریپت با sh

#!/bin/sh
echo "این اسکریپت با Sh اجرا می‌شود."

📌 مثال برای اجرای اسکریپت با zsh

#!/bin/zsh
echo "این اسکریپت با Zsh اجرا می‌شود."

📌 مثال برای اجرای اسکریپت با dash

#!/bin/dash
echo "این اسکریپت با Dash اجرا می‌شود."

✅ در این روش، هنگام اجرای اسکریپت از طریق ./script.sh، سیستم به‌طور خودکار از مفسر مشخص‌شده در Shebang استفاده می‌کند.


۲. اجرای اسکریپت با تعیین مفسر هنگام اجرا

اگر اسکریپت شامل Shebang نباشد، یا بخواهید آن را با مفسر متفاوتی اجرا کنید، می‌توانید مستقیماً مفسر را مشخص کنید.

📌 اجرای اسکریپت با bash

bash script.sh

📌 اجرای اسکریپت با sh

sh script.sh

📌 اجرای اسکریپت با zsh

zsh script.sh

✅ در این روش، مفسری که در خط فرمان مشخص می‌شود، اجرای اسکریپت را بر عهده می‌گیرد و نیازی به Shebang در داخل اسکریپت نیست.


۳. استفاده از env برای یافتن مفسر در مسیر سیستم

در برخی سیستم‌ها، ممکن است مسیر دقیق مفسر مشخص نباشد. در این حالت، استفاده از env می‌تواند کمک کند تا مفسر مناسب از PATH سیستم پیدا شود.

📌 Shebang با env برای یافتن bash

#!/usr/bin/env bash
echo "این اسکریپت با Bash اجرا می‌شود."

📌 Shebang با env برای یافتن zsh

#!/usr/bin/env zsh
echo "این اسکریپت با Zsh اجرا می‌شود."

مزیت این روش این است که در هر سیستمی که مفسر در مسیر متفاوتی نصب شده باشد، بدون نیاز به تغییر اسکریپت، اجرا خواهد شد.


۴. بررسی نسخه و مسیر مفسر مورد استفاده

گاهی اوقات نیاز است که بررسی کنیم اسکریپت با چه مفسری اجرا می‌شود.

📌 بررسی مفسر جاری در اسکریپت

#!/bin/bash
echo "مفسر این اسکریپت: $0"

📌 بررسی نسخه مفسر

bash --version
zsh --version
sh --version

📌 یافتن مسیر مفسر در سیستم

which bash
which sh
which zsh

✅ این دستورات کمک می‌کنند تا مطمئن شویم که مسیر مفسر به‌درستی مشخص شده است.


جمع‌بندی

روش اصلی مشخص کردن مفسر، استفاده از Shebang (#!) در ابتدای اسکریپت است.
برای اجرای اسکریپت بدون نیاز به Shebang، می‌توان مفسر را مستقیماً در خط فرمان تعیین کرد.
استفاده از #!/usr/bin/env bash یک روش پرتابل‌تر برای یافتن مفسر در سیستم‌های مختلف است.
برای بررسی نسخه و مسیر مفسر، می‌توان از دستورات which, echo $0 و --version استفاده کرد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. نوشتن اولین اسکریپت ساده”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”ایجاد یک اسکریپت ساده برای چاپ متن با دستور echo” subtitle=”توضیحات کامل”]در این بخش، یک اسکریپت ساده شل می‌نویسیم که یک پیام را روی صفحه نمایش چاپ کند. این اولین گام برای یادگیری اسکریپت‌نویسی در لینوکس است.


۱. ایجاد فایل اسکریپت

ابتدا باید یک فایل جدید ایجاد کنیم. می‌توان از touch یا یک ویرایشگر متن برای این کار استفاده کرد.

📌 ایجاد فایل اسکریپت با touch

touch myscript.sh

📌 یا ایجاد و باز کردن فایل با nano

nano myscript.sh

۲. نوشتن اسکریپت

حالا داخل فایل myscript.sh، کد زیر را اضافه می‌کنیم:

#!/bin/bash

# چاپ یک پیام ساده
echo "سلام، این اولین اسکریپت Bash من است!"

توضیحات کد:

  • #!/bin/bash → مشخص می‌کند که این اسکریپت باید با Bash اجرا شود.
  • echo → متن را روی صفحه نمایش چاپ می‌کند.

۳. اعطای مجوز اجرایی به اسکریپت

قبل از اجرا، باید به اسکریپت مجوز اجرا بدهیم:

chmod +x myscript.sh

۴. اجرای اسکریپت

پس از تنظیم مجوز، می‌توانیم اسکریپت را به یکی از روش‌های زیر اجرا کنیم:

📌 اجرای مستقیم با ./

./myscript.sh

📌 یا اجرای آن با Bash

bash myscript.sh

جمع‌بندی

✅ یک اسکریپت ساده ایجاد کردیم که با دستور echo یک پیام چاپ می‌کند.
✅ از chmod +x برای دادن مجوز اجرایی استفاده کردیم.
✅ اسکریپت را با ./script.sh یا bash script.sh اجرا کردیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”اجرای اسکریپت با استفاده از دستور bash scriptname.sh یا ./scriptname.sh” subtitle=”توضیحات کامل”]برای اجرای یک اسکریپت شل در لینوکس، روش‌های مختلفی وجود دارد. در این بخش، دو روش پرکاربرد را بررسی می‌کنیم:

  1. اجرای اسکریپت با bash scriptname.sh
  2. اجرای اسکریپت به‌صورت مستقیم با ./scriptname.sh

۱. ایجاد یک اسکریپت نمونه

ابتدا یک اسکریپت ساده ایجاد می‌کنیم که یک پیام را روی صفحه نمایش چاپ کند.

📌 ایجاد فایل اسکریپت

nano myscript.sh

📌 افزودن محتوای اسکریپت:

#!/bin/bash

echo "این یک اسکریپت نمونه است."

📌 ذخیره و خروج در nano
برای ذخیره: CTRL + X سپس Y و Enter


۲. اجرای اسکریپت با دستور bash scriptname.sh

در این روش، بدون نیاز به دادن مجوز اجرایی، اسکریپت مستقیماً توسط Bash اجرا می‌شود:

bash myscript.sh

مزیت این روش:

  • نیازی به اعطای مجوز اجرایی (chmod +x) نیست.
  • مفید برای اجرای اسکریپتی که نیاز به اجرای یک‌باره دارد.

۳. اجرای اسکریپت به‌صورت مستقیم (./scriptname.sh)

برای این روش، ابتدا باید مجوز اجرایی به اسکریپت بدهیم:

📌 دادن مجوز اجرایی

chmod +x myscript.sh

📌 اجرای اسکریپت به‌صورت مستقیم

./myscript.sh

مزیت این روش:

  • می‌توان اسکریپت را بدون نیاز به تایپ bash مستقیماً اجرا کرد.
  • مناسب برای اسکریپت‌هایی که قرار است به‌صورت مداوم اجرا شوند.

۴. تفاوت بین دو روش

روش اجرا نیاز به مجوز اجرایی؟ نحوه اجرا
bash scriptname.sh ❌ نیاز ندارد اجرا از طریق bash
./scriptname.sh ✅ نیاز دارد (chmod +x) اجرا به‌صورت مستقل

جمع‌بندی

✅ دو روش اجرای اسکریپت را بررسی کردیم:

  1. bash script.sh (بدون نیاز به مجوز اجرایی)
  2. ./script.sh (نیاز به chmod +x)

✅ بسته به نیاز، می‌توان از یکی از این دو روش برای اجرای اسکریپت استفاده کرد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. مجوزهای اجرایی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”توضیح مفهوم مجوزهای اجرایی در لینوکس” subtitle=”توضیحات کامل”]در سیستم‌عامل لینوکس، مجوزهای دسترسی به فایل‌ها نقش مهمی در امنیت و کنترل دسترسی کاربران دارند. یکی از مهم‌ترین مجوزها، مجوز اجرایی (execute permission) است که به یک فایل اجازه می‌دهد به‌عنوان یک برنامه یا اسکریپت اجرا شود.


۱. بررسی مجوزهای فایل در لینوکس

برای مشاهده مجوزهای یک فایل از دستور ls -l استفاده می‌کنیم:

ls -l myscript.sh

📌 مثال خروجی:

-rw-r--r-- 1 user user 42 Feb 21 12:00 myscript.sh

آنالیز خروجی:

  • بخش اول (-rw-r--r--) نشان‌دهنده مجوزهای فایل است.
  • ۱۰ کاراکتر اول نشان‌دهنده نوع فایل و مجوزهای آن است:
    • - (اولین کاراکتر) نشان‌دهنده فایل معمولی است.
    • rw- → مجوز خواندن و نوشتن برای مالک (User)
    • r-- → مجوز خواندن برای گروه (Group)
    • r-- → مجوز خواندن برای دیگر کاربران (Others)
  • این فایل مجوز اجرایی ندارد و نمی‌توان آن را مستقیماً اجرا کرد.

۲. اعطای مجوز اجرایی به یک اسکریپت

برای اینکه یک اسکریپت بتواند اجرا شود، باید مجوز اجرایی داشته باشد. این کار را می‌توان با دستور chmod +x انجام داد:

chmod +x myscript.sh

اکنون اگر دوباره ls -l را اجرا کنیم:

ls -l myscript.sh

📌 خروجی جدید:

-rwxr-xr-x 1 user user 42 Feb 21 12:05 myscript.sh

تغییرات:

  • x به فایل اضافه شده است: -rwxr-xr-x
  • اکنون فایل قابلیت اجرا دارد.

۳. اجرای فایل پس از اعطای مجوز اجرایی

پس از اعمال مجوز اجرایی، می‌توان فایل را مستقیماً اجرا کرد:

./myscript.sh

۴. انواع مجوزها در لینوکس

مجوزهای دسترسی به فایل در لینوکس به سه بخش تقسیم می‌شوند:

نماد مفهوم توضیح
r Read امکان خواندن محتویات فایل
w Write امکان ویرایش و تغییر فایل
x Execute امکان اجرای فایل

مجوزها برای سه دسته از کاربران تنظیم می‌شوند:

  1. مالک فایل (User – u)
  2. اعضای گروه فایل (Group – g)
  3. دیگر کاربران (Others – o)

۵. تغییر دستی مجوزها با chmod

برای تغییر مجوزها به‌صورت دستی می‌توان از chmod استفاده کرد:

📌 اعطای مجوز اجرایی فقط به مالک فایل:

chmod u+x myscript.sh

📌 اعطای مجوز اجرایی به همه کاربران:

chmod a+x myscript.sh

📌 حذف مجوز اجرایی از همه کاربران:

chmod -x myscript.sh

۶. تغییر مجوزها با استفاده از مقدار عددی (Octal Mode)

در لینوکس می‌توان مجوزها را با اعداد هشت‌هشتی (Octal) نیز تنظیم کرد:

مقدار مجوز معادل
7 rwx (خواندن، نوشتن، اجرا)
6 rw- (خواندن، نوشتن)
5 r-x (خواندن، اجرا)
4 r-- (فقط خواندن)
0 --- (بدون دسترسی)

📌 مثال:
دادن مجوز rwx به مالک، r-x به گروه و r-x به دیگر کاربران:

chmod 755 myscript.sh

📌 خروجی:

-rwxr-xr-x 1 user user 42 Feb 21 12:10 myscript.sh

جمع‌بندی

مجوزهای اجرایی در لینوکس برای تعیین دسترسی به فایل‌ها ضروری هستند.
✅ با دستور ls -l می‌توان مجوزهای فعلی را مشاهده کرد.
✅ برای اجرای یک اسکریپت، باید مجوز x را به آن اضافه کنیم (chmod +x).
✅ می‌توان از روش نمادی (chmod u+x) یا روش عددی (chmod 755) برای تغییر مجوزها استفاده کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”استفاده از دستور chmod +x scriptname.sh برای فعال‌سازی قابلیت اجرا” subtitle=”توضیحات کامل”]در لینوکس، فایل‌های اسکریپت (مانند script.sh) به‌صورت پیش‌فرض دارای مجوز اجرایی نیستند. این بدان معناست که حتی اگر اسکریپت حاوی کد صحیح باشد، بدون اعطای مجوز اجرایی امکان اجرای مستقیم آن وجود ندارد. برای فعال‌سازی قابلیت اجرا، از دستور chmod +x استفاده می‌شود.


۱. بررسی وضعیت مجوزهای فایل

قبل از هر چیز، می‌توان بررسی کرد که آیا یک فایل اسکریپت دارای مجوز اجرایی است یا خیر. برای این کار از دستور زیر استفاده می‌شود:

ls -l scriptname.sh

📌 خروجی نمونه:

-rw-r--r-- 1 user user 42 Feb 21 12:00 scriptname.sh
  • مقدار -rw-r--r-- نشان می‌دهد که این فایل فقط قابلیت خواندن (r) و نوشتن (w) برای مالک و خواندن برای سایر کاربران را دارد.
  • مجوز اجرایی (x) در اینجا وجود ندارد.

۲. اعطای مجوز اجرایی به اسکریپت با chmod +x

برای اضافه کردن مجوز اجرا به این اسکریپت، از دستور زیر استفاده کنید:

chmod +x scriptname.sh

اکنون، اگر مجدداً مجوزهای فایل را بررسی کنیم:

ls -l scriptname.sh

📌 خروجی جدید:

-rwxr-xr-x 1 user user 42 Feb 21 12:05 scriptname.sh

تفاوت اصلی:

  • مقدار x (اجرا) به فایل اضافه شده است (-rwxr-xr-x).
  • اکنون فایل می‌تواند اجرا شود.

۳. اجرای اسکریپت پس از اعطای مجوز اجرایی

پس از تنظیم مجوز اجرایی، دو روش برای اجرای اسکریپت وجود دارد:

روش ۱: اجرای مستقیم از مسیر فعلی

./scriptname.sh

روش ۲: اجرای اسکریپت از طریق مفسر bash

bash scriptname.sh

۴. بررسی سطح دسترسی‌ها پس از تغییر مجوز

با دستور ls -l، سطح دسترسی‌ها به‌صورت زیر نمایش داده می‌شود:

-rwxr-xr-x 1 user user 42 Feb 21 12:05 scriptname.sh

🔹 rwx برای مالک: امکان خواندن (r)، نوشتن (w)، و اجرا (x)
🔹 r-x برای گروه و دیگر کاربران: امکان خواندن (r) و اجرا (x) ولی بدون قابلیت نوشتن

اگر بخواهیم تنها به مالک دسترسی اجرا بدهیم، از دستور زیر استفاده می‌کنیم:

chmod u+x scriptname.sh

و اگر بخواهیم همه کاربران بتوانند اسکریپت را اجرا کنند:

chmod a+x scriptname.sh

۵. حذف مجوز اجرایی از اسکریپت

برای حذف مجوز اجرای یک اسکریپت از تمام کاربران:

chmod -x scriptname.sh

📌 بررسی مجوزها پس از حذف:

ls -l scriptname.sh

🔸 خروجی:

-rw-r--r-- 1 user user 42 Feb 21 12:10 scriptname.sh

فایل دیگر قابلیت اجرا ندارد و فقط خواندنی است.


جمع‌بندی

✅ فایل‌های اسکریپت برای اجرا نیاز به مجوز اجرایی دارند.
✅ دستور chmod +x scriptname.sh قابلیت اجرا را فعال می‌کند.
✅ می‌توان با ls -l سطح دسترسی‌ها را بررسی کرد.
✅ برای اجرای اسکریپت، از ./scriptname.sh یا bash scriptname.sh استفاده می‌شود.
✅ می‌توان مجوزهای اجرا را برای کاربر خاص (chmod u+x) یا همه کاربران (chmod a+x) تنظیم کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی مجوزهای فایل با استفاده از دستور ls -l” subtitle=”توضیحات کامل”]در سیستم‌عامل‌های مبتنی بر لینوکس و یونیکس، هر فایل و دایرکتوری دارای مجموعه‌ای از مجوزهای دسترسی (Permissions) است که تعیین می‌کند چه کاربرانی اجازه خواندن (Read)، نوشتن (Write) و اجرای (Execute) آن را دارند.

برای بررسی سطح مجوزهای یک فایل یا دایرکتوری، از دستور ls -l استفاده می‌شود.


۱. بررسی مجوزهای فایل با ls -l

دستور زیر لیست فایل‌های موجود در دایرکتوری جاری را همراه با مجوزهای آن‌ها نمایش می‌دهد:

ls -l

📌 خروجی نمونه:

-rwxr-xr--  1 user group  1234 Feb 21 12:00 script.sh

۲. تحلیل خروجی دستور ls -l

خروجی این دستور شامل اطلاعات مختلفی درباره فایل است که در ادامه توضیح داده می‌شود:

-rwxr-xr--  1 user group  1234 Feb 21 12:00 script.sh

🔹 بخش اول (-rwxr-xr--): تعیین نوع فایل و مجوزهای آن
🔹 بخش دوم (1): تعداد لینک‌های سخت (Hard Links)
🔹 بخش سوم (user): نام کاربر مالک فایل
🔹 بخش چهارم (group): نام گروه مالک فایل
🔹 بخش پنجم (1234): اندازه فایل بر حسب بایت
🔹 بخش ششم (Feb 21 12:00): تاریخ و ساعت آخرین تغییر
🔹 بخش هفتم (script.sh): نام فایل


۳. درک ساختار مجوزهای فایل (-rwxr-xr--)

بخش اول خروجی که شامل ۱۰ کاراکتر است، از دو قسمت اصلی تشکیل شده است:
اولین کاراکتر نوع فایل را مشخص می‌کند:

  • - : فایل معمولی (Regular File)
  • d : دایرکتوری (Directory)
  • l : لینک نمادین (Symbolic Link)

نه کاراکتر بعدی شامل سه دسته مجوز برای مالک، گروه و سایر کاربران است:

rwx | r-x | r-- 

🔹 rwx → مجوزهای مالک (User/Owner)
🔹 r-x → مجوزهای گروه (Group)
🔹 r-- → مجوزهای سایر کاربران (Others)

جدول مجوزها:

کاراکتر معنی
r Read (خواندن)
w Write (نوشتن)
x Execute (اجرا)
- بدون مجوز

مثال:
-rw-r--r-- → فایل خواندنی و نوشتنی برای مالک، فقط خواندنی برای گروه و سایر کاربران
-rwxr-xr-x → فایل قابل اجرا برای همه کاربران


۴. تغییر مجوزهای فایل با chmod

اضافه کردن مجوز اجرا به یک فایل برای همه کاربران:

chmod +x script.sh

حذف مجوز نوشتن از گروه:

chmod g-w script.sh

دادن مجوز کامل به مالک و مجوز خواندن به سایرین:

chmod 744 script.sh

۵. نمایش جزئیات مجوزهای یک فایل خاص

می‌توان با دستور زیر فقط اطلاعات یک فایل را مشاهده کرد:

ls -l script.sh

📌 خروجی:

-rwxr--r-- 1 user group  567 Feb 21 12:30 script.sh

جمع‌بندی

دستور ls -l برای نمایش سطح دسترسی فایل‌ها و دایرکتوری‌ها استفاده می‌شود.
اولین کاراکتر (- یا d) نوع فایل را مشخص می‌کند.
سه گروه مجوز (rwx) برای مالک، گروه، و سایر کاربران وجود دارد.
✅ با chmod می‌توان سطح دسترسی‌ها را تغییر داد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. افزودن کامنت‌ها به اسکریپت”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”استفاده از نماد # برای اضافه کردن توضیحات و مستندسازی کد” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، مستندسازی و توضیح کد یکی از مهم‌ترین اصول برای خوانایی و نگهداری کد است. در Bash و سایر شل‌ها، از نماد # برای نوشتن توضیحات در اسکریپت استفاده می‌شود. این توضیحات در حین اجرای اسکریپت نادیده گرفته می‌شوند و صرفاً برای راهنمایی برنامه‌نویسان و کاربران کاربرد دارند.


۱. نوشتن توضیحات تک‌خطی در اسکریپت شل

برای اضافه کردن یک توضیح تک‌خطی، کافی است نماد # را در ابتدای خط قرار دهید:

#!/bin/bash  # مشخص کردن مفسر برای اجرای اسکریپت

# این یک اسکریپت ساده است که متن را در خروجی نمایش می‌دهد
echo "سلام! این یک اسکریپت نمونه است."

📌 نکته: هر متنی که بعد از # بیاید، توسط مفسر شل نادیده گرفته می‌شود.


۲. نوشتن توضیحات چندخطی در اسکریپت شل

در اسکریپت‌های طولانی، بهتر است توضیحات چندخطی برای مستندسازی کد استفاده شود:

#!/bin/bash

# این اسکریپت نام کاربر جاری را نمایش داده
# سپس نام دایرکتوری فعلی را نشان می‌دهد
# و در نهایت لیست فایل‌های موجود را چاپ می‌کند

echo "نام کاربر جاری: $USER"
echo "دایرکتوری جاری: $PWD"
ls -l

📌 نکته: در Bash هیچ ساختار خاصی برای توضیحات چندخطی مانند /* */ در C یا """ """ در Python وجود ندارد، بنابراین باید هر خط توضیح را با # شروع کرد.


۳. استفاده از توضیحات برای غیرفعال کردن موقت یک خط کد

گاهی اوقات برای اشکال‌زدایی (Debugging) یا آزمایش کد، نیاز است که یک خط از اسکریپت اجرا نشود. برای این کار می‌توان از # برای کامنت‌گذاری (Commenting Out) آن خط استفاده کرد:

#!/bin/bash

echo "این خط اجرا می‌شود"

# echo "این خط اجرا نمی‌شود زیرا کامنت شده است"

۴. استفاده از توضیحات برای مستندسازی ورودی و خروجی اسکریپت

برای خوانایی بهتر، می‌توان در ابتدای اسکریپت توضیحاتی درباره نحوه استفاده از آن نوشت:

#!/bin/bash

# اسکریپت: backup.sh
# توضیحات: این اسکریپت از یک دایرکتوری مشخص نسخه پشتیبان تهیه می‌کند
# استفاده: ./backup.sh /home/user/Documents /backup/
# ورودی‌ها: 
#   1. مسیر دایرکتوری منبع
#   2. مسیر دایرکتوری مقصد
# خروجی: ایجاد یک فایل آرشیو از دایرکتوری مشخص‌شده

SOURCE=$1
DEST=$2

tar -czf $DEST/backup.tar.gz $SOURCE

echo "نسخه پشتیبان با موفقیت ایجاد شد!"

📌 نکته: این روش برای اسکریپت‌های عمومی و ابزارهای اتوماسیون بسیار مفید است، زیرا به کاربران نشان می‌دهد که چگونه باید از اسکریپت استفاده کنند.


۵. حذف تمام خطوط توضیحی از یک اسکریپت

اگر بخواهید تمام توضیحات را از یک اسکریپت حذف کنید، می‌توانید از دستور sed استفاده کنید:

sed '/^#/d' script.sh > script_clean.sh

📌 این دستور تمام خطوطی که با # شروع می‌شوند را حذف کرده و خروجی را در script_clean.sh ذخیره می‌کند.


جمع‌بندی

✅ نماد # در Bash برای اضافه کردن توضیحات و مستندسازی کد استفاده می‌شود.
✅ توضیحات باعث افزایش خوانایی کد و درک بهتر عملکرد اسکریپت می‌شوند.
✅ برای توضیحات چندخطی، باید هر خط را جداگانه با # شروع کرد.
✅ می‌توان از # برای غیرفعال کردن موقت بخشی از کد استفاده کرد.
✅ در اسکریپت‌های پیچیده، نوشتن توضیحات در ابتدای فایل برای مستندسازی ورودی‌ها، خروجی‌ها و نحوه استفاده ضروری است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”اهمیت کامنت‌گذاری در خوانایی و نگهداری کد” subtitle=”توضیحات کامل”]کامنت‌گذاری (Commenting) یکی از مهم‌ترین اصول برنامه‌نویسی و اسکریپت‌نویسی است که تأثیر زیادی در خوانایی، نگهداری و اشکال‌زدایی کد دارد. در Bash و سایر شل‌ها، برای نوشتن توضیحات از نماد # استفاده می‌شود. این توضیحات توسط مفسر نادیده گرفته می‌شوند و فقط برای راهنمایی برنامه‌نویسان استفاده می‌شوند.


۱. افزایش خوانایی کد

بدون توضیحات، خواندن و درک کد به‌خصوص در پروژه‌های بزرگ دشوار خواهد شد. کامنت‌گذاری مناسب باعث می‌شود که ساختار و هدف هر بخش از کد به‌راحتی قابل درک باشد.

🔹 مثال بدون کامنت (کد نامفهوم برای افراد دیگر):

#!/bin/bash

a=$(ls -l | wc -l)
echo $a

🔹 مثال با کامنت‌گذاری مناسب:

#!/bin/bash

# شمارش تعداد فایل‌ها و دایرکتوری‌های موجود در مسیر جاری
a=$(ls -l | wc -l)

# نمایش تعداد فایل‌ها در خروجی
echo $a

📌 نتیجه: در نسخه کامنت‌گذاری‌شده، هدف هر خط مشخص است و فهم کد برای دیگران (و حتی خود نویسنده در آینده) آسان‌تر می‌شود.


۲. کمک به اشکال‌زدایی و رفع خطاها

یکی از روش‌های رایج در رفع خطاها (Debugging)، غیرفعال کردن موقتی برخی خطوط کد است. این کار باعث می‌شود که برنامه را مرحله‌به‌مرحله بررسی کنیم.

🔹 مثال:

#!/bin/bash

echo "مرحله ۱: شروع برنامه"

# echo "مرحله ۲: اجرای فرآیند X"  # این خط موقتاً غیرفعال شده است

echo "مرحله ۳: پایان برنامه"

📌 نتیجه: کامنت‌گذاری باعث می‌شود که بدون حذف کردن کد، بتوانیم برخی از بخش‌ها را موقتاً غیرفعال کنیم و رفتار برنامه را بررسی کنیم.


۳. مستندسازی اسکریپت و توضیح عملکرد آن

برای اسکریپت‌هایی که قرار است توسط کاربران دیگر یا تیم‌های مختلف استفاده شوند، بهتر است که در ابتدای کد توضیحاتی درباره نحوه استفاده، ورودی‌ها و خروجی‌های اسکریپت ارائه شود.

🔹 مثال:

#!/bin/bash

# اسکریپت: backup.sh
# توضیحات: این اسکریپت یک نسخه پشتیبان از مسیر مشخص‌شده تهیه می‌کند
# نحوه اجرا: ./backup.sh /home/user/Documents /backup/
# ورودی‌ها:
#   1. مسیر دایرکتوری منبع
#   2. مسیر دایرکتوری مقصد
# خروجی: ایجاد یک فایل آرشیو از دایرکتوری مشخص‌شده

SOURCE=$1
DEST=$2

tar -czf $DEST/backup.tar.gz $SOURCE

echo "نسخه پشتیبان با موفقیت ایجاد شد!"

📌 نتیجه: این نوع کامنت‌گذاری راهنمایی کاملی درباره نحوه استفاده از اسکریپت به کاربران می‌دهد.


۴. جلوگیری از ابهام و سوءتفاهم در تیم‌های برنامه‌نویسی

اگر چندین توسعه‌دهنده روی یک پروژه کار می‌کنند، کامنت‌گذاری می‌تواند از سوءبرداشت‌ها و تغییرات اشتباه در کد جلوگیری کند.

🔹 مثال:

#!/bin/bash

# این متغیر برای ذخیره مسیر فایل‌های موقتی استفاده می‌شود
TMP_DIR="/tmp/my_temp_files"

# بررسی اینکه آیا دایرکتوری وجود دارد یا نه
if [ ! -d "$TMP_DIR" ]; then
    mkdir "$TMP_DIR"
fi

📌 نتیجه: تیم‌های برنامه‌نویسی با خواندن این کامنت متوجه می‌شوند که تغییر این متغیر ممکن است در عملکرد کلی برنامه تأثیر بگذارد.


۵. رعایت استانداردهای نگهداری و توسعه نرم‌افزار

کامنت‌گذاری خوب یکی از استانداردهای مهندسی نرم‌افزار است که در توسعه بلندمدت پروژه‌ها تأثیر زیادی دارد. بسیاری از شرکت‌ها و تیم‌های توسعه، کامنت‌گذاری را به‌عنوان یک استاندارد اجباری در فرآیند توسعه نرم‌افزار در نظر می‌گیرند.

🔹 چند نکته برای کامنت‌گذاری استاندارد:
کامنت‌های مفید بنویسید: توضیح دهید که چرا این کد نوشته شده است، نه فقط اینکه چه کاری انجام می‌دهد.
از کامنت‌های بیش‌ازحد اجتناب کنید: اگر کد به‌اندازه کافی خوانا است، نیازی به توضیح اضافی نیست.
کامنت‌ها را به‌روز نگه دارید: اگر کد تغییر کرد، کامنت‌ها را هم به‌روزرسانی کنید تا اطلاعات غلط ارائه ندهند.


جمع‌بندی

✅ کامنت‌گذاری باعث افزایش خوانایی کد و درک بهتر عملکرد آن می‌شود.
✅ کامنت‌ها به اشکال‌زدایی و رفع خطاها کمک می‌کنند.
✅ مستندسازی در ابتدای اسکریپت، استفاده از آن را برای کاربران دیگر آسان‌تر می‌کند.
✅ در تیم‌های توسعه، کامنت‌ها از سوءبرداشت و تغییرات اشتباه جلوگیری می‌کنند.
✅ رعایت استانداردهای کامنت‌گذاری، نگهداری و توسعه پروژه را در درازمدت ساده‌تر می‌کند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 7. ساختار اصلی یک اسکریپت شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تعریف بخش‌های اصلی یک اسکریپت” subtitle=”توضیحات کامل”]یک اسکریپت شل شامل بخش‌های مختلفی است که هر کدام نقش خاصی در اجرای برنامه دارند. در این قسمت، سه بخش اصلی اسکریپت را بررسی می‌کنیم:

  • تعریف متغیرها (Variables)
  • دستورات اصلی (Main Commands)
  • حلقه‌ها و شرط‌ها (Loops & Conditions)

۱. تعریف متغیرها

متغیرها در اسکریپت شل برای ذخیره داده‌ها و مقداردهی اولیه استفاده می‌شوند. تعریف متغیرها به شما این امکان را می‌دهد که مقدارهای تکراری را در کد ذخیره کنید و برنامه را انعطاف‌پذیرتر کنید.

🔹 نحوه تعریف متغیر در Bash:

#!/bin/bash

# تعریف متغیرها
NAME="Ali"
AGE=25
CITY="Tehran"

# نمایش مقدار متغیرها
echo "نام: $NAME"
echo "سن: $AGE"
echo "شهر: $CITY"

📌 نکات مهم درباره متغیرها:
✅ بین نام متغیر و مقدار آن نباید فاصله باشد.
✅ برای مقداردهی متغیرهای متنی نیاز به علامت نقل‌قول (“”) داریم.
✅ برای مقداردهی متغیرهای عددی نیازی به نقل‌قول نیست.
✅ برای استفاده از مقدار متغیر از نماد $ قبل از نام آن استفاده می‌شود.


۲. دستورات اصلی

دستورات اصلی شامل دستورات لینوکس و دستورات داخلی شل هستند که در اسکریپت اجرا می‌شوند. این دستورات می‌توانند شامل کارهایی مثل مدیریت فایل‌ها، نمایش اطلاعات و اجرای برنامه‌های دیگر باشند.

🔹 مثال از دستورات اصلی در اسکریپت:

#!/bin/bash

# نمایش اطلاعات سیستم
echo "نام کاربر: $(whoami)"
echo "تاریخ و زمان: $(date)"
echo "مسیر جاری: $(pwd)"

# ایجاد یک دایرکتوری جدید
mkdir my_directory

# بررسی وجود فایل
if [ -f myfile.txt ]; then
    echo "فایل موجود است."
else
    echo "فایل یافت نشد."
fi

📌 نکات:
echo برای نمایش پیام‌ها در خروجی استفاده می‌شود.
$(whoami), $(date), $(pwd) دستورات داخلی سیستم هستند که مقدارهای مختلفی را برمی‌گردانند.
mkdir برای ایجاد دایرکتوری و [ -f ] برای بررسی وجود فایل استفاده می‌شود.


۳. حلقه‌ها و شرط‌ها

حلقه‌ها و شرط‌ها به شما اجازه می‌دهند برنامه را بر اساس شرایط خاصی اجرا کنید یا چندین بار یک عملیات را انجام دهید.

۳.۱ دستورات شرطی (if-else)

دستورات شرطی برای بررسی شرایط مختلف و اجرای کدهای متفاوت بر اساس شرایط صحیح یا غلط استفاده می‌شوند.

🔹 مثال از دستور شرطی:

#!/bin/bash

# بررسی وضعیت اینترنت
ping -c 1 google.com &> /dev/null

if [ $? -eq 0 ]; then
    echo "اتصال اینترنت برقرار است."
else
    echo "اتصال اینترنت برقرار نیست."
fi

📌 نکات:
✅ دستور ping -c 1 google.com بررسی می‌کند که آیا اینترنت متصل است یا نه.
✅ مقدار $? وضعیت اجرای دستور قبلی را ذخیره می‌کند (۰ برای موفقیت، عددی غیر از صفر برای شکست).

۳.۲ حلقه‌ها (for, while, until)

حلقه‌ها برای اجرای یک دستور چندین بار استفاده می‌شوند.

🔹 مثال از حلقه for برای تکرار دستورات:

#!/bin/bash

# نمایش اعداد ۱ تا ۵
for i in {1..5}
do
    echo "عدد: $i"
done

🔹 مثال از حلقه while برای اجرای دستورات تا زمان خاصی:

#!/bin/bash

count=1
while [ $count -le 5 ]
do
    echo "تعداد: $count"
    ((count++))
done

📌 نکات:
✅ حلقه for از {1..5} برای تولید اعداد ۱ تا ۵ استفاده می‌کند.
✅ حلقه while تا زمانی که مقدار count کمتر از ۵ باشد، اجرا می‌شود.


جمع‌بندی

متغیرها برای ذخیره داده‌ها و مقداردهی اولیه در اسکریپت استفاده می‌شوند.
دستورات اصلی شامل دستورات سیستم، مدیریت فایل‌ها و پردازش داده‌ها هستند.
شرط‌ها امکان بررسی شرایط و اجرای تصمیمات منطقی را فراهم می‌کنند.
حلقه‌ها اجرای دستورات تکراری را امکان‌پذیر می‌کنند.
✅ ترکیب این سه بخش اصلی در اسکریپت‌های Bash امکان مدیریت خودکار فرآیندها و اجرای وظایف پیشرفته را فراهم می‌کند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”سازماندهی اسکریپت به صورت منطقی و خوانا” subtitle=”توضیحات کامل”]یک اسکریپت شل خوانا و سازمان‌یافته باعث می‌شود که نه‌تنها درک آن آسان‌تر باشد، بلکه نگهداری و رفع اشکال آن نیز ساده‌تر شود. در این بخش، روش‌هایی را بررسی می‌کنیم که به شما کمک می‌کنند اسکریپت‌های Bash را به‌صورت منظم و حرفه‌ای بنویسید.


۱. تقسیم‌بندی اسکریپت به بخش‌های مشخص

یک اسکریپت خوب باید ساختار واضحی داشته باشد. معمولاً اسکریپت‌های Bash به بخش‌های زیر تقسیم می‌شوند:

  1. Shebang و اطلاعات اولیه
  2. تعریف متغیرها
  3. تعریف توابع (در صورت نیاز)
  4. دستورات اصلی (Logic اصلی اسکریپت)
  5. جمع‌بندی و پایان اسکریپت

🔹 نمونه ساختار استاندارد یک اسکریپت خوانا:

#!/bin/bash

# ==============================
#  اسکریپت: Backup Script
#  نویسنده: Ali
#  تاریخ: 2025-02-21
#  توضیح: این اسکریپت از دایرکتوری مشخص‌شده بکاپ می‌گیرد.
# ==============================

# --- 1. تعریف متغیرها ---
SOURCE_DIR="/home/user/Documents"
BACKUP_DIR="/home/user/Backup"
LOG_FILE="/home/user/backup.log"

# --- 2. تعریف توابع ---
backup_files() {
    echo "در حال ایجاد بکاپ از $SOURCE_DIR..."
    tar -czf "$BACKUP_DIR/backup_$(date +%F).tar.gz" "$SOURCE_DIR"
    echo "بکاپ با موفقیت ذخیره شد!" | tee -a "$LOG_FILE"
}

# --- 3. اجرای اسکریپت ---
backup_files

📌 ویژگی‌های این اسکریپت:
دارای بخش توضیحات در ابتدای کد (نام، نویسنده، تاریخ، توضیحات کوتاه)
متغیرها در یک بخش جدا تعریف شده‌اند
توابع برای سازمان‌دهی بهتر کد استفاده شده‌اند
دستورات اصلی در انتهای اسکریپت قرار گرفته‌اند


۲. استفاده از کامنت‌ها برای توضیح کد

کامنت‌ها باعث خوانایی بیشتر کد می‌شوند و درک آن را برای برنامه‌نویس‌های دیگر (و حتی خودتان در آینده) آسان‌تر می‌کنند.

🔹 نمونه استفاده صحیح از کامنت‌ها:

#!/bin/bash

# نام فایل بکاپ را بر اساس تاریخ تنظیم می‌کند
BACKUP_FILE="backup_$(date +%F).tar.gz"

# ایجاد بکاپ از دایرکتوری مشخص‌شده
tar -czf "/backup/$BACKUP_FILE" "/home/user/Documents"

# بررسی موفقیت‌آمیز بودن عملیات بکاپ‌گیری
if [ $? -eq 0 ]; then
    echo "بکاپ با موفقیت ایجاد شد: $BACKUP_FILE"
else
    echo "بکاپ‌گیری ناموفق بود!"
fi

📌 نکات مهم:
هر بخش مهم از اسکریپت توضیح داده شده است
کامنت‌ها کوتاه و دقیق هستند
از کامنت‌های اضافی که واضحات را توضیح می‌دهند اجتناب شده است


۳. نام‌گذاری استاندارد متغیرها و توابع

🔹 قوانین پیشنهادی برای نام‌گذاری متغیرها و توابع:
نام متغیرها باید گویا باشند (به جای x=5 بنویسید MAX_RETRY=5)
متغیرها با حروف بزرگ نوشته شوند (مثلاً BACKUP_DIR به جای backupdir)
نام توابع باید توصیفی باشد (مثلاً backup_files به جای bf)

🔹 نمونه نام‌گذاری مناسب:

#!/bin/bash

# متغیرها
LOG_DIR="/var/log/my_script"
MAX_RETRY=3

# تعریف تابع برای بررسی فضای دیسک
check_disk_space() {
    df -h | grep "/dev/sda1"
}

📌 مزیت این روش: نام‌ها معنی‌دار هستند و باعث خوانایی بیشتر اسکریپت می‌شوند.


۴. استفاده از توابع برای جلوگیری از تکرار کد

اگر یک کد چندین بار در اسکریپت استفاده شود، بهتر است که آن را در قالب یک تابع تعریف کنیم.

🔹 مثال بدون استفاده از تابع:

#!/bin/bash

echo "در حال بررسی اتصال به اینترنت..."
ping -c 1 google.com &> /dev/null
if [ $? -eq 0 ]; then
    echo "اینترنت متصل است."
else
    echo "اینترنت قطع است."
fi

echo "در حال بررسی اتصال به سرور..."
ping -c 1 192.168.1.1 &> /dev/null
if [ $? -eq 0 ]; then
    echo "سرور در دسترس است."
else
    echo "سرور در دسترس نیست."
fi

🔹 بهینه‌سازی با استفاده از تابع:

#!/bin/bash

# تابع بررسی اتصال
check_connection() {
    ping -c 1 $1 &> /dev/null
    if [ $? -eq 0 ]; then
        echo "$1 در دسترس است."
    else
        echo "$1 در دسترس نیست."
    fi
}

# اجرای تابع برای بررسی اینترنت و سرور
check_connection "google.com"
check_connection "192.168.1.1"

📌 مزیت استفاده از توابع:
جلوگیری از تکرار کد
خوانایی بیشتر و مدیریت آسان‌تر


۵. استفاده از کنترل خطا برای جلوگیری از توقف غیرمنتظره اسکریپت

یک اسکریپت خوب باید بتواند خطاهای احتمالی را مدیریت کند تا باعث اختلال در اجرای برنامه نشود.

🔹 مثال: بررسی وجود یک دایرکتوری قبل از ایجاد آن

#!/bin/bash

DIR="/backup"

# بررسی وجود دایرکتوری
if [ ! -d "$DIR" ]; then
    echo "دایرکتوری وجود ندارد. در حال ایجاد..."
    mkdir -p "$DIR"
else
    echo "دایرکتوری از قبل وجود دارد."
fi

📌 مزیت این روش:
✅ از ایجاد خطای “فایل یا دایرکتوری موجود نیست” جلوگیری می‌کند.


جمع‌بندی

ساختار اسکریپت را به بخش‌های مشخص (Shebang، متغیرها، توابع، دستورات اصلی) تقسیم کنید.
از کامنت‌های کوتاه و کاربردی برای توضیح بخش‌های مهم استفاده کنید.
نام متغیرها و توابع باید گویا و قابل فهم باشند.
از توابع برای جلوگیری از تکرار کد استفاده کنید.
برای مدیریت بهتر اسکریپت، کنترل خطا و بررسی وضعیت دستورات را لحاظ کنید.

با رعایت این نکات، اسکریپت‌های شما خواناتر، منظم‌تر و نگهداری‌پذیرتر خواهند بود.[/cdb_course_lesson][cdb_course_lesson title=”فصل 8. اجرای اسکریپت و اشکال‌زدایی اولیه”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”نحوه اجرای اسکریپت و بررسی خطاهای احتمالی” subtitle=”توضیحات کامل”]اجرای صحیح اسکریپت شل و بررسی خطاهای احتمالی، یکی از مهم‌ترین بخش‌های مدیریت اسکریپت‌ها در لینوکس است. در این بخش، روش‌های مختلف اجرای اسکریپت، نحوه بررسی و مدیریت خطاها، و جلوگیری از توقف ناگهانی اسکریپت را توضیح می‌دهیم.


۱. روش‌های مختلف اجرای اسکریپت

پس از ایجاد یک اسکریپت، چندین روش برای اجرای آن وجود دارد:

🔹 ۱. اجرای اسکریپت با نام مستقیم و استفاده از bash یا sh

bash myscript.sh
sh myscript.sh

📌 در این روش، نیازی به اعمال مجوز اجرایی (chmod +x) نیست، اما اسکریپت باید به درستی نوشته شده باشد.

🔹 ۲. اجرای اسکریپت با استفاده از ./ (مستقیم از مسیر فعلی)

./myscript.sh

📌 در این روش، اسکریپت باید دارای مجوز اجرایی باشد. در غیر این صورت، با خطای زیر مواجه می‌شوید:

bash: ./myscript.sh: Permission denied

✅ برای حل مشکل، باید مجوز اجرایی به اسکریپت بدهید:

chmod +x myscript.sh

🔹 ۳. اجرای اسکریپت از مسیر کامل

/home/user/scripts/myscript.sh

📌 اگر مسیر اسکریپت در PATH تعریف نشده باشد، باید مسیر کامل را مشخص کنید.

🔹 ۴. اجرای اسکریپت در یک شل دیگر

zsh myscript.sh   # اجرای اسکریپت با Zsh
dash myscript.sh  # اجرای اسکریپت با Dash

📌 این روش زمانی کاربرد دارد که بخواهید اسکریپت را در یک مفسر خاص اجرا کنید.


۲. بررسی خطاهای احتمالی در اجرای اسکریپت

در هنگام اجرای یک اسکریپت، ممکن است با خطاهای مختلفی مواجه شوید. در ادامه روش‌های بررسی و مدیریت خطاها را بررسی می‌کنیم.

🔹 ۱. استفاده از echo $? برای بررسی خروجی دستورات
هر دستور در لینوکس پس از اجرا، یک مقدار خروجی (exit status) برمی‌گرداند:

✅ مقدار 0 نشان‌دهنده موفقیت است.
❌ مقدار غیر از 0 نشان‌دهنده خطا است.

🔹 مثال بررسی خروجی یک دستور:

ls /home/user
echo $?

اگر مقدار خروجی 0 باشد، یعنی دستور بدون خطا اجرا شده است. در غیر این صورت، باید مشکل را بررسی کنید.

🔹 ۲. استفاده از set -e برای توقف اجرای اسکریپت در صورت وقوع خطا
در حالت عادی، اگر یک دستور در اسکریپت با خطا مواجه شود، اجرای اسکریپت ادامه پیدا می‌کند. برای جلوگیری از این اتفاق، می‌توان از set -e استفاده کرد.

🔹 مثال:

#!/bin/bash
set -e  # توقف اجرای اسکریپت در صورت وقوع خطا

echo "در حال اجرای دستورات..."
mkdir /root/testdir  # اگر کاربر دسترسی نداشته باشد، اسکریپت متوقف می‌شود
echo "این پیام چاپ نمی‌شود اگر خطا رخ دهد!"

📌 بدون set -e، اگر یک دستور با خطا مواجه شود، اجرای اسکریپت ادامه می‌یابد. اما با set -e، اجرای اسکریپت متوقف می‌شود.

🔹 ۳. استفاده از trap برای مدیریت خطاها
اگر بخواهید هنگام وقوع خطا یک پیام خاص نمایش داده شود یا عملیات خاصی انجام دهید، می‌توانید از trap استفاده کنید.

🔹 مثال:

#!/bin/bash

trap 'echo "❌ خطا رخ داده است! اسکریپت متوقف شد." ; exit 1' ERR

echo "شروع اسکریپت..."
cd /root/non_existent_directory  # این خطا باعث اجرای trap می‌شود
echo "این پیام چاپ نمی‌شود!"

📌 در این مثال، اگر اسکریپت به خطایی برخورد کند، trap پیام خطا را نمایش داده و اجرای اسکریپت را متوقف می‌کند.

🔹 ۴. استفاده از if برای بررسی موفقیت یا شکست یک دستور

#!/bin/bash

echo "بررسی ارتباط با اینترنت..."
ping -c 1 google.com &> /dev/null

if [ $? -eq 0 ]; then
    echo "✅ اینترنت متصل است."
else
    echo "❌ اینترنت قطع است!"
fi

📌 در این مثال، اگر ping موفق باشد، پیام “اینترنت متصل است” نمایش داده می‌شود، در غیر این صورت، پیام “اینترنت قطع است” نمایش داده خواهد شد.

🔹 ۵. ثبت خروجی و خطاها در یک فایل لاگ
برای ذخیره اطلاعات اجرای اسکریپت و بررسی خطاها بعداً، می‌توان خروجی را در یک فایل لاگ ثبت کرد.

🔹 مثال:

#!/bin/bash

LOG_FILE="/var/log/myscript.log"

echo "شروع اجرای اسکریپت..." | tee -a "$LOG_FILE"
ls /nonexistent_directory &>> "$LOG_FILE"
echo "پایان اجرای اسکریپت." | tee -a "$LOG_FILE"

📌 در این روش، خطاها و خروجی‌ها در فایل /var/log/myscript.log ذخیره می‌شوند.


جمع‌بندی

روش‌های مختلف اجرای اسکریپت شامل bash script.sh، ./script.sh و sh script.sh است.
برای اجرای اسکریپت به صورت مستقیم، باید مجوز اجرایی (chmod +x script.sh) داده شود.
برای بررسی موفقیت اجرای دستورات، می‌توان از echo $? استفاده کرد.
استفاده از set -e مانع از ادامه اجرای اسکریپت در صورت وقوع خطا می‌شود.
با استفاده از trap می‌توان خطاهای احتمالی را مدیریت و پیام‌های مناسب نمایش داد.
برای جلوگیری از اجرای ادامه اسکریپت در صورت خطا، می‌توان از if برای بررسی exit status دستورات استفاده کرد.
ثبت لاگ اجرای اسکریپت باعث می‌شود که بتوانیم خطاها را در آینده بررسی کنیم.

با رعایت این نکات، می‌توان اسکریپت‌هایی پایدار، بدون خطا و قابل‌مدیریت نوشت.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”استفاده از گزینه bash -x scriptname.sh برای دنبال کردن دستورات در حین اجرا” subtitle=”توضیحات کامل”]یکی از مشکلات رایج در اسکریپت‌نویسی شل، خطایابی و بررسی نحوه اجرای دستورات است. در لینوکس، bash -x یک گزینه مفید برای اشکال‌زدایی (Debugging) اسکریپت‌هاست که هنگام اجرای اسکریپت، دستورات را قبل از اجرا نمایش می‌دهد. این قابلیت کمک می‌کند تا متوجه شوید که کدام دستورات اجرا می‌شوند، چه مقادیری به متغیرها اختصاص داده شده و چه چیزی باعث خطاهای احتمالی می‌شود.


۱. نحوه استفاده از bash -x برای اشکال‌زدایی اسکریپت

🔹 برای مشاهده دستورات در حین اجرا، کافی است اسکریپت را با گزینه -x اجرا کنید:

bash -x scriptname.sh

📌 در این روش، هر دستوری که اجرا می‌شود، قبل از اجرا با یک + در ابتدای آن نمایش داده می‌شود.

🔹 مثال ساده:
فرض کنید یک اسکریپت ساده به نام test.sh داریم:

#!/bin/bash
name="Ali"
echo "Hello, $name!"

✅ اجرای معمولی اسکریپت:

./test.sh

🔹 خروجی:

Hello, Ali!

✅ اجرای اسکریپت با bash -x:

bash -x test.sh

🔹 خروجی:

+ name='Ali'
+ echo 'Hello, Ali!'
Hello, Ali!

📌 در این خروجی، علامت + نشان‌دهنده دستورات در حال اجرا است.


۲. اشکال‌زدایی اسکریپت‌های پیچیده‌تر

فرض کنید اسکریپتی دارید که محاسبات انجام می‌دهد و ممکن است دارای خطا باشد:

🔹 اسکریپت نمونه (calc.sh)

#!/bin/bash
a=10
b=0
result=$((a / b))
echo "Result: $result"

✅ اجرای معمولی:

./calc.sh

🔹 خروجی:

./calc.sh: line 4: division by zero (error token is "b)")

📌 این خطا نشان می‌دهد که تقسیم بر صفر انجام شده است اما مشخص نمی‌کند که دقیقا کدام مقدار باعث این مشکل شده است.

✅ اجرای اسکریپت با bash -x:

bash -x calc.sh

🔹 خروجی:

+ a=10
+ b=0
+ result='(10 / 0)'
./calc.sh: line 4: division by zero (error token is "b)")

📌 این خروجی نشان می‌دهد که مقدار b=0 بوده و باعث این خطا شده است.


۳. استفاده از set -x و set +x برای فعال/غیرفعال کردن اشکال‌زدایی

گاهی اوقات نمی‌خواهید کل اسکریپت را در حالت اشکال‌زدایی اجرا کنید، بلکه فقط بخش خاصی از آن را بررسی کنید. در این حالت، می‌توانید از دستورات set -x و set +x استفاده کنید:

🔹 مثال:

#!/bin/bash
echo "شروع اسکریپت..."

set -x  # فعال کردن اشکال‌زدایی
a=5
b=3
sum=$((a + b))
echo "جمع: $sum"
set +x  # غیرفعال کردن اشکال‌زدایی

echo "پایان اسکریپت."

✅ اجرای اسکریپت:

./script.sh

🔹 خروجی:

شروع اسکریپت...
+ a=5
+ b=3
+ sum=8
+ echo 'جمع: 8'
جمع: 8
پایان اسکریپت.

📌 در این خروجی، فقط بخش موردنظر (بین set -x و set +x) در حالت اشکال‌زدایی نمایش داده شده است.


۴. ترکیب bash -x با tee برای ذخیره خروجی اشکال‌زدایی

🔹 اگر بخواهید خروجی اشکال‌زدایی را در یک فایل لاگ ذخیره کنید، می‌توانید از tee استفاده کنید:

bash -x scriptname.sh 2>&1 | tee debug.log

✅ این دستور خروجی اشکال‌زدایی را هم در ترمینال نمایش می‌دهد و هم در فایل debug.log ذخیره می‌کند.


۵. مقایسه bash -x و bash -v و bash -n

🔹 bash -x : نمایش دستورات در حین اجرا (برای اشکال‌زدایی)
🔹 bash -v : نمایش کل محتوای اسکریپت قبل از اجرا
🔹 bash -n : بررسی نحوی اسکریپت بدون اجرای آن

🔹 مثال:

bash -n script.sh

📌 این دستور اسکریپت را بررسی می‌کند و در صورت وجود خطای نحوی، آن را نمایش می‌دهد.


جمع‌بندی

bash -x برای اشکال‌زدایی اسکریپت‌ها استفاده می‌شود و دستورات را قبل از اجرا نمایش می‌دهد.
با set -x و set +x می‌توان اشکال‌زدایی را فقط برای بخش‌های خاصی از اسکریپت فعال کرد.
با bash -x script.sh 2>&1 | tee log.txt می‌توان خروجی اشکال‌زدایی را در یک فایل ذخیره کرد.
گزینه‌های دیگر مانند bash -v و bash -n نیز برای اشکال‌زدایی مفید هستند.

با استفاده از این روش‌ها، می‌توانید اسکریپت‌های خود را راحت‌تر اشکال‌زدایی و مشکلات آن‌ها را سریع‌تر پیدا کنید. 🚀[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”رفع مشکلات رایج مانند دسترسی یا خطاهای سینتکس” subtitle=”توضیحات کامل”]در هنگام اجرای اسکریپت‌های شل، ممکن است با خطاهای مختلفی مواجه شوید. این خطاها معمولاً به دو دسته اصلی تقسیم می‌شوند:

  1. مشکلات مربوط به دسترسی و مجوزها (Permissions)
  2. خطاهای نحوی (Syntax Errors) و مشکلات منطقی

در این قسمت، روش‌های رفع این مشکلات را بررسی می‌کنیم.


۱. مشکلات مربوط به دسترسی (Permissions Errors)

یکی از رایج‌ترین خطاهایی که هنگام اجرای یک اسکریپت با آن مواجه می‌شوید، مربوط به مجوز اجرا (Execution Permission) است.

خطای رایج:

bash: ./script.sh: Permission denied

📌 این خطا به این دلیل است که فایل اسکریپت مجوز اجرای (Executable Permission) لازم را ندارد.

🔹 راه‌حل: باید با استفاده از دستور chmod مجوز اجرا را اضافه کنید:

chmod +x script.sh

🔹 سپس می‌توانید اسکریپت را اجرا کنید:

./script.sh

📌 اگر هنوز مشکل وجود دارد، بررسی کنید که فایل دارای مجوز اجرای کافی است:

ls -l script.sh

🔹 خروجی نمونه:

-rw-r--r-- 1 user user  1234 Feb 21 10:30 script.sh

📌 در این حالت، x (اجرا) در مجوزها وجود ندارد. باید chmod +x را اجرا کنید.

🔹 اگر خطا همچنان باقی ماند، ممکن است مشکل به دلیل مالکیت فایل باشد. در این صورت، مالک فایل را تغییر دهید:

sudo chown $USER:$USER script.sh

🔹 اگر همچنان اجازه اجرا ندارید، اسکریپت را با bash اجرا کنید:

bash script.sh

📌 این روش نیاز به مجوز اجرایی ندارد، زیرا bash مستقیماً فایل را اجرا می‌کند.


۲. خطاهای نحوی (Syntax Errors) و مشکلات کدنویسی

گاهی اوقات هنگام اجرای اسکریپت با خطاهای نحوی (Syntax Errors) مواجه می‌شوید.

خطای رایج:

./script.sh: line 3: unexpected token `('

📌 این خطا معمولاً نشان‌دهنده یک مشکل در سینتکس (Syntax) کد شما است.

🔹 راه‌حل: بررسی اسکریپت با دستور bash -n

bash -n script.sh

📌 این دستور، اسکریپت را بدون اجرا از نظر نحوی بررسی می‌کند و اگر مشکلی وجود داشته باشد، اعلام می‌کند.

🔹 استفاده از bash -x برای اشکال‌زدایی

bash -x script.sh

📌 این دستور، دستورات را قبل از اجرا نمایش می‌دهد و کمک می‌کند که مشکل را سریع‌تر پیدا کنید.

🔹 بررسی وجود Shebang در ابتدای اسکریپت
حتماً بررسی کنید که اسکریپت شما با Shebang شروع شده باشد:

#!/bin/bash

📌 اگر این خط وجود نداشته باشد، ممکن است اسکریپت در محیطی نادرست اجرا شود و باعث خطا شود.


۳. مشکل command not found هنگام اجرای دستورات

خطای رایج:

./script.sh: line 5: somecommand: command not found

📌 این خطا نشان می‌دهد که دستور somecommand در سیستم وجود ندارد یا در PATH تعریف نشده است.

🔹 راه‌حل: بررسی کنید که آیا دستور در مسیر صحیح قرار دارد:

which somecommand

📌 اگر این دستور خروجی‌ای نداشت، یعنی برنامه نصب نیست. باید آن را نصب کنید:

sudo apt install somecommand  # برای Debian/Ubuntu
sudo yum install somecommand  # برای CentOS/RHEL

🔹 اگر برنامه در مسیر خاصی نصب شده است، مسیر کامل را در اسکریپت مشخص کنید:

/home/user/bin/somecommand

🔹 بررسی مسیر PATH

echo $PATH

📌 اگر مسیر دستور در PATH نیست، می‌توانید آن را اضافه کنید:

export PATH=$PATH:/home/user/bin

📌 برای دائمی کردن این تغییر، مقدار جدید را در ~/.bashrc اضافه کنید.


۴. مشکل bad interpreter در اجرای اسکریپت

خطای رایج:

-bash: ./script.sh: /bin/bash^M: bad interpreter: No such file or directory

📌 این خطا معمولاً زمانی رخ می‌دهد که اسکریپت در ویندوز نوشته شده و فرمت پایان خط آن CRLF است، نه LF.

🔹 راه‌حل:

dos2unix script.sh

📌 اگر dos2unix نصب نیست، از sed استفاده کنید:

sed -i 's/\r$//' script.sh

۵. مشکل متغیرهای تعریف‌نشده (Undefined Variables)

خطای رایج:

./script.sh: line 4: $myvar: unbound variable

📌 این خطا زمانی رخ می‌دهد که متغیری استفاده شده است ولی مقداردهی نشده است.

🔹 راه‌حل: بررسی مقدار متغیرها با echo

echo $myvar

📌 مقداردهی پیش‌فرض برای جلوگیری از خطا:

myvar=${myvar:-"Default Value"}

🔹 استفاده از set -u برای پیدا کردن متغیرهای تعریف‌نشده

set -u

📌 این گزینه باعث می‌شود که اگر متغیری تعریف نشده باشد، اسکریپت متوقف شود.


۶. بررسی و اشکال‌زدایی لاگ‌ها

برای تحلیل بهتر مشکلات، می‌توان خروجی لاگ اسکریپت را ذخیره کرد:

./script.sh > output.log 2>&1

📌 این دستور تمام خروجی استاندارد (stdout) و خطاها (stderr) را در فایل output.log ذخیره می‌کند.


جمع‌بندی

مشکل دسترسی:

  • اجرای chmod +x script.sh برای اجازه اجرا
  • اجرای ls -l script.sh برای بررسی مجوزها
  • استفاده از bash script.sh برای اجرا بدون نیاز به مجوز اجرایی

مشکل سینتکس:

  • اجرای bash -n script.sh برای بررسی نحوی بدون اجرا
  • اجرای bash -x script.sh برای اشکال‌زدایی و نمایش دستورات در حین اجرا

مشکل command not found:

  • بررسی which command و اضافه کردن مسیر صحیح به PATH
  • نصب دستورات موردنیاز با apt install یا yum install

مشکل bad interpreter (خطای ^M):

  • اجرای dos2unix script.sh برای تبدیل فرمت پایان خط ویندوز به لینوکس

مشکل متغیرهای تعریف‌نشده:

  • استفاده از set -u برای پیدا کردن متغیرهای تعریف‌نشده
  • مقداردهی پیش‌فرض با ${var:-default}

با رعایت این نکات، می‌توانید مشکلات رایج در اجرای اسکریپت‌های شل را برطرف کنید و اسکریپت‌های پایدارتر و بهینه‌تری بنویسید. 🚀[/cdb_course_lesson][cdb_course_lesson title=”فصل 9. تعامل با کاربر”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”استفاده از دستور read برای گرفتن ورودی از کاربر” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، برای دریافت ورودی از کاربر می‌توان از دستور read استفاده کرد. این دستور اطلاعات را از ورودی استاندارد (stdin) دریافت کرده و در یک متغیر ذخیره می‌کند.


۱. دریافت ورودی ساده از کاربر

می‌توان مقدار ورودی را در یک متغیر ذخیره و سپس از آن استفاده کرد.

🔹 مثال: دریافت نام کاربر و نمایش پیام خوش‌آمدگویی

#!/bin/bash

echo "لطفاً نام خود را وارد کنید:"
read name
echo "سلام، $name! خوش آمدید."

📌 در این مثال، مقدار ورودی در متغیر name ذخیره شده و سپس در خروجی نمایش داده می‌شود.

🔹 اجرای اسکریپت:

chmod +x script.sh
./script.sh

🔹 خروجی نمونه:

لطفاً نام خود را وارد کنید:
علی
سلام، علی! خوش آمدید.

۲. دریافت ورودی در همان خط

به‌طور پیش‌فرض، read منتظر می‌ماند تا کاربر ورودی را وارد کند و سپس مقدار را ذخیره می‌کند. اما برای زیبایی و راحتی می‌توان متن راهنما را در همان خط نمایش داد.

🔹 استفاده از فلگ -p برای نمایش پیام در همان خط:

#!/bin/bash

read -p "لطفاً سن خود را وارد کنید: " age
echo "شما $age سال دارید."

🔹 خروجی نمونه:

لطفاً سن خود را وارد کنید: 25
شما 25 سال دارید.

۳. دریافت چندین ورودی در یک خط

می‌توان هم‌زمان چند مقدار را از کاربر دریافت و در متغیرهای مختلف ذخیره کرد.

🔹 مثال: دریافت نام و نام خانوادگی در یک خط:

#!/bin/bash

read -p "لطفاً نام و نام خانوادگی خود را وارد کنید: " first_name last_name
echo "سلام، $first_name $last_name!"

🔹 خروجی نمونه:

لطفاً نام و نام خانوادگی خود را وارد کنید: علی رضایی
سلام، علی رضایی!

۴. دریافت ورودی بدون نمایش آن (ورودی مخفی – مناسب برای پسورد)

برای دریافت ورودی محرمانه (مانند رمز عبور) می‌توان از فلگ -s استفاده کرد تا هنگام تایپ، ورودی نمایش داده نشود.

🔹 مثال: دریافت رمز عبور از کاربر:

#!/bin/bash

read -s -p "لطفاً رمز عبور خود را وارد کنید: " password
echo -e "\nرمز عبور شما ذخیره شد."

📌 -s باعث می‌شود کاراکترهای ورودی روی صفحه نمایش داده نشوند.
📌 -e "\n" برای اضافه کردن یک خط جدید بعد از دریافت ورودی استفاده شده است.

🔹 خروجی نمونه:

لطفاً رمز عبور خود را وارد کنید: 
رمز عبور شما ذخیره شد.

📌 در این مثال، هنگام وارد کردن رمز عبور، چیزی روی صفحه نمایش داده نمی‌شود.


۵. تنظیم مقدار پیش‌فرض برای ورودی

اگر کاربر مقدار خاصی وارد نکند، می‌توان مقدار پیش‌فرضی برای متغیر در نظر گرفت.

🔹 مثال: مقدار پیش‌فرض برای نام کاربر

#!/bin/bash

read -p "نام خود را وارد کنید (پیش‌فرض: کاربر مهمان): " name
name=${name:-"کاربر مهمان"}
echo "سلام، $name!"

📌 name=${name:-"کاربر مهمان"} اگر مقدار name خالی باشد، مقدار “کاربر مهمان” را جایگزین می‌کند.

🔹 خروجی نمونه (وقتی کاربر نام وارد نمی‌کند):

نام خود را وارد کنید (پیش‌فرض: کاربر مهمان): 
سلام، کاربر مهمان!

۶. دریافت مقدار ورودی به‌صورت محدود به تعداد کاراکتر

گاهی لازم است که تعداد کاراکتر ورودی محدود شود. این کار با فلگ -n انجام می‌شود.

🔹 مثال: دریافت کد تأیید ۴ رقمی:

#!/bin/bash

read -n 4 -p "کد تأیید را وارد کنید: " code
echo -e "\nکد شما: $code"

📌 -n 4 تعیین می‌کند که حداکثر ۴ کاراکتر دریافت شود.
📌 -e "\n" برای ایجاد خط جدید بعد از ورود مقدار استفاده شده است.

🔹 خروجی نمونه:

کد تأیید را وارد کنید: 1234
کد شما: 1234

۷. محدود کردن زمان دریافت ورودی

اگر بخواهید ورودی را در یک بازه زمانی محدود بگیرید، می‌توانید از فلگ -t استفاده کنید.

🔹 مثال: دریافت نام کاربر با محدودیت زمانی ۵ ثانیه:

#!/bin/bash

read -t 5 -p "لطفاً نام خود را ظرف ۵ ثانیه وارد کنید: " name
name=${name:-"کاربر ناشناس"}
echo "سلام، $name!"

📌 -t 5 مشخص می‌کند که ورودی باید در عرض ۵ ثانیه انجام شود. در غیر این صورت، مقدار پیش‌فرض تنظیم می‌شود.

🔹 خروجی نمونه (اگر کاربر ورودی ندهد):

لطفاً نام خود را ظرف ۵ ثانیه وارد کنید: 
سلام، کاربر ناشناس!

۸. خواندن ورودی از فایل

به‌جای دریافت ورودی از کاربر، می‌توان ورودی را از یک فایل خواند.

🔹 مثال: خواندن مقدار از فایل data.txt و نمایش آن

#!/bin/bash

read content < data.txt
echo "محتوای فایل: $content"

📌 read content < data.txt مقدار اولین خط از فایل data.txt را در متغیر content ذخیره می‌کند.

🔹 اگر بخواهید کل فایل را خط به خط بخوانید:

#!/bin/bash

while read line
do
  echo "خط خوانده شده: $line"
done < data.txt

جمع‌بندی

دریافت ورودی ساده از کاربر:

read name

دریافت ورودی در همان خط:

read -p "لطفاً سن خود را وارد کنید: " age

دریافت چندین مقدار هم‌زمان:

read first_name last_name

ورودی مخفی (رمز عبور):

read -s password

مقدار پیش‌فرض در صورت وارد نکردن مقدار:

name=${name:-"کاربر مهمان"}

محدود کردن تعداد کاراکتر ورودی:

read -n 4 code

محدود کردن زمان دریافت ورودی:

read -t 5 name

خواندن مقدار از فایل:

read content < file.txt

با استفاده از این روش‌ها، می‌توانید ورودی‌های کاربر را در اسکریپت‌های شل مدیریت کرده و تجربه بهتری برای کاربران ایجاد کنید. 🚀[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”چاپ پیغام‌ها و توضیحات برای کاربر با استفاده از دستور echo” subtitle=”توضیحات کامل”]در شل اسکریپت، دستور echo برای نمایش پیام‌ها و اطلاعات در خروجی استاندارد (Terminal) استفاده می‌شود. این دستور یکی از پراستفاده‌ترین دستورات برای نمایش متن، مقدار متغیرها، و پیام‌های راهنما است.


۱. چاپ یک پیام ساده

برای نمایش یک متن ساده در خروجی، کافی است echo را به همراه متن موردنظر استفاده کنید.

🔹 مثال: نمایش یک پیام خوش‌آمدگویی

#!/bin/bash

echo "سلام! به اسکریپت ما خوش آمدید."

🔹 خروجی:

سلام! به اسکریپت ما خوش آمدید.

۲. چاپ مقدار متغیرها

می‌توان مقدار یک متغیر را در خروجی نمایش داد.

🔹 مثال: نمایش نام کاربر ذخیره‌شده در متغیر

#!/bin/bash

name="علی"
echo "سلام، $name!"

🔹 خروجی:

سلام، علی!

📌 نام متغیر با علامت $ استفاده می‌شود تا مقدار آن در خروجی نمایش داده شود.


۳. استفاده از کاراکترهای خاص و نقل‌قول‌ها

🔹 مثال: چاپ رشته با کاراکتر نقل‌قول (")

#!/bin/bash

echo "این یک متن با \"نقل‌قول\" است."

🔹 خروجی:

این یک متن با "نقل‌قول" است.

📌 برای نمایش نقل‌قول (") داخل متن، باید از بک‌اسلش \ قبل از آن استفاده کنیم.


۴. چاپ چند خطی (خط جدید در خروجی)

🔹 مثال: نمایش متن در چندین خط

#!/bin/bash

echo "این یک متن چندخطی است.
هر خط در یک خط جدید نمایش داده می‌شود."

🔹 خروجی:

این یک متن چندخطی است.
هر خط در یک خط جدید نمایش داده می‌شود.

📌 اگر متن را بین دو نقل‌قول "" قرار دهید، echo به‌صورت پیش‌فرض خط جدید را در خروجی در نظر می‌گیرد.


۵. جلوگیری از ایجاد خط جدید در خروجی

🔹 مثال: چاپ متن بدون رفتن به خط جدید با استفاده از فلگ -n

#!/bin/bash

echo -n "در حال پردازش..."
sleep 3
echo " انجام شد!"

🔹 خروجی:

در حال پردازش... انجام شد!

📌 -n باعث می‌شود که echo بدون ایجاد خط جدید، متن را در همان خط چاپ کند.


۶. استفاده از escape sequences برای قالب‌بندی متن

با استفاده از \n، \t و \e می‌توان قالب‌بندی بهتری به خروجی داد.

🔹 مثال: استفاده از \n برای ایجاد خط جدید

#!/bin/bash

echo -e "این یک خط است.\nو این یک خط جدید است."

🔹 خروجی:

این یک خط است.
و این یک خط جدید است.

📌 فلگ -e برای فعال کردن escape sequences ضروری است.

🔹 مثال: استفاده از \t برای اضافه کردن فاصله تب (Tab)

#!/bin/bash

echo -e "ستون اول\tستون دوم\tستون سوم"

🔹 خروجی:

ستون اول    ستون دوم    ستون سوم

۷. نمایش متن رنگی و استایل‌دار در ترمینال

برای نمایش متن رنگی یا دارای استایل، می‌توان از ANSI escape codes استفاده کرد.

🔹 مثال: نمایش متن قرمز و ضخیم (Bold Red)

#!/bin/bash

echo -e "\e[1;31mاین یک متن قرمز و ضخیم است!\e[0m"

🔹 خروجی:
(متن قرمز و ضخیم نمایش داده می‌شود)

📌 کد \e[1;31m باعث تغییر رنگ متن به قرمز ضخیم و \e[0m باعث بازگرداندن رنگ به حالت عادی می‌شود.

کدهای رنگی پرکاربرد:

رنگ کد ANSI
سیاه \e[30m
قرمز \e[31m
سبز \e[32m
زرد \e[33m
آبی \e[34m
بنفش \e[35m
فیروزه‌ای \e[36m
سفید \e[37m

📌 می‌توان این تکنیک را برای نمایش پیام‌های هشدار، موفقیت یا خطا استفاده کرد.


۸. استفاده از echo برای نمایش خروجی دستورات دیگر

🔹 مثال: نمایش تاریخ و زمان سیستم

#!/bin/bash

echo "تاریخ و زمان فعلی: $(date)"

🔹 خروجی:

تاریخ و زمان فعلی: Mon Feb 21 14:35:12 UTC 2025

📌 علامت $( ) خروجی دستور date را دریافت کرده و در echo نمایش می‌دهد.


۹. ذخیره خروجی echo در یک فایل

🔹 مثال: ذخیره خروجی در فایل log.txt

#!/bin/bash

echo "این یک پیام نمونه است." > log.txt

📌 این دستور مقدار “این یک پیام نمونه است.” را داخل فایل log.txt ذخیره می‌کند.

🔹 اضافه کردن پیام جدید به فایل بدون حذف محتوای قبلی:

echo "این یک پیام جدید است." >> log.txt

📌 >> باعث می‌شود که متن جدید به انتهای فایل اضافه شود، بدون حذف محتوای قبلی.


جمع‌بندی

چاپ متن ساده:

echo "سلام! به اسکریپت ما خوش آمدید."

چاپ مقدار متغیر:

echo "نام شما: $name"

چاپ بدون خط جدید:

echo -n "در حال پردازش..."

چاپ متن در چند خط:

echo -e "خط اول\nخط دوم"

چاپ متن با رنگ:

echo -e "\e[1;32mمتن سبز\e[0m"

ذخیره خروجی در فایل:

echo "این یک پیام است." > log.txt

استفاده از echo به شما کمک می‌کند تا اسکریپت‌های خود را خواناتر، کاربردی‌تر و کاربرپسندتر کنید. 🚀[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش 3. متغیرها و نوع داده‌ها در شل”][cdb_course_lesson title=”فصل 1. مبانی متغیرها در شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف متغیرها: نحوه تعریف متغیرها در اسکریپت شل” subtitle=”توضیحات کامل”]متغیرها در Shell Scripting نقش مهمی در ذخیره داده‌ها، پردازش اطلاعات، و اجرای عملیات پویا دارند. در این بخش، نحوه تعریف و استفاده از متغیرها در شل اسکریپت را با جزئیات کامل توضیح می‌دهیم.


۱. تعریف متغیر در شل

🔹 برای تعریف متغیر در Bash یا سایر شل‌ها، کافی است یک نام برای متغیر انتخاب کرده و مقدار آن را به کمک علامت = مقداردهی کنیم.

📌 نکات مهم در نام‌گذاری متغیرها:
✔ نام متغیر باید با حروف (a-z, A-Z) یا آندرلاین _ شروع شود.
✔ نمی‌توان نام متغیر را با عدد شروع کرد.
✔ از فاصله ( ) بین نام و مقدار متغیر استفاده نکنید.

🔹 مثال: تعریف یک متغیر و چاپ مقدار آن

#!/bin/bash

name="Ali"
age=25

echo "نام: $name"
echo "سن: $age"

🔹 خروجی:

نام: Ali
سن: 25

📌 برای استفاده از مقدار متغیر، باید قبل از نام آن از علامت $ استفاده کنیم.


۲. تعریف متغیرهای عددی

برخلاف برخی زبان‌های برنامه‌نویسی، شل به‌صورت پیش‌فرض تمام متغیرها را به‌عنوان رشته (String) ذخیره می‌کند. برای انجام عملیات ریاضی، باید از $(( )) یا دستور expr استفاده کرد.

🔹 مثال: انجام محاسبات عددی

#!/bin/bash

num1=10
num2=5

sum=$((num1 + num2))
product=$((num1 * num2))

echo "مجموع: $sum"
echo "حاصل‌ضرب: $product"

🔹 خروجی:

مجموع: 15
حاصل‌ضرب: 50

۳. مقداردهی به متغیر با استفاده از ورودی کاربر

گاهی اوقات نیاز داریم که مقدار متغیر را از ورودی دریافت کنیم.

🔹 مثال: گرفتن مقدار از کاربر با read

#!/bin/bash

echo "لطفاً نام خود را وارد کنید:"
read user_name

echo "سلام، $user_name! خوش آمدید."

🔹 خروجی:

لطفاً نام خود را وارد کنید:
(کاربر وارد می‌کند: محمد)
سلام، محمد! خوش آمدید.

📌 دستور read مقدار ورودی کاربر را گرفته و در متغیر ذخیره می‌کند.


۴. تعریف متغیرهای فقط-خواندنی (readonly)

اگر می‌خواهید مقدار یک متغیر تغییر نکند، می‌توانید از دستور readonly استفاده کنید.

🔹 مثال: تعریف متغیر فقط‌خواندنی

#!/bin/bash

site="example.com"
readonly site

site="newsite.com"  # این خط باعث خطا می‌شود.

🔹 خروجی:

/script.sh: line 5: site: readonly variable

۵. حذف مقدار یک متغیر با unset

🔹 مثال: حذف مقدار متغیر و بررسی آن

#!/bin/bash

var="Hello"
echo "قبل از unset: $var"

unset var

echo "بعد از unset: $var"

🔹 خروجی:

قبل از unset: Hello
بعد از unset:

📌 دستور unset مقدار متغیر را حذف می‌کند اما نام متغیر را از محیط حذف نمی‌کند.


۶. متغیرهای محیطی (Environment Variables)

متغیرهای محیطی در سیستم‌عامل لینوکس یا یونیکس ذخیره شده و می‌توانند در اسکریپت‌ها استفاده شوند.

🔹 مثال: نمایش برخی از متغیرهای محیطی مهم

#!/bin/bash

echo "نام کاربر جاری: $USER"
echo "مسیر خانه: $HOME"
echo "پوسته جاری: $SHELL"
echo "دایرکتوری فعلی: $PWD"

🔹 خروجی:

نام کاربر جاری: ali
مسیر خانه: /home/ali
پوسته جاری: /bin/bash
دایرکتوری فعلی: /home/ali/projects

📌 برخی از متغیرهای محیطی پرکاربرد:

متغیر توضیح
$USER نام کاربر جاری
$HOME مسیر دایرکتوری خانه
$PWD مسیر دایرکتوری فعلی
$SHELL پوسته جاری
$PATH مسیر جستجوی دستورات

۷. مقداردهی متغیرها با export برای استفاده در سایر اسکریپت‌ها

🔹 مثال: تعریف متغیر محیطی

#!/bin/bash

export MY_VAR="Hello World"
bash -c 'echo "مقدار MY_VAR در شل جدید: $MY_VAR"'

🔹 خروجی:

مقدار MY_VAR در شل جدید: Hello World

📌 export باعث می‌شود متغیر در سایر اسکریپت‌ها و جلسات شل قابل‌دسترسی باشد.


۸. مقداردهی پیش‌فرض در صورت مقداردهی نشدن (:-)

🔹 مثال: مقدار پیش‌فرض در صورت عدم مقداردهی

#!/bin/bash

echo "نام کاربر: ${name:-کاربر ناشناس}"

🔹 خروجی (در صورت عدم مقداردهی به name)

نام کاربر: کاربر ناشناس

۹. چک کردن مقدار متغیر (:- و :=)

🔹 مثال: مقداردهی در صورت مقداردهی نشدن

#!/bin/bash

echo "نام: ${name:=Ali}"
echo "نام: $name"

🔹 خروجی:

نام: Ali
نام: Ali

📌 اگر متغیر name مقداردهی نشده باشد، مقدار Ali را به آن اختصاص می‌دهد.


جمع‌بندی

تعریف متغیر ساده:

name="Ali"

چاپ مقدار متغیر:

echo "نام: $name"

تعریف متغیر عددی و محاسبات:

sum=$((num1 + num2))

دریافت ورودی از کاربر:

read user_input

متغیر فقط‌خواندنی:

readonly site

حذف مقدار متغیر:

unset var

متغیرهای محیطی پرکاربرد:

echo $USER $HOME $PWD

تعریف متغیر سراسری:

export MY_VAR="Hello"

مقداردهی پیش‌فرض در صورت مقداردهی نشدن:

echo ${name:-"کاربر ناشناس"}

🔹 درک مفاهیم متغیرها به شما کمک می‌کند تا اسکریپت‌های پویاتر و کارآمدتری بنویسید. 🚀[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”قوانین نام‌گذاری متغیرها: کاراکترهای مجاز و ساختار صحیح نام‌گذاری” subtitle=”توضیحات کامل”]نام‌گذاری متغیرها در Shell Scripting از قوانین مشخصی پیروی می‌کند. رعایت این قوانین باعث جلوگیری از بروز خطا و افزایش خوانایی و کارایی اسکریپت‌ها می‌شود. در این بخش، به بررسی ساختار صحیح نام‌گذاری متغیرها، کاراکترهای مجاز و نکات مهم خواهیم پرداخت.


۱. قوانین کلی نام‌گذاری متغیرها در شل

🔹 مجازات:
✔ نام متغیر باید با یک حرف (A-Z, a-z) یا آندرلاین _ شروع شود.
✔ می‌تواند شامل حروف (A-Z, a-z)، اعداد (0-9) و آندرلاین _ باشد.
نمی‌تواند با عدد شروع شود.
نباید شامل کاراکترهای ویژه مثل ! @ # $ % ^ & * - + یا فاصله باشد.

🔹 محدودیت‌ها:
❌ استفاده از کلمات رزرو شده (مانند if, then, else, fi, case, esac, for, while, do, done, function, echo, export) به‌عنوان نام متغیر مجاز نیست.
❌ استفاده از فاصله در نام متغیر غیرمجاز است.


۲. مثال‌های صحیح و غلط در نام‌گذاری متغیرها

نام‌گذاری صحیح:

name="Ali"
user_name="Mohammad"
AGE=25
_file_path="/home/user/script.sh"
VAR123="Example"

نام‌گذاری نادرست (به دلیل قوانین ذکرشده):

1var="خطا"      # شروع با عدد (اشتباه)
user-name="Ali"  # استفاده از کاراکتر غیرمجاز `-` (اشتباه)
user name="Ali"  # استفاده از فاصله (اشتباه)
@var="خطا"      # استفاده از کاراکتر `@` (اشتباه)
echo="Hello"    # استفاده از نام دستور داخلی (اشتباه)

۳. بررسی نام متغیر قبل از استفاده

🔹 برای بررسی نام متغیرها و اطمینان از مقداردهی صحیح، می‌توان از declare -p استفاده کرد.

🔹 مثال:

#!/bin/bash

name="Ali"
declare -p name

🔹 خروجی:

declare -- name="Ali"

📌 این دستور اطلاعات متغیر را نمایش می‌دهد.


۴. رعایت اصول خوانایی و بهترین روش‌های نام‌گذاری

✅ از نام‌های معنادار و گویا استفاده کنید:

user_age=30       # نام‌گذاری صحیح
var1=30           # نام‌گذاری غیرگویا (نامفهوم)

✅ برای جداسازی کلمات در نام متغیر از آندرلاین _ استفاده کنید:

server_ip="192.168.1.1"
user_email="test@example.com"

✅ نام متغیرها را ترجیحاً با حروف کوچک تعریف کنید تا با متغیرهای محیطی سیستم تداخل نداشته باشد:

file_path="/etc/config"

📌 متغیرهای محیطی سیستم معمولاً با حروف بزرگ تعریف می‌شوند (مانند $PATH, $HOME).


۵. استفاده از متغیرهای فقط‌خواندنی (readonly)

🔹 برای متغیرهایی که نباید تغییر کنند، می‌توان از readonly استفاده کرد:

#!/bin/bash

app_name="MyApp"
readonly app_name

app_name="NewApp"  # این خط باعث خطا می‌شود.

🔹 خروجی:

/script.sh: line 5: app_name: readonly variable

۶. بررسی مقدار متغیر و مقداردهی پیش‌فرض

🔹 بررسی مقدار متغیر و مقداردهی در صورت مقداردهی نشدن:

#!/bin/bash

echo "نام کاربر: ${username:-"ناشناس"}"

🔹 اگر متغیر مقداردهی نشده باشد، مقدار "ناشناس" استفاده می‌شود.


جمع‌بندی

قوانین مجاز در نام‌گذاری متغیرها:
✔ فقط از حروف، اعداد و _ استفاده کنید.
✔ با حروف یا _ شروع شود.
نباید با عدد شروع شود.
✔ از کاراکترهای ویژه و فاصله استفاده نکنید.

بهترین روش‌های نام‌گذاری:
معنادار و گویا باشد.
✔ از آندرلاین _ برای جداسازی کلمات استفاده کنید.
✔ متغیرهای محیطی را با حروف بزرگ و متغیرهای معمولی را با حروف کوچک نام‌گذاری کنید.
✔ متغیرهای حساس را readonly کنید.

🚀 رعایت این اصول باعث افزایش خوانایی و پایداری اسکریپت‌های شما می‌شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف متغیرهای پویا (Dynamic Variables) در شل” subtitle=”توضیحات کامل”]در Shell Scripting، متغیرهای پویا (Dynamic Variables) متغیرهایی هستند که نام یا مقدار آن‌ها در زمان اجرا تعیین می‌شود. این نوع متغیرها امکان تنظیم مقدار به‌صورت دینامیک را دارند و می‌توانند بر اساس ورودی‌های کاربر، مقادیر خروجی دستورات یا سایر متغیرهای اسکریپت مقداردهی شوند.


۱. تعریف متغیرهای پویا بر اساس ورودی کاربر

🔹 در بسیاری از موارد، مقدار یک متغیر بر اساس داده‌های ورودی از کاربر تعیین می‌شود.

🔹 مثال: دریافت نام کاربر و مقداردهی متغیر به‌صورت پویا

#!/bin/bash

echo "لطفا نام خود را وارد کنید:"
read user_name  # مقدار متغیر user_name از ورودی دریافت می‌شود.

echo "سلام $user_name، به شل اسکریپت خوش آمدید!"

🔹 اجرای اسکریپت و ورودی کاربر:

لطفا نام خود را وارد کنید:
Ali
سلام Ali، به شل اسکریپت خوش آمدید!

📌 متغیر $user_name در زمان اجرا مقداردهی شده و در خروجی استفاده شده است.


۲. مقداردهی پویا با استفاده از مقدار خروجی دستورات

🔹 مقدار یک متغیر را می‌توان بر اساس خروجی یک دستور مقداردهی کرد.

🔹 مثال: دریافت نام کاربر لاگین‌شده و مقداردهی متغیر

#!/bin/bash

current_user=$(whoami)  # مقدار متغیر از خروجی دستور `whoami` گرفته می‌شود.

echo "شما به عنوان $current_user وارد شده‌اید."

🔹 خروجی (مثال):

شما به عنوان ali وارد شده‌اید.

📌 این روش در مواردی مانند خواندن اطلاعات سیستم، مقداردهی پویا به متغیرها و پردازش خودکار داده‌ها بسیار مفید است.


۳. ایجاد نام متغیر پویا (Indirect Referencing)

🔹 در شل می‌توان نام یک متغیر را به‌صورت پویا تعیین و مقداردهی کرد.

🔹 مثال: مقداردهی غیرمستقیم با استفاده از eval

#!/bin/bash

var_name="user_age"
eval "$var_name=30"  # مقدار متغیر user_age به 30 تنظیم می‌شود.

echo "مقدار متغیر پویا: $user_age"

🔹 خروجی:

مقدار متغیر پویا: 30

📌 این تکنیک در برنامه‌های انعطاف‌پذیر که نیاز به مقداردهی پویا دارند، کاربردی است.


۴. استفاده از declare برای متغیرهای پویا

🔹 با دستور declare می‌توان متغیرها را به‌صورت پویا مقداردهی کرد.

🔹 مثال:

#!/bin/bash

var_name="my_var"
declare "$var_name=Hello"

echo "مقدار متغیر پویا: ${!var_name}"

🔹 خروجی:

مقدار متغیر پویا: Hello

📌 در این مثال، نام متغیر به‌صورت دینامیک ساخته شده و مقدار آن تنظیم شده است.


۵. بررسی مقدار متغیر قبل از مقداردهی

🔹 می‌توان مقدار متغیر را بررسی کرده و در صورت عدم مقداردهی، مقدار پیش‌فرض تعیین کرد.

🔹 مثال:

#!/bin/bash

echo "لطفا نام کاربر را وارد کنید (اگر خالی بگذارید، مقدار پیش‌فرض 'Guest' تنظیم می‌شود):"
read username

username=${username:-"Guest"}  # مقداردهی پیش‌فرض در صورت خالی بودن ورودی

echo "سلام $username!"

🔹 اجرای اسکریپت (بدون ورودی):

لطفا نام کاربر را وارد کنید (اگر خالی بگذارید، مقدار پیش‌فرض 'Guest' تنظیم می‌شود):

سلام Guest!

📌 این روش برای مدیریت ورودی‌های خالی و تنظیم مقادیر پیش‌فرض در اسکریپت‌ها مفید است.


جمع‌بندی

✅ متغیرهای پویا در شل اسکریپت متغیرهایی هستند که مقدار یا نام آن‌ها در زمان اجرا تعیین می‌شود.
✅ مقداردهی پویا می‌تواند از ورودی کاربر، خروجی دستورات، مقداردهی غیرمستقیم یا متغیرهای از پیش تعیین‌شده انجام شود.
✅ برای مقداردهی پویا می‌توان از read برای دریافت ورودی، $() برای اجرای دستورات، eval و declare برای مقداردهی غیرمستقیم استفاده کرد.
✅ در صورت نیاز به مقدار پیش‌فرض برای متغیرهای پویا، می‌توان از ${variable:-default_value} استفاده کرد.

🚀 استفاده از متغیرهای پویا باعث افزایش انعطاف‌پذیری و کارایی اسکریپت‌ها می‌شود![/cdb_course_lesson][cdb_course_lesson title=”فصل 2. استفاده از متغیرها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مقداردهی به متغیرها: مثال‌های ساده و پیشرفته” subtitle=”توضیحات کامل”]در Shell Scripting، مقداردهی به متغیرها بخش مهمی از پردازش داده‌ها است. می‌توان متغیرها را به روش‌های مختلف مقداردهی کرد، از مقداردهی مستقیم گرفته تا استفاده از مقادیر خروجی دستورات. در این بخش، چندین روش ساده و پیشرفته برای مقداردهی متغیرها را بررسی می‌کنیم.


۱. مقداردهی ساده به متغیرها

🔹 مقداردهی به متغیرها در شل اسکریپت به شکل زیر انجام می‌شود:

variable_name=value

نکات مهم:

  • بین نام متغیر و مقدار آن نباید فاصله باشد.
  • متغیرها به‌طور پیش‌فرض حساس به حروف بزرگ و کوچک هستند.
  • برای دسترسی به مقدار متغیر، از علامت $ قبل از نام متغیر استفاده می‌شود.

🔹 مثال:

#!/bin/bash

name="Ali"
age=25
city="Tehran"

echo "نام: $name"
echo "سن: $age"
echo "شهر: $city"

🔹 خروجی:

نام: Ali
سن: 25
شهر: Tehran

۲. مقداردهی عددی و عملیات ریاضی

🔹 در Bash، متغیرهای عددی را نمی‌توان مستقیماً به‌عنوان عدد صحیح در نظر گرفت. برای انجام عملیات ریاضی، باید از $(()) یا expr استفاده کرد.

🔹 مثال: انجام عملیات ریاضی

#!/bin/bash

num1=10
num2=5

sum=$((num1 + num2))
diff=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))

echo "جمع: $sum"
echo "تفاضل: $diff"
echo "ضرب: $product"
echo "تقسیم: $quotient"

🔹 خروجی:

جمع: 15
تفاضل: 5
ضرب: 50
تقسیم: 2

📌 برای محاسبات پیچیده‌تر می‌توان از ابزار bc استفاده کرد.

🔹 مثال: محاسبات اعشاری

#!/bin/bash

result=$(echo "scale=2; 10 / 3" | bc)
echo "نتیجه تقسیم: $result"

🔹 خروجی:

نتیجه تقسیم: 3.33

۳. مقداردهی با استفاده از ورودی کاربر (read)

🔹 می‌توان مقدار متغیر را در زمان اجرا از کاربر دریافت کرد.

🔹 مثال: دریافت مقدار از ورودی

#!/bin/bash

echo "لطفاً نام خود را وارد کنید:"
read user_name

echo "سلام $user_name، خوش آمدید!"

🔹 ورودی و خروجی:

لطفاً نام خود را وارد کنید:
Reza
سلام Reza، خوش آمدید!

📌 read به‌طور پیش‌فرض مقدار ورودی را در متغیر مشخص‌شده ذخیره می‌کند.


۴. مقداردهی با استفاده از مقدار خروجی دستورات

🔹 می‌توان مقدار یک متغیر را بر اساس خروجی یک دستور تنظیم کرد.

🔹 مثال: ذخیره نام کاربری لاگین‌شده

#!/bin/bash

current_user=$(whoami)
current_date=$(date +%Y-%m-%d)

echo "کاربر فعلی: $current_user"
echo "تاریخ امروز: $current_date"

🔹 خروجی (نمونه):

کاربر فعلی: ali
تاریخ امروز: 2025-02-21

📌 برای مقداردهی بر اساس دستورات خارجی از $(command) یا `command` استفاده می‌شود.


۵. مقداردهی شرطی (Default Values)

🔹 می‌توان مقدار یک متغیر را در صورت خالی بودن، مقدار پیش‌فرض داد.

🔹 مثال: مقدار پیش‌فرض در صورت خالی بودن ورودی

#!/bin/bash

echo "نام خود را وارد کنید (یا Enter بزنید تا مقدار پیش‌فرض تنظیم شود):"
read username

username=${username:-"کاربر ناشناس"}

echo "سلام $username!"

🔹 ورودی و خروجی:

نام خود را وارد کنید (یا Enter بزنید تا مقدار پیش‌فرض تنظیم شود):

سلام کاربر ناشناس!

📌 ${variable:-default_value} مقدار پیش‌فرض تعیین می‌کند.


۶. مقداردهی به چندین متغیر هم‌زمان

🔹 می‌توان چندین متغیر را در یک خط مقداردهی کرد.

🔹 مثال:

#!/bin/bash

name="Ali" age=25 city="Mashhad"

echo "نام: $name، سن: $age، شهر: $city"

🔹 خروجی:

نام: Ali، سن: 25، شهر: Mashhad

📌 بین مقداردهی‌ها فاصله نباید باشد، مگر اینکه از ; برای جدا کردن استفاده کنیم.


۷. مقداردهی غیرمستقیم (Indirect Referencing)

🔹 در برخی موارد، نام متغیر می‌تواند به‌صورت پویا تعیین شود.

🔹 مثال: مقداردهی غیرمستقیم

#!/bin/bash

var_name="my_var"
declare "$var_name=Hello"

echo "مقدار متغیر پویا: ${!var_name}"

🔹 خروجی:

مقدار متغیر پویا: Hello

📌 ${!var_name} مقدار متغیری که نام آن در $var_name ذخیره شده را نمایش می‌دهد.


۸. مقداردهی به متغیرهای فقط خواندنی (readonly)

🔹 برای ایجاد متغیرهایی که مقدار آن‌ها تغییر نکند، از readonly استفاده می‌شود.

🔹 مثال:

#!/bin/bash

readonly pi=3.14
echo "مقدار عدد پی: $pi"

pi=3.14159  # این دستور باعث خطا خواهد شد.

🔹 خروجی:

مقدار عدد پی: 3.14
script.sh: خطا: نمی‌توان مقدار readonly متغیر 'pi' را تغییر داد

📌 این روش برای متغیرهای ثابت و حیاتی در اسکریپت مفید است.


جمع‌بندی

✅ مقداردهی به متغیرها در Bash را می‌توان به روش‌های مختلفی انجام داد:

  • مقداردهی مستقیم (var=value)
  • مقداردهی عددی و محاسبات ریاضی ($((expression)))
  • مقداردهی از طریق ورودی کاربر (read var)
  • مقداردهی از خروجی دستورات ($(command))
  • مقدار پیش‌فرض (${var:-default_value})
  • مقداردهی غیرمستقیم (declare و ${!var})
  • مقداردهی به متغیرهای فقط خواندنی (readonly var=value)

🚀 درک صحیح این روش‌ها باعث افزایش انعطاف‌پذیری اسکریپت‌های شما می‌شود![/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”دسترسی به مقدار متغیرها با $” subtitle=”توضیحات کامل”]در Bash Scripting، برای دسترسی به مقدار متغیرها از علامت $ قبل از نام متغیر استفاده می‌شود. این روش به شما امکان می‌دهد مقدار ذخیره‌شده در یک متغیر را در اسکریپت خود بخوانید و استفاده کنید. در این بخش، روش‌های مختلف دسترسی به مقدار متغیرها را بررسی می‌کنیم.


۱. دسترسی ساده به مقدار متغیر

🔹 برای نمایش مقدار یک متغیر، کافی است از علامت $ قبل از نام آن استفاده کنید.

🔹 مثال:

#!/bin/bash

name="Ali"
age=30

echo "نام: $name"
echo "سن: $age"

🔹 خروجی:

نام: Ali
سن: 30

✅ مقدار Ali و 30 که به متغیرها داده شده بود، با $name و $age نمایش داده شد.


۲. استفاده از {} برای دسترسی ایمن به متغیرها

🔹 اگر بخواهیم متغیری را در کنار یک متن دیگر استفاده کنیم، ممکن است شل مقدار متغیر را اشتباه تشخیص دهد. در این مواقع، از ${} برای تعیین دقیق نام متغیر استفاده می‌شود.

🔹 مثال:

#!/bin/bash

file="document"
echo "نام فایل: ${file}.txt"

🔹 خروجی:

نام فایل: document.txt

✅ اگر بدون {} نوشته شود ($file.txt)، شل سعی می‌کند متغیری به نام file.txt را پیدا کند که وجود ندارد.


۳. دسترسی به مقدار متغیرهای سیستم

🔹 Bash شامل برخی متغیرهای محیطی (System Variables) است که می‌توان مقدار آن‌ها را با $ دریافت کرد.

🔹 مثال:

#!/bin/bash

echo "نام کاربر: $USER"
echo "دایرکتوری فعلی: $PWD"
echo "سیستم‌عامل: $OSTYPE"

🔹 خروجی (نمونه):

نام کاربر: ali
دایرکتوری فعلی: /home/ali
سیستم‌عامل: linux-gnu

متغیرهای محیطی رایج:

  • $USER → نام کاربری
  • $PWD → مسیر دایرکتوری فعلی
  • $HOME → مسیر دایرکتوری خانه کاربر
  • $SHELL → مسیر شل فعال
  • $OSTYPE → نوع سیستم‌عامل

۴. دسترسی به متغیرهای دریافت‌شده از ورودی کاربر

🔹 اگر از read برای گرفتن ورودی استفاده کنیم، مقدار متغیر را با $ می‌توان دریافت کرد.

🔹 مثال:

#!/bin/bash

echo "لطفاً نام خود را وارد کنید:"
read username

echo "سلام $username، خوش آمدید!"

🔹 ورودی و خروجی:

لطفاً نام خود را وارد کنید:
Reza
سلام Reza، خوش آمدید!

۵. استفاده از مقدار متغیرها در دستورات

🔹 می‌توان مقدار متغیرها را در دستورات لینوکس به کار برد.

🔹 مثال: ذخیره مسیر دایرکتوری و تغییر مسیر

#!/bin/bash

dir="/etc"
cd $dir
echo "شما در مسیر $(pwd) هستید."

🔹 خروجی:

شما در مسیر /etc هستید.

✅ مقدار متغیر $dir در دستور cd استفاده شد.


۶. مقداردهی شرطی (Default Values) هنگام دسترسی

🔹 می‌توان هنگام خواندن مقدار یک متغیر، در صورتی که مقدار آن تعریف نشده باشد، یک مقدار پیش‌فرض به آن اختصاص داد.

🔹 مثال:

#!/bin/bash

echo "نام کاربر: ${username:-"کاربر ناشناس"}"

🔹 ورودی و خروجی:

نام کاربر: کاربر ناشناس

✅ اگر متغیر username مقدار نداشته باشد، مقدار "کاربر ناشناس" نمایش داده می‌شود.


۷. خواندن مقدار متغیرهای پویا (Indirect Referencing)

🔹 گاهی نام متغیر در یک متغیر دیگر ذخیره شده است. برای دسترسی به مقدار آن، از ${!} استفاده می‌شود.

🔹 مثال:

#!/bin/bash

var_name="greeting"
greeting="Hello, World!"

echo "مقدار greeting: ${!var_name}"

🔹 خروجی:

مقدار greeting: Hello, World!

${!var_name} مقدار متغیری که نام آن در var_name ذخیره شده است را نمایش می‌دهد.


۸. استخراج بخش خاصی از مقدار متغیر

🔹 می‌توان بخش خاصی از مقدار یک متغیر را استخراج کرد.

🔹 مثال: دریافت ۳ کاراکتر اول مقدار متغیر

#!/bin/bash

text="BashScripting"
echo "سه کاراکتر اول: ${text:0:3}"

🔹 خروجی:

سه کاراکتر اول: Bas

فرمت:

${variable:offset:length}
  • offset → شروع از چندمین کاراکتر
  • length → تعداد کاراکترها

جمع‌بندی

✅ در Bash Scripting، برای دسترسی به مقدار متغیرها از $ استفاده می‌شود.
✅ برای جلوگیری از مشکلات نام‌گذاری، می‌توان از ${} استفاده کرد.
✅ مقدار متغیرهای محیطی مانند $USER، $PWD و $HOME قابل دریافت است.
✅ مقدار متغیرها را می‌توان در دستورات لینوکس به کار برد.
✅ در صورت نیاز، می‌توان مقدار پیش‌فرض برای متغیرها تعیین کرد.
✅ با ${!variable} می‌توان مقدار متغیرهای پویا را خواند.
✅ می‌توان بخش خاصی از مقدار متغیرها را استخراج کرد.

🚀 تسلط بر این روش‌ها باعث افزایش انعطاف‌پذیری اسکریپت‌های شما خواهد شد![/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تغییر مقادیر متغیرها و تأثیر آن در برنامه” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، متغیرها مقدار خود را در طول اجرای برنامه ذخیره می‌کنند، اما در صورت نیاز می‌توان مقدار آن‌ها را تغییر داد. این قابلیت به شما این امکان را می‌دهد که برنامه‌های پویا و انعطاف‌پذیرتری ایجاد کنید. در این بخش، روش‌های مختلف تغییر مقدار متغیرها و تأثیر آن در اجرای برنامه را بررسی می‌کنیم.


۱. تغییر مقدار متغیرها در حین اجرای برنامه

🔹 در Bash، مقدار متغیرها را می‌توان در طول اجرای اسکریپت تغییر داد. کافی است نام متغیر را دوباره مقداردهی کنیم.

🔹 مثال:

#!/bin/bash

counter=1
echo "مقدار اولیه: $counter"

counter=5
echo "مقدار جدید: $counter"

🔹 خروجی:

مقدار اولیه: 1  
مقدار جدید: 5  

✅ مقدار متغیر counter از 1 به 5 تغییر کرد.


۲. تغییر مقدار متغیرها با استفاده از ورودی کاربر

🔹 مقدار یک متغیر می‌تواند بر اساس ورودی کاربر تغییر کند.

🔹 مثال:

#!/bin/bash

echo "لطفاً نام خود را وارد کنید:"
read username

echo "سلام $username، خوش آمدید!"
username="کاربر جدید"
echo "نام تغییر یافت به: $username"

🔹 ورودی و خروجی:

لطفاً نام خود را وارد کنید:  
Ali  
سلام Ali، خوش آمدید!  
نام تغییر یافت به: کاربر جدید  

✅ مقدار username ابتدا از ورودی کاربر دریافت شد و سپس تغییر کرد.


۳. مقداردهی مجدد متغیرها درون یک حلقه

🔹 مقدار متغیرها را می‌توان درون یک حلقه تغییر داد.

🔹 مثال: شمارش از ۱ تا ۵

#!/bin/bash

counter=1
while [ $counter -le 5 ]
do
    echo "مقدار فعلی: $counter"
    counter=$((counter + 1))
done

🔹 خروجی:

مقدار فعلی: 1  
مقدار فعلی: 2  
مقدار فعلی: 3  
مقدار فعلی: 4  
مقدار فعلی: 5  

✅ مقدار counter در هر دور حلقه افزایش یافت.


۴. تغییر مقدار متغیرها با عملیات ریاضی

🔹 مقدار متغیرهای عددی را می‌توان با انجام عملیات ریاضی تغییر داد.

🔹 مثال:

#!/bin/bash

num=10
echo "مقدار اولیه: $num"

num=$((num + 5))
echo "بعد از جمع: $num"

num=$((num * 2))
echo "بعد از ضرب: $num"

🔹 خروجی:

مقدار اولیه: 10  
بعد از جمع: 15  
بعد از ضرب: 30  

✅ مقدار num ابتدا 5 واحد افزایش یافت و سپس در 2 ضرب شد.


۵. تأثیر تغییر مقدار متغیرها در شرط‌ها

🔹 مقدار متغیرها مستقیماً روی تصمیم‌گیری‌های برنامه تأثیر می‌گذارد.

🔹 مثال: بررسی مقدار متغیر

#!/bin/bash

score=75
echo "نمره شما: $score"

if [ $score -ge 60 ]; then
    echo "شما قبول شدید."
else
    echo "متأسفانه مردود شدید."
fi

🔹 خروجی:

نمره شما: 75  
شما قبول شدید.  

✅ مقدار score در شرط بررسی شد و مسیر اجرای برنامه مشخص گردید.


۶. تأثیر تغییر مقدار متغیرهای محیطی

🔹 متغیرهای محیطی مانند $PATH، $USER و $HOME در عملکرد سیستم تأثیر دارند. تغییر مقدار آن‌ها ممکن است رفتار سیستم را تغییر دهد.

🔹 مثال: تغییر مقدار PATH

#!/bin/bash

echo "مقدار اولیه PATH: $PATH"
export PATH="/usr/local/bin:$PATH"
echo "مقدار جدید PATH: $PATH"

✅ تغییر مقدار $PATH می‌تواند مسیرهای جدیدی را برای اجرای دستورات اضافه کند.


۷. تغییر مقدار متغیرها در اسکریپت‌های فرزند (Subshells)

🔹 اگر متغیری در یک Subshell مقداردهی شود، مقدار آن فقط در همان Subshell معتبر خواهد بود.

🔹 مثال:

#!/bin/bash

var="اصلی"
echo "قبل از Subshell: $var"

( var="تغییر در Subshell"; echo "داخل Subshell: $var" )

echo "بعد از Subshell: $var"

🔹 خروجی:

قبل از Subshell: اصلی  
داخل Subshell: تغییر در Subshell  
بعد از Subshell: اصلی  

✅ تغییر مقدار متغیر درون () فقط در همان Subshell اعمال شد و مقدار اصلی تغییری نکرد.


جمع‌بندی

✅ مقدار متغیرها را می‌توان در طول اجرای برنامه تغییر داد.
✅ مقادیر می‌توانند از ورودی کاربر دریافت شده و سپس تغییر کنند.
✅ متغیرها در حلقه‌ها و عملیات ریاضی تغییر می‌کنند.
✅ تغییر مقدار متغیرها بر شرط‌ها و جریان اجرای برنامه تأثیر می‌گذارد.
✅ تغییر متغیرهای محیطی می‌تواند روی کل سیستم تأثیر بگذارد.
✅ تغییر مقدار متغیرها در Subshells فقط در همان Subshell معتبر است.

🚀 مدیریت صحیح تغییر مقدار متغیرها باعث ایجاد اسکریپت‌های بهینه و قابل اطمینان خواهد شد![/cdb_course_lesson][cdb_course_lesson title=”فصل 3. انواع متغیرها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”متغیرهای محلی (Local Variables): تعریف و محدودیت‌های آن‌ها” subtitle=”توضیحات کامل”]در Bash و سایر شل‌ها، متغیرهای محلی (Local Variables) نوعی متغیر هستند که دامنه‌ی اثر آن‌ها محدود به یک تابع خاص است و نمی‌توان از آن‌ها خارج از آن تابع استفاده کرد. استفاده از متغیرهای محلی باعث می‌شود که کد تمیزتر، ساختاریافته‌تر و بدون تداخل با سایر بخش‌های اسکریپت اجرا شود. در این بخش، تعریف، نحوه استفاده و محدودیت‌های متغیرهای محلی را بررسی خواهیم کرد.


۱. تعریف متغیر محلی در Bash

🔹 در Bash، برای تعریف متغیرهای محلی از کلمه کلیدی local درون یک تابع استفاده می‌شود.

🔹 نحوه تعریف:

local variable_name="value"

📌 اگر local استفاده نشود، متغیر به‌صورت سراسری (Global) تعریف می‌شود و در کل اسکریپت در دسترس خواهد بود.


۲. مثال ساده از متغیرهای محلی

🔹 در این مثال، متغیر name فقط درون تابع greet تعریف شده و مقدار آن در خارج از تابع در دسترس نیست.

#!/bin/bash

greet() {
    local name="Ali"
    echo "سلام، $name!"
}

greet

# تلاش برای دسترسی به متغیر محلی در خارج از تابع
echo "نام در خارج از تابع: $name"

🔹 خروجی:

سلام، Ali!  
نام در خارج از تابع:  

✅ مقدار name فقط در داخل تابع greet در دسترس است و در خارج از تابع مقداردهی نشده است.


۳. تفاوت بین متغیرهای محلی و سراسری

🔹 اگر متغیر را بدون local تعریف کنیم، مقدار آن در کل اسکریپت باقی می‌ماند.

🔹 مثال:

#!/bin/bash

name="Sina"  # متغیر سراسری

greet() {
    name="Ali"  # مقداردهی مجدد متغیر سراسری
    echo "سلام، $name!"
}

echo "قبل از فراخوانی تابع: $name"
greet
echo "بعد از فراخوانی تابع: $name"

🔹 خروجی:

قبل از فراخوانی تابع: Sina  
سلام، Ali!  
بعد از فراخوانی تابع: Ali  

✅ مقدار name در تابع تغییر کرد و این تغییر روی مقدار اصلی تأثیر گذاشت.

🔹 حالا اگر local استفاده کنیم:

#!/bin/bash

name="Sina"  # متغیر سراسری

greet() {
    local name="Ali"  # متغیر محلی
    echo "سلام، $name!"
}

echo "قبل از فراخوانی تابع: $name"
greet
echo "بعد از فراخوانی تابع: $name"

🔹 خروجی:

قبل از فراخوانی تابع: Sina  
سلام، Ali!  
بعد از فراخوانی تابع: Sina  

✅ مقدار name داخل تابع تغییر کرد، اما مقدار متغیر سراسری دست‌نخورده باقی ماند.


۴. محدودیت‌های متغیرهای محلی

🔹 ۱. فقط درون تابع قابل تعریف هستند
📌 نمی‌توان از local در سطح کلی اسکریپت استفاده کرد.

🔹 ۲. در بیرون از تابع در دسترس نیستند
📌 دسترسی به متغیر محلی بعد از اجرای تابع امکان‌پذیر نیست.

🔹 ۳. محدود به تابع والد هستند
📌 اگر تابعی درون تابع دیگر تعریف شود، متغیر محلی فقط در همان تابع والد معتبر است.

🔹 مثال:

#!/bin/bash

outer_function() {
    local var="درون تابع خارجی"

    inner_function() {
        echo "متغیر درون تابع داخلی: $var"
    }

    inner_function
}

outer_function
# این دستور خطا می‌دهد چون متغیر var محلی است
echo "متغیر خارج از تابع: $var"

🔹 خروجی:

متغیر درون تابع داخلی: درون تابع خارجی  
متغیر خارج از تابع:  

✅ مقدار var فقط در outer_function معتبر است و در خارج از تابع مقداردهی نشده است.


۵. استفاده از متغیرهای محلی برای جلوگیری از تداخل

🔹 بدون متغیر محلی:

#!/bin/bash

count=10

increment() {
    count=$((count + 1))
}

echo "قبل از افزایش: $count"
increment
echo "بعد از افزایش: $count"

🔹 خروجی:

قبل از افزایش: 10  
بعد از افزایش: 11  

✅ مقدار count در کل اسکریپت تغییر کرد.

🔹 با استفاده از local (عدم تأثیر روی مقدار اصلی):

#!/bin/bash

count=10

increment() {
    local count=0
    count=$((count + 1))
    echo "مقدار داخل تابع: $count"
}

echo "قبل از افزایش: $count"
increment
echo "بعد از افزایش: $count"

🔹 خروجی:

قبل از افزایش: 10  
مقدار داخل تابع: 1  
بعد از افزایش: 10  

✅ مقدار count درون تابع تغییر کرد، اما مقدار متغیر اصلی بدون تغییر باقی ماند.


جمع‌بندی

متغیرهای محلی فقط در محدوده تابع تعریف و استفاده می‌شوند.
برای تعریف متغیر محلی از local استفاده می‌شود.
متغیرهای محلی از تداخل با سایر بخش‌های برنامه جلوگیری می‌کنند.
متغیرهای محلی را نمی‌توان در سطح اسکریپت تعریف کرد، فقط داخل توابع.
محدودیت متغیرهای محلی باعث کاهش مشکلات ناخواسته در مقداردهی متغیرها می‌شود.

🚀 استفاده‌ی هوشمندانه از متغیرهای محلی، اسکریپت‌های Bash را کارآمدتر و ساختاریافته‌تر می‌کند![/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”متغیرهای محیطی (Environment Variables): متغیرهای سیستم و نحوه استفاده از آن‌ها” subtitle=”توضیحات کامل”]متغیرهای محیطی در سیستم‌عامل لینوکس و یونیکس نقش مهمی در ذخیره و مدیریت اطلاعات سیستم، پیکربندی برنامه‌ها و مدیریت پردازش‌ها دارند. این متغیرها به‌صورت سراسری (Global) در دسترس هستند و می‌توان از آن‌ها در اسکریپت‌های شل، دستورات ترمینال و برنامه‌های مختلف استفاده کرد.

در این بخش، تعریف متغیرهای محیطی، نحوه مشاهده، مقداردهی، تغییر و حذف آن‌ها را همراه با مثال‌های عملی بررسی خواهیم کرد.


۱. متغیر محیطی چیست؟

🔹 متغیرهای محیطی متغیرهایی هستند که در سطح سیستم تعریف شده و در اختیار تمامی پردازش‌ها قرار می‌گیرند.
🔹 این متغیرها برای مدیریت مسیرهای سیستم، تنظیمات زبان، مسیر کاربران و تنظیمات مهم دیگر استفاده می‌شوند.
🔹 برخی از متغیرهای محیطی توسط سیستم‌عامل تعریف می‌شوند، اما می‌توان متغیرهای جدیدی نیز اضافه کرد.


۲. مشاهده متغیرهای محیطی

🔹 دستور printenv یا env برای نمایش متغیرهای محیطی

printenv

یا

env

🔹 دستور echo برای نمایش مقدار یک متغیر خاص

echo $HOME
echo $USER
echo $PATH

📌 نمونه‌ای از خروجی:

/home/ali
ali
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

۳. متغیرهای محیطی مهم در سیستم لینوکس

برخی از متغیرهای از پیش تعریف‌شده در لینوکس:

متغیر محیطی توضیح
$HOME مسیر دایرکتوری خانه‌ی کاربر فعلی
$USER نام کاربر فعلی
$PATH مسیرهای جستجو برای اجرای برنامه‌ها
$SHELL مسیر شل پیش‌فرض کاربر
$PWD مسیر فعلی (Current Directory)
$LANG تنظیمات زبان سیستم
$EDITOR ویرایشگر پیش‌فرض متنی (مثلاً vim یا nano)
$LOGNAME نام کاربر ورود‌ی
$HOSTNAME نام میزبان سیستم
$TERM نوع ترمینال فعال
$UID شناسه کاربر فعلی

🔹 مثال: مشاهده مسیر bash شل پیش‌فرض

echo $SHELL

🔹 مثال: بررسی مسیر جستجوی فایل‌های اجرایی

echo $PATH

۴. تعریف و مقداردهی به متغیرهای محیطی

🔹 متغیر محیطی جدید ایجاد کنید:

export MYVAR="Hello, Linux!"

🔹 مشاهده مقدار متغیر:

echo $MYVAR

🔹 متغیر محیطی فقط در همان نشست (Session) معتبر است و بعد از بستن ترمینال از بین می‌رود.


۵. تغییر مقدار متغیرهای محیطی

🔹 مثلاً تغییر مسیر ویرایشگر پیش‌فرض:

export EDITOR=nano

🔹 مشاهده مقدار جدید:

echo $EDITOR

۶. حذف متغیر محیطی

🔹 برای حذف یک متغیر محیطی از unset استفاده کنید:

unset MYVAR

🔹 تست حذف متغیر:

echo $MYVAR  # خروجی خالی خواهد بود

۷. افزودن متغیرهای محیطی به‌صورت دائمی

🔹 متغیرهای تعریف‌شده با export فقط در همان نشست ترمینال معتبر هستند و پس از راه‌اندازی مجدد سیستم از بین می‌روند.

🔹 برای ثبت دائمی، مقداردهی متغیرها را در فایل‌های پیکربندی شل قرار دهید:
✅ برای Bash متغیر را در ~/.bashrc یا ~/.bash_profile اضافه کنید:

echo 'export MYVAR="Hello, Linux!"' >> ~/.bashrc

✅ برای Zsh در ~/.zshrc قرار دهید:

echo 'export MYVAR="Hello, Zsh!"' >> ~/.zshrc

🔹 اعمال تغییرات بدون نیاز به ری‌استارت:

source ~/.bashrc  # برای Bash
source ~/.zshrc   # برای Zsh

🔹 بررسی مقدار جدید:

echo $MYVAR

۸. استفاده از متغیرهای محیطی در اسکریپت‌ها

🔹 متغیرهای محیطی را می‌توان در اسکریپت‌های شل استفاده کرد.

مثال: ذخیره یک متغیر و استفاده از آن در یک اسکریپت

#!/bin/bash

echo "کاربر فعلی: $USER"
echo "مسیر فعلی: $PWD"
echo "زبان سیستم: $LANG"

اجرای اسکریپت:

chmod +x script.sh
./script.sh

📌 نمونه خروجی:

کاربر فعلی: ali
مسیر فعلی: /home/ali
زبان سیستم: en_US.UTF-8

جمع‌بندی

متغیرهای محیطی در لینوکس برای ذخیره اطلاعات سیستم و پیکربندی پردازش‌ها استفاده می‌شوند.
برای مشاهده متغیرهای محیطی از printenv یا env و برای نمایش مقدار خاص از echo $VAR استفاده می‌شود.
با export VAR="value" می‌توان متغیرهای محیطی جدید تعریف کرد، اما این تغییرات در نشست فعلی معتبر هستند.
برای ثبت دائمی، مقداردهی متغیرها را در ~/.bashrc یا ~/.bash_profile اضافه کنید.
از unset VAR برای حذف متغیرهای محیطی استفاده می‌شود.
متغیرهای محیطی در اسکریپت‌های شل برای مدیریت تنظیمات و اطلاعات سیستم بسیار مفید هستند.

🚀 با درک و مدیریت صحیح متغیرهای محیطی، اسکریپت‌های Bash قوی‌تر و پویاتری بنویسید![/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”متغیرهای تعریف‌شده توسط کاربر: مقایسه با متغیرهای پیش‌فرض سیستم” subtitle=”توضیحات کامل”]در لینوکس و سیستم‌های یونیکس، متغیرها نقش مهمی در مدیریت داده‌ها، ذخیره اطلاعات و تنظیم پیکربندی‌ها دارند. به‌طور کلی، متغیرها در دو دسته اصلی قرار می‌گیرند:

  1. متغیرهای پیش‌فرض سیستم (System Variables): متغیرهایی که توسط سیستم‌عامل تعریف شده‌اند و اطلاعات مهمی مانند نام کاربر، مسیرهای سیستم و تنظیمات محیطی را ذخیره می‌کنند.
  2. متغیرهای تعریف‌شده توسط کاربر (User-Defined Variables): متغیرهایی که کاربران به‌صورت دستی برای ذخیره مقادیر خاص در اسکریپت‌ها و جلسات ترمینال تعریف می‌کنند.

در این بخش، این دو نوع متغیر را بررسی کرده و تفاوت‌های آن‌ها را با مثال‌های عملی توضیح می‌دهیم.


۱. متغیرهای پیش‌فرض سیستم (System Variables)

🔹 این متغیرها هنگام راه‌اندازی سیستم به‌طور خودکار مقداردهی می‌شوند و برای تنظیمات عمومی استفاده می‌شوند.
🔹 متغیرهای سیستم معمولاً با حروف بزرگ نوشته می‌شوند.
🔹 مثال‌هایی از متغیرهای محیطی سیستم:

متغیر توضیح
$HOME مسیر دایرکتوری خانه کاربر فعلی
$USER نام کاربری فعلی
$PATH مسیرهای جستجوی دستورات اجرایی
$SHELL مسیر شل پیش‌فرض
$PWD مسیر فعلی
$LANG تنظیمات زبان سیستم
$EDITOR ویرایشگر متنی پیش‌فرض
$HOSTNAME نام میزبان سیستم

🔹 مشاهده مقدار متغیرهای سیستم:

echo $USER
echo $HOME
echo $SHELL

📌 خروجی نمونه:

ali
/home/ali
/bin/bash

۲. متغیرهای تعریف‌شده توسط کاربر (User-Defined Variables)

🔹 این متغیرها توسط کاربر برای ذخیره مقادیر سفارشی در طول یک نشست (Session) یا درون یک اسکریپت تعریف می‌شوند.
🔹 برخلاف متغیرهای سیستم، این متغیرها معمولاً با حروف کوچک یا ترکیبی از حروف بزرگ و کوچک نوشته می‌شوند.
🔹 برای مقداردهی به متغیرهای کاربر نیازی به $ نیست، اما برای استفاده از مقدار آن‌ها باید از $ استفاده کرد.

تعریف یک متغیر و مقداردهی به آن:

myname="Ali"
myage=25
city="Tehran"

مشاهده مقدار متغیر:

echo $myname
echo $myage
echo $city

📌 خروجی:

Ali
25
Tehran

۳. تفاوت‌های کلیدی بین متغیرهای سیستم و متغیرهای کاربر

ویژگی متغیرهای سیستم متغیرهای کاربر
تعریف‌شده توسط سیستم‌عامل کاربر
نام‌گذاری معمولاً حروف بزرگ معمولاً حروف کوچک
دسترسی در تمام پردازش‌ها و نشست‌ها قابل‌دسترسی است معمولاً فقط در نشست فعلی معتبر است
محدوده اعتبار سراسری (Global) محلی (Local) مگر اینکه با export سراسری شود
نحوه مشاهده مقدار echo $VAR_NAME یا printenv VAR_NAME echo $varname
نحوه تغییر مقدار امکان‌پذیر اما تغییرات پس از ری‌استارت از بین می‌رود امکان‌پذیر و در صورت نیاز به دائمی شدن باید در فایل‌های پیکربندی ذخیره شود

۴. تغییر مقدار متغیرهای سیستم

🔹 متغیرهای پیش‌فرض سیستم را می‌توان تغییر داد، اما این تغییرات موقتی خواهند بود.

مثال: تغییر مسیر ویرایشگر پیش‌فرض:

echo $EDITOR   # مقدار فعلی را نمایش می‌دهد
export EDITOR=nano
echo $EDITOR   # مقدار جدید را نمایش می‌دهد

📌 این تغییر فقط در نشست فعلی معتبر است. اگر بخواهید این مقدار دائمی شود، باید مقدار را در فایل ~/.bashrc یا ~/.bash_profile اضافه کنید:

echo 'export EDITOR=nano' >> ~/.bashrc
source ~/.bashrc

۵. تبدیل متغیر کاربر به متغیر محیطی (Global کردن متغیر کاربر)

🔹 متغیرهای تعریف‌شده توسط کاربر فقط در همان نشست قابل استفاده هستند. اگر می‌خواهید این متغیرها در پردازش‌های دیگر نیز قابل استفاده باشند، باید آن‌ها را به متغیر محیطی تبدیل کنید.

مثال:

myvar="Hello, Linux!"
export myvar

🔹 اکنون این متغیر در پردازش‌های فرزند (Child Processes) نیز در دسترس است.

آزمایش دسترسی متغیر در شل جدید:

bash  # باز کردن یک شل جدید
echo $myvar  # مقدار نمایش داده می‌شود
exit  # خروج از شل جدید

۶. حذف متغیرها

🔹 برای حذف متغیرهای کاربر یا سیستم از دستور unset استفاده می‌شود.

حذف متغیر کاربر:

unset myvar
echo $myvar  # مقدار خالی خواهد بود

حذف یک متغیر سیستم (موقتی):

unset EDITOR
echo $EDITOR  # مقدار ویرایشگر دیگر نمایش داده نمی‌شود

۷. استفاده از متغیرهای تعریف‌شده در اسکریپت‌ها

مثال: استفاده از متغیرهای تعریف‌شده در یک اسکریپت شل

#!/bin/bash

username="Ali"
age=30

echo "نام کاربر: $username"
echo "سن کاربر: $age"
echo "کاربر فعلی سیستم: $USER"

اجرای اسکریپت:

chmod +x script.sh
./script.sh

📌 خروجی:

نام کاربر: Ali
سن کاربر: 30
کاربر فعلی سیستم: ali

جمع‌بندی

متغیرهای سیستم به‌صورت پیش‌فرض توسط لینوکس تعریف شده و در پردازش‌های مختلف در دسترس هستند، درحالی‌که متغیرهای تعریف‌شده توسط کاربر فقط در همان نشست معتبرند.
متغیرهای سیستم معمولاً با حروف بزرگ و متغیرهای کاربر با حروف کوچک نام‌گذاری می‌شوند.
متغیرهای سیستم را می‌توان تغییر داد، اما این تغییرات موقتی است، مگر اینکه در فایل‌های پیکربندی ذخیره شوند.
برای تبدیل متغیرهای تعریف‌شده توسط کاربر به متغیر محیطی از export استفاده می‌شود.
برای حذف متغیرها از unset استفاده کنید.
متغیرهای تعریف‌شده توسط کاربر در اسکریپت‌های شل کاربرد زیادی دارند و می‌توانند اطلاعات و پیکربندی‌های خاص را مدیریت کنند.

🚀 با درک این تفاوت‌ها، می‌توانید مدیریت بهتری روی اسکریپت‌های Bash و محیط لینوکس داشته باشید![/cdb_course_lesson][cdb_course_lesson title=”فصل 4. مدیریت نوع داده‌ها در شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مدیریت داده‌های رشته‌ای در شل اسکریپتینگ” subtitle=”توضیحات کامل”]در Bash Shell، رشته‌ها (Strings) یکی از رایج‌ترین انواع داده‌ای هستند که برای ذخیره و پردازش متن به کار می‌روند. در این بخش، نحوه تعریف، مقداردهی، الحاق، استخراج، تغییر، و مقایسه رشته‌ها را با ذکر مثال‌های عملی بررسی خواهیم کرد.

تعریف و مقداردهی متغیرهای رشته‌ای

برای تعریف یک متغیر رشته‌ای در Bash، مقدار آن را درون نقل‌قول تکی (”) یا نقل‌قول دوتایی (“”) قرار می‌دهیم.

name="Ali"
message='Hello, welcome to Bash scripting!'

چاپ مقدار متغیر با echo

echo $name
echo $message

خروجی:

Ali
Hello, welcome to Bash scripting!

تفاوت بین نقل‌قول تکی و دوتایی

🔹 نقل‌قول دوتایی (“”) متغیرها و دستورات را تفسیر می‌کند.
🔹 نقل‌قول تکی (”) مقدار را به‌صورت خام نگه می‌دارد.

name="Ali"
echo "Hello, $name!"  # مقدار متغیر جایگزین می‌شود
echo 'Hello, $name!'  # مقدار متغیر جایگزین نمی‌شود

خروجی:

Hello, Ali!
Hello, $name!

الحاق (اتصال) رشته‌ها

می‌توان رشته‌ها را با کنار هم قرار دادن متغیرها یا مقدارهای رشته‌ای الحاق کرد.

greeting="Hello"
greeting+=" World"
echo $greeting

خروجی:

Hello World

دسترسی به کاراکترهای یک رشته

برای دسترسی به یک کاراکتر خاص درون رشته از ایندکس استفاده می‌شود.

text="Linux"
echo "First character: ${text:0:1}"  # اولین کاراکتر
echo "First three characters: ${text:0:3}"  # سه کاراکتر اول
echo "Substring: ${text:1:3}"  # سه کاراکتر از موقعیت دوم

طول یک رشته (length)

برای گرفتن تعداد کاراکترهای یک رشته از ${#variable} استفاده می‌شود.

text="Bash Scripting"
echo "Length: ${#text}"

خروجی:

Length: 14

جایگزینی قسمتی از رشته

برای جایگزینی یک قسمت از متن از ${variable/old/new} استفاده می‌شود.

text="I love Linux!"
new_text=${text/Linux/Bash}
echo $new_text

خروجی:

I love Bash!

حذف کاراکترها از ابتدا و انتها

text="---Hello, World!"
echo "${text#*-}"  # حذف همه چیز تا اولین '-'

خروجی:

Hello, World!

مقایسه رشته‌ها

برای مقایسه دو رشته می‌توان از = یا == استفاده کرد.

str1="Bash"
str2="Bash"

if [ "$str1" = "$str2" ]; then
    echo "Strings are equal"
else
    echo "Strings are not equal"
fi

خروجی:

Strings are equal

تبدیل حروف کوچک به بزرگ و بالعکس

text="bash scripting"
echo "${text^^}"  # تبدیل به حروف بزرگ

خروجی:

BASH SCRIPTING
text="HELLO BASH"
echo "${text,,}"  # تبدیل به حروف کوچک

خروجی:

hello bash

بررسی وجود یک رشته در متن

sentence="I love Linux scripting"

if [[ $sentence == *"Linux"* ]]; then
    echo "Linux found!"
fi

خروجی:

Linux found!

جمع‌بندی

مدیریت رشته‌ها در Bash شامل تعریف، مقداردهی، الحاق، مقایسه، جایگزینی و بررسی طول می‌شود.
با استفاده از ${#variable} می‌توان طول یک رشته را محاسبه کرد.
برای جایگزینی یک کلمه درون متن از ${variable/old/new} استفاده می‌شود.
برای حذف کاراکترها از ابتدا و انتها از ${variable#*-} و ${variable%!*} استفاده می‌شود.
برای مقایسه رشته‌ها از [ "$str1" = "$str2" ] استفاده می‌شود.
می‌توان رشته‌ها را به حروف بزرگ یا کوچک تبدیل کرد و یک عبارت را درون متن بررسی نمود.

🚀 با یادگیری این مفاهیم، می‌توان اسکریپت‌های Bash را به‌صورت حرفه‌ای‌تر و کارآمدتر نوشت![/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”داده‌های عددی و انجام عملیات ریاضی در Bash” subtitle=”توضیحات کامل”]در Bash، متغیرها به‌صورت پیش‌فرض رشته‌ای هستند، اما می‌توان عملیات ریاضی را با آن‌ها انجام داد. در این بخش، نحوه انجام محاسبات ریاضی، استفاده از expr، let، (( )) و bc برای پردازش اعداد را بررسی خواهیم کرد.

تعریف متغیرهای عددی و مقداردهی

متغیرهای عددی مانند متغیرهای رشته‌ای تعریف می‌شوند:

num1=10
num2=5
echo "Number 1: $num1"
echo "Number 2: $num2"

خروجی:

Number 1: 10
Number 2: 5

انجام عملیات ریاضی با expr

برای انجام محاسبات ساده مانند جمع، تفریق، ضرب و تقسیم می‌توان از expr استفاده کرد.

sum=$(expr $num1 + $num2)
difference=$(expr $num1 - $num2)
product=$(expr $num1 \* $num2)  # علامت * باید escape شود
quotient=$(expr $num1 / $num2)

echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"

خروجی:

Sum: 15
Difference: 5
Product: 50
Quotient: 2

استفاده از let برای انجام محاسبات

let به‌صورت داخلی از عملیات ریاضی درون Bash پشتیبانی می‌کند.

let sum=num1+num2
let difference=num1-num2
let product=num1*num2
let quotient=num1/num2

echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"

انجام عملیات با (( ))

برای انجام محاسبات در Bash scripting از (( )) نیز می‌توان استفاده کرد.

sum=$(( num1 + num2 ))
difference=$(( num1 - num2 ))
product=$(( num1 * num2 ))
quotient=$(( num1 / num2 ))

echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"

عملیات با اعداد اعشاری (bc Command)

expr و (( )) فقط با اعداد صحیح کار می‌کنند. برای اعداد اعشاری باید از bc استفاده کرد.

num1=10.5
num2=3.2

sum=$(echo "$num1 + $num2" | bc)
difference=$(echo "$num1 - $num2" | bc)
product=$(echo "$num1 * $num2" | bc)
quotient=$(echo "scale=2; $num1 / $num2" | bc)  # scale=2 یعنی نمایش تا دو رقم اعشار

echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"

خروجی:

Sum: 13.7
Difference: 7.3
Product: 33.60
Quotient: 3.28

محاسبه باقیمانده (Modulo)

برای محاسبه باقی‌مانده یک تقسیم (modulo) از % استفاده می‌شود.

remainder=$(( num1 % num2 ))
echo "Remainder: $remainder"

افزایش (Increment) و کاهش (Decrement) متغیرها

در Bash، می‌توان از ++ و -- برای افزایش یا کاهش مقدار یک متغیر استفاده کرد.

(( num1++ ))  # افزایش مقدار num1
(( num2-- ))  # کاهش مقدار num2

echo "New num1: $num1"
echo "New num2: $num2"

مقایسه اعداد و شرط‌گذاری

در شرط‌ها، برای مقایسه عددی از -eq، -ne، -lt، -gt، -le و -ge استفاده می‌شود.

if [ $num1 -gt $num2 ]; then
    echo "$num1 is greater than $num2"
else
    echo "$num1 is not greater than $num2"
fi

عملگرهای مقایسه‌ای در Bash:

عملگر توضیح
-eq برابر بودن (==)
-ne نابرابر بودن (!=)
-lt کوچکتر بودن (<)
-gt بزرگتر بودن (>)
-le کوچکتر یا مساوی (<=)
-ge بزرگتر یا مساوی (>=)

جمع‌بندی

Bash از روش‌های مختلفی برای انجام عملیات ریاضی روی متغیرهای عددی پشتیبانی می‌کند.
برای محاسبات ساده می‌توان از expr، let و (( )) استفاده کرد.
اعداد اعشاری با bc پردازش می‌شوند و scale=2 برای نمایش دو رقم اعشار کاربرد دارد.
محاسبات شامل جمع، تفریق، ضرب، تقسیم، باقیمانده، افزایش (++) و کاهش (--) هستند.
شرط‌های عددی در if از -eq، -ne، -gt، -lt و … استفاده می‌کنند.

🚀 با استفاده از این مفاهیم می‌توان اسکریپت‌های Bash را برای پردازش داده‌های عددی بهینه‌تر نوشت![/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”آرایه‌ها در شل اسکریپتینگ” subtitle=”توضیحات کامل”]آرایه‌ها در Bash به ما اجازه می‌دهند تا مجموعه‌ای از داده‌ها را در یک متغیر ذخیره کنیم. در این بخش، نحوه تعریف آرایه‌ها، دسترسی به عناصر، اضافه و حذف کردن عناصر را بررسی خواهیم کرد.


تعریف آرایه در شل

در Bash، آرایه‌ها به دو دسته تقسیم می‌شوند:
آرایه‌های عددی (Indexed Arrays): اعضای آرایه با اعداد (اندیس‌ها) از ۰ شروع می‌شوند.
آرایه‌های انجمنی (Associative Arrays): اعضای آرایه با کلیدهای متنی مشخص می‌شوند.

ایجاد آرایه عددی

روش‌های مختلف برای تعریف آرایه عددی:

# روش 1: تعریف آرایه با مقادیر اولیه
fruits=("Apple" "Banana" "Cherry" "Mango")

# روش 2: مقداردهی هر عنصر جداگانه
fruits[0]="Apple"
fruits[1]="Banana"
fruits[2]="Cherry"
fruits[3]="Mango"

# روش 3: تعریف آرایه خالی
numbers=()

دسترسی به اعضای آرایه

برای دسترسی به یک مقدار مشخص، از ${array[index]} استفاده می‌کنیم.

echo "First fruit: ${fruits[0]}"
echo "Second fruit: ${fruits[1]}"

خروجی:

First fruit: Apple
Second fruit: Banana

دسترسی به تمام اعضای آرایه:

echo "All fruits: ${fruits[@]}"

خروجی:

All fruits: Apple Banana Cherry Mango

تعداد اعضای آرایه:

echo "Number of fruits: ${#fruits[@]}"

خروجی:

Number of fruits: 4

دسترسی به تمام ایندکس‌های آرایه:

echo "Indexes: ${!fruits[@]}"

خروجی:

Indexes: 0 1 2 3

اضافه کردن عناصر به آرایه

برای افزودن یک مقدار جدید، کافی است مقدار را به یک ایندکس جدید اختصاص دهیم.

fruits[4]="Orange"
echo "Updated fruits: ${fruits[@]}"

خروجی:

Updated fruits: Apple Banana Cherry Mango Orange

افزودن مقدار جدید به انتهای آرایه بدون دانستن آخرین ایندکس:

fruits+=("Pineapple")
echo "New fruits list: ${fruits[@]}"

حذف عناصر از آرایه

حذف یک مقدار مشخص از آرایه:

unset fruits[1]  # حذف مقدار با ایندکس 1 (Banana)
echo "Fruits after deletion: ${fruits[@]}"

خروجی:

Fruits after deletion: Apple Cherry Mango Orange Pineapple

حذف کامل آرایه:

unset fruits
echo "Fruits: ${fruits[@]}"  # خروجی خالی خواهد بود

آرایه‌های انجمنی (Associative Arrays)

در Bash 4+، آرایه‌های انجمنی امکان ذخیره مقادیر را با کلید متنی دارند.

تعریف و مقداردهی آرایه انجمنی:
declare -A user_info  # تعریف آرایه انجمنی
user_info[name]="John"
user_info[age]=30
user_info[email]="john@example.com"
دسترسی به مقادیر:
echo "User Name: ${user_info[name]}"
echo "User Age: ${user_info[age]}"
echo "User Email: ${user_info[email]}"
لیست تمام کلیدها و مقادیر:
echo "Keys: ${!user_info[@]}"
echo "Values: ${user_info[@]}"
حذف مقدار از آرایه انجمنی:
unset user_info[email]
echo "After deletion: ${!user_info[@]}"

جمع‌بندی

Bash از آرایه‌های عددی و آرایه‌های انجمنی (در نسخه ۴ به بعد) پشتیبانی می‌کند.
می‌توان با ${array[index]} به مقادیر دسترسی پیدا کرد و با ${array[@]} تمام مقادیر را خواند.
برای حذف مقدار از آرایه، از unset array[index] و برای پاک کردن کل آرایه از unset array استفاده می‌شود.
در آرایه‌های انجمنی، مقداردهی با declare -A انجام می‌شود و مقادیر با کلیدهای متنی ذخیره می‌شوند.

🚀 با این روش‌ها می‌توان مدیریت داده‌ها در اسکریپت‌های Bash را بهینه‌تر کرد![/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”متغیرهای چندبعدی در شل اسکریپت (Multi-Dimensional Arrays in Shell Scripting)” subtitle=”توضیحات کامل”]Bash به‌صورت پیش‌فرض از آرایه‌های چندبعدی (Nested Arrays) پشتیبانی نمی‌کند، اما می‌توان این مفهوم را با استفاده از آرایه‌های انجمنی یا تو در تو شبیه‌سازی کرد. در این بخش، روش‌های مختلف پیاده‌سازی آرایه‌های چندبعدی در شل را بررسی خواهیم کرد.


استفاده از آرایه‌های عددی به‌عنوان آرایه‌های چندبعدی

Bash به‌طور ذاتی از آرایه‌های چندبعدی پشتیبانی نمی‌کند، اما می‌توان این ویژگی را با روش‌های مختلفی مانند شبیه‌سازی دستی ایندکس‌ها پیاده‌سازی کرد.

ایجاد یک آرایه دوبعدی (شبیه‌سازی)
matrix=(
    "1 2 3"
    "4 5 6"
    "7 8 9"
)

# دسترسی به یک سطر از آرایه
echo "Row 1: ${matrix[0]}"
echo "Row 2: ${matrix[1]}"
echo "Row 3: ${matrix[2]}"

خروجی:

Row 1: 1 2 3  
Row 2: 4 5 6  
Row 3: 7 8 9  

دسترسی به مقدار خاص در آرایه دوبعدی (با استفاده از awk یا cut)

row=1  # ایندکس سطر
col=2  # ایندکس ستون
echo "Element at ($row,$col): $(echo ${matrix[$row]} | cut -d' ' -f$(($col+1)))"

خروجی:

Element at (1,2): 6

استفاده از آرایه‌های انجمنی برای شبیه‌سازی آرایه‌های چندبعدی

در Bash نسخه ۴+، می‌توان با آرایه‌های انجمنی، آرایه‌های چندبعدی را پیاده‌سازی کرد.

ایجاد یک آرایه دو بعدی با آرایه‌های انجمنی
declare -A matrix

# مقداردهی آرایه
matrix["0,0"]=1
matrix["0,1"]=2
matrix["0,2"]=3
matrix["1,0"]=4
matrix["1,1"]=5
matrix["1,2"]=6
matrix["2,0"]=7
matrix["2,1"]=8
matrix["2,2"]=9

# دسترسی به مقدار خاص
echo "Element at (1,2): ${matrix["1,2"]}"

خروجی:

Element at (1,2): 6

چاپ کل ماتریس با استفاده از حلقه

for i in {0..2}; do
    for j in {0..2}; do
        echo -n "${matrix["$i,$j"]} "
    done
    echo ""  # برای رفتن به خط جدید
done

خروجی:

1 2 3  
4 5 6  
7 8 9  

جمع‌بندی

Bash مستقیماً از آرایه‌های چندبعدی پشتیبانی نمی‌کند، اما می‌توان آن را شبیه‌سازی کرد.
روش اول: استفاده از آرایه‌های تک‌بعدی و دسترسی به مقادیر با cut یا awk.
روش دوم (بهینه‌تر): استفاده از آرایه‌های انجمنی در Bash 4+ برای مدیریت مقادیر با کلیدهای ترکیبی (row,col).
برای پردازش ماتریس‌ها، ترکیب حلقه‌ها و echo امکان‌پذیر است.

🚀 با این روش‌ها می‌توان مفهوم آرایه‌های چندبعدی را در Bash پیاده‌سازی کرد![/cdb_course_lesson][cdb_course_lesson title=”فصل 5. ابزارها و دستورات مرتبط با متغیرها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از دستورات declare و typeset برای تعیین نوع متغیرها” subtitle=”توضیحات کامل”]در Bash، متغیرها به‌صورت دینامیک تعریف می‌شوند و نیازی به تعیین نوع ندارند. اما برای مدیریت بهتر داده‌ها و کنترل نوع متغیرها، می‌توان از دستورات declare و typeset استفاده کرد. این دستورات به شما اجازه می‌دهند محدودیت‌هایی روی متغیرها اعمال کنید، مانند:

  • تعیین نوع متغیر (رشته، عددی، فقط خواندنی و…)
  • تعریف آرایه‌ها
  • افزایش امنیت و جلوگیری از تغییرات ناخواسته

تعریف دستور declare در Bash

declare برای تعریف و تنظیم ویژگی‌های متغیرها در Bash استفاده می‌شود.

ساختار کلی دستور declare
declare [option] variable_name=value
  • [option] نوع متغیر را مشخص می‌کند.
  • variable_name=value مقدار متغیر را تعیین می‌کند.
برخی از گزینه‌های پرکاربرد declare
گزینه توضیح
-r تعیین متغیر فقط خواندنی (Read-Only)
-i تبدیل مقدار متغیر به عددی (Integer)
-a تعریف آرایه معمولی (Indexed Array)
-A تعریف آرایه انجمنی (Associative Array)
-x تبدیل متغیر به متغیر محیطی (Export)

استفاده از declare برای تعیین نوع متغیرها

تعریف متغیر فقط خواندنی (-r)

✅ متغیرهای فقط خواندنی تغییر نمی‌کنند و اگر مقدار جدیدی به آن اختصاص دهید، خطا دریافت می‌کنید.

declare -r PI=3.14
echo "Value of PI: $PI"

# تلاش برای تغییر مقدار (باعث خطا می‌شود)
PI=3.14159  

خروجی:

Value of PI: 3.14
bash: PI: readonly variable
تعریف متغیر عددی (-i)

✅ وقتی از -i استفاده می‌کنید، مقدار متغیر به‌عنوان عدد تفسیر می‌شود.

declare -i number=10
number+=5
echo "Result: $number"  # خروجی: 15

# مقداردهی با رشته (خودکار مقدار را صفر می‌کند)
number="abc"
echo "Number: $number"  # خروجی: 0
تعریف آرایه‌ها (-a برای معمولی، -A برای انجمنی)

-a برای آرایه‌های معمولی و -A برای آرایه‌های انجمنی استفاده می‌شود.

# تعریف آرایه معمولی
declare -a my_array=("Apple" "Banana" "Cherry")
echo "First element: ${my_array[0]}"

# تعریف آرایه انجمنی
declare -A student
student[name]="Ali"
student[age]=25
echo "Student Name: ${student[name]}"
تعریف متغیرهای محیطی (-x)

-x باعث می‌شود متغیر در کل سیستم در دسترس باشد.

declare -x PATH="/usr/local/bin:$PATH"
echo "Updated PATH: $PATH"

استفاده از typeset در شل‌های دیگر

typeset دقیقاً مشابه declare عمل می‌کند اما معمولاً در Korn Shell (ksh) و Zsh کاربرد دارد.
typeset در نسخه‌های جدید Bash کمتر استفاده می‌شود.

typeset -i num=20
num+=10
echo "Result: $num"  # خروجی: 30

جمع‌بندی

  • declare و typeset برای مدیریت نوع متغیرها در شل اسکریپت استفاده می‌شوند.
  • declare در Bash پرکاربردتر است، اما typeset در ksh و zsh بیشتر دیده می‌شود.
  • می‌توان از declare برای:
    • تعریف متغیرهای فقط خواندنی (-r)
    • عدد کردن متغیرها (-i)
    • تعریف آرایه‌ها (-a و -A)
    • تعریف متغیرهای محیطی (-x)
  • declare به بهینه‌سازی و افزایش امنیت اسکریپت‌ها کمک می‌کند! 🚀

[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”محدود کردن مقادیر متغیرها با استفاده از readonly” subtitle=”توضیحات کامل”]در Bash، زمانی که می‌خواهیم مقدار یک متغیر پس از مقداردهی قابل تغییر نباشد، از دستور readonly استفاده می‌کنیم. این قابلیت باعث می‌شود متغیر فقط خواندنی (Read-Only) شود و دیگر قابل تغییر یا حذف نباشد. این ویژگی در افزایش امنیت و پایداری اسکریپت‌ها نقش مهمی دارد.


استفاده از readonly برای تعیین متغیر فقط خواندنی

✅ ساده‌ترین روش تعریف یک متغیر فقط خواندنی استفاده از دستور readonly به شکل زیر است:

readonly VAR_NAME=value

✅ مثال عملی:

readonly PI=3.14
echo "Value of PI: $PI"

# تلاش برای تغییر مقدار متغیر (باعث خطا می‌شود)
PI=3.14159

🔴 خروجی:

Value of PI: 3.14
bash: PI: readonly variable

همان‌طور که می‌بینید، تغییر مقدار متغیر باعث خطای Bash می‌شود.


استفاده از declare -r برای تعریف متغیر فقط خواندنی

✅ روش دیگر برای تعیین متغیرهای فقط خواندنی استفاده از declare -r است:

declare -r USERNAME="admin"
echo "Username: $USERNAME"

# تلاش برای تغییر مقدار متغیر (باعث خطا می‌شود)
USERNAME="root"

🔴 خروجی:

Username: admin
bash: USERNAME: readonly variable

بررسی متغیرهای فقط خواندنی با readonly -p

✅ اگر می‌خواهید لیستی از تمام متغیرهای فقط خواندنی را مشاهده کنید، می‌توانید از دستور زیر استفاده کنید:

readonly -p

🔹 این دستور تمام متغیرهای فقط خواندنی در سیستم را نمایش می‌دهد.


اعمال readonly روی متغیرهای محیطی

✅ متغیرهای محیطی نیز می‌توانند فقط خواندنی شوند تا از تغییر ناخواسته جلوگیری شود.

readonly PATH
echo "Current PATH: $PATH"

# تلاش برای تغییر مقدار (باعث خطا می‌شود)
PATH="/new/path:$PATH"

🔴 خروجی:

Current PATH: /usr/local/bin:/usr/bin:/bin
bash: PATH: readonly variable

📌 این روش مطمئن می‌شود که مسیرهای سیستم تغییر نکنند و از مشکلات امنیتی جلوگیری شود.


تعیین تابع فقط خواندنی در Bash

✅ می‌توان توابع را نیز فقط خواندنی کرد تا امکان بازنویسی آن‌ها وجود نداشته باشد.

my_function() {
    echo "This is a read-only function."
}

readonly -f my_function

# تلاش برای بازنویسی تابع (باعث خطا می‌شود)
my_function() {
    echo "Trying to modify the function!"
}

🔴 خروجی:

bash: my_function: readonly function

📌 این روش مانع تغییر توابع حساس در اسکریپت‌ها می‌شود.


جمع‌بندی

  • readonly VAR_NAME=value متغیر را فقط خواندنی می‌کند و مقدار آن دیگر تغییر نمی‌کند.
  • declare -r VAR_NAME=value روشی جایگزین برای تعیین متغیرهای فقط خواندنی است.
  • readonly -p لیستی از تمام متغیرهای فقط خواندنی را نمایش می‌دهد.
  • readonly PATH و سایر متغیرهای محیطی را از تغییرات ناخواسته محافظت می‌کند.
  • readonly -f function_name یک تابع را فقط خواندنی کرده و مانع بازنویسی آن می‌شود.

✅ استفاده از readonly در اسکریپت‌های Bash باعث افزایش امنیت، جلوگیری از تغییرات تصادفی و افزایش پایداری کدها می‌شود! 🚀[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”حذف متغیرها با دستور unset” subtitle=”توضیحات کامل”]در Bash، اگر بخواهید یک متغیر را کامل حذف کنید، می‌توانید از دستور unset استفاده کنید. این دستور متغیر را از محیط حذف کرده و مقدار آن را غیرقابل‌دسترسی می‌کند.


حذف یک متغیر معمولی

✅ ساده‌ترین روش حذف یک متغیر به این صورت است:

VAR="Hello World"
echo "Before unset: $VAR"

unset VAR  # حذف متغیر

echo "After unset: $VAR"

🔴 خروجی:

Before unset: Hello World
After unset:

📌 همان‌طور که مشاهده می‌کنید، مقدار متغیر بعد از حذف دیگر قابل‌دسترسی نیست.


بررسی متغیر قبل و بعد از حذف

✅ برای بررسی اینکه متغیر وجود دارد یا خیر، می‌توان از شرط زیر استفاده کرد:

VAR="Bash Scripting"

if [ -z "$VAR" ]; then
    echo "VAR is empty"
else
    echo "VAR exists with value: $VAR"
fi

unset VAR  # حذف متغیر

if [ -z "$VAR" ]; then
    echo "VAR is now empty"
else
    echo "VAR still exists: $VAR"
fi

🔴 خروجی:

VAR exists with value: Bash Scripting
VAR is now empty

حذف چند متغیر هم‌زمان

✅ شما می‌توانید چند متغیر را به‌طور هم‌زمان حذف کنید:

VAR1="Linux"
VAR2="Shell"
VAR3="Scripting"

echo "Before unset: $VAR1, $VAR2, $VAR3"

unset VAR1 VAR2 VAR3  # حذف چند متغیر

echo "After unset: $VAR1, $VAR2, $VAR3"

🔴 خروجی:

Before unset: Linux, Shell, Scripting
After unset:  

📌 همان‌طور که مشاهده می‌کنید، تمام متغیرها حذف شدند.


عدم حذف متغیرهای فقط خواندنی

✅ اگر متغیری را با readonly فقط خواندنی کرده باشید، نمی‌توان آن را حذف کرد:

readonly PI=3.14
unset PI  # تلاش برای حذف متغیر فقط خواندنی

🔴 خروجی:

bash: unset: PI: cannot unset: readonly variable

📌 unset روی متغیرهای فقط خواندنی کار نمی‌کند و باعث خطا می‌شود.


حذف متغیرهای محیطی

✅ برای حذف یک متغیر محیطی (exported variable)، می‌توانید از unset استفاده کنید:

export MY_VAR="System Variable"
echo "Before unset: $MY_VAR"

unset MY_VAR  # حذف متغیر محیطی

echo "After unset: $MY_VAR"

🔴 خروجی:

Before unset: System Variable
After unset:

📌 این کار متغیر محیطی را از محیط جاری شل حذف می‌کند.


حذف عناصر خاص از یک آرایه

✅ برای حذف یک عضو خاص از آرایه، می‌توان unset را روی یک ایندکس خاص اعمال کرد:

arr=("one" "two" "three")
echo "Before unset: ${arr[@]}"

unset arr[1]  # حذف عنصر دوم

echo "After unset: ${arr[@]}"

🔴 خروجی:

Before unset: one two three
After unset: one three

📌 عنصر دوم حذف شد، اما ساختار آرایه حفظ شد.

✅ برای حذف کل آرایه:

unset arr

جمع‌بندی

  • unset VAR_NAME → متغیر موردنظر را از حافظه حذف می‌کند.
  • unset VAR1 VAR2 VAR3 → چندین متغیر را هم‌زمان حذف می‌کند.
  • unset arr[INDEX] → یک عضو خاص از آرایه را حذف می‌کند.
  • unset arr → کل آرایه را حذف می‌کند.
  • unset روی متغیرهای readonly کار نمی‌کند و باعث خطا می‌شود.
  • متغیرهای محیطی را می‌توان با unset از محیط شل حذف کرد.

✅ استفاده از unset به شما کمک می‌کند تا حافظه را مدیریت کنید، متغیرهای غیرضروری را حذف کنید و از آلودگی محیط شل جلوگیری نمایید. 🚀[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. گسترش متغیرها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”گسترش مقدار متغیرها: ${variable}” subtitle=”توضیحات کامل”]در شل، می‌توان از گسترش مقدار متغیرها برای دسترسی به مقدار یک متغیر و انجام عملیات مختلف بر روی آن استفاده کرد. این ویژگی به شما این امکان را می‌دهد که از مقدار متغیر در مکان‌های مختلف اسکریپت خود استفاده کنید و آن را تغییر دهید یا پردازش کنید.


1. دسترسی به مقدار یک متغیر با ${variable}

وقتی که شما یک متغیر را تعریف کرده‌اید، برای دسترسی به مقدار آن از ${variable} استفاده می‌کنید. این روش به‌ویژه زمانی مفید است که نام متغیر در داخل یک رشته یا عبارت پیچیده قرار داشته باشد.

name="Alice"
echo "Hello, ${name}!"  # چاپ Hello, Alice!

🔴 خروجی:

Hello, Alice!

در این مثال، متغیر name به مقدار "Alice" تنظیم شده و سپس در دستور echo گسترش می‌یابد.


2. استفاده از گسترش برای ترکیب متغیرها و رشته‌ها

شما می‌توانید از ${variable} برای ترکیب متغیرها با رشته‌ها استفاده کنید، به‌طوری که بین آن‌ها هیچ فاصله‌ای وجود نداشته باشد:

name="Alice"
echo "Hello, ${name}World!"  # چاپ Hello, AliceWorld!

🔴 خروجی:

Hello, AliceWorld!

در اینجا، متغیر name با رشته "World!" ترکیب شده است.


3. استفاده از گسترش برای بخش‌بندی متغیرها (Substring Extraction)

در شل، می‌توانید از گسترش متغیر برای استخراج یک زیررشته خاص از مقدار متغیر استفاده کنید.

string="Hello, World!"
echo ${string:7:5}  # استخراج رشته از موقعیت 7 و طول 5

🔴 خروجی:

World

📌 در این مثال:

  • 7 به معنی موقعیت شروع (شروع از حرف W در "World!").
  • 5 طول زیررشته‌ای است که می‌خواهیم استخراج کنیم.

4. استفاده از گسترش برای جایگزینی مقدار متغیر

با استفاده از گسترش متغیر، می‌توانید بخشی از مقدار یک متغیر را با چیزی دیگر جایگزین کنید.

filename="file123.txt"
echo ${filename/file/Document}  # جایگزینی 'file' با 'Document'

🔴 خروجی:

Document123.txt

📌 در اینجا، عبارت file با Document جایگزین شده است.


5. تعیین مقدار پیش‌فرض برای متغیرها با گسترش

اگر یک متغیر مقداردهی نشده باشد، می‌توانید از گسترش برای تعیین مقدار پیش‌فرض استفاده کنید.

echo ${name:-"Default Name"}  # اگر name مقدار نداشته باشد، "Default Name" چاپ می‌شود

🔴 خروجی:

Default Name

اگر متغیر name تنظیم نشده باشد، مقدار "Default Name" چاپ می‌شود. در غیر این صورت، مقدار متغیر name چاپ می‌شود.


6. تغییر مقدار متغیر اگر خالی باشد (شبیه‌سازی شرط)

اگر می‌خواهید فقط در صورتی که یک متغیر مقدار ندارد، به آن مقدار دهید، می‌توانید از گسترش به‌صورت زیر استفاده کنید:

name=""
echo ${name:="Default Name"}  # اگر name خالی باشد، "Default Name" به آن اختصاص داده می‌شود

🔴 خروجی:

Default Name

اگر متغیر name خالی باشد، مقدار "Default Name" به آن اختصاص داده می‌شود. در غیر این صورت، مقدار فعلی متغیر حفظ خواهد شد.


7. حذف بخش‌هایی از متغیر

برای حذف بخشی از مقدار متغیر از شروع یا پایان، می‌توانید از گسترش استفاده کنید:

  • حذف از ابتدا (Remove prefix):
filename="file123.txt"
echo ${filename#file}  # حذف prefix 'file'

🔴 خروجی:

123.txt
  • حذف از انتها (Remove suffix):
filename="file123.txt"
echo ${filename%.txt}  # حذف suffix '.txt'

🔴 خروجی:

file123

8. بررسی وجود متغیر و انجام عملیات بر اساس آن

با استفاده از گسترش می‌توان بررسی کرد که آیا متغیر مقدار دارد یا نه و سپس عملیاتی انجام داد:

var="value"
echo ${var:+Variable exists}  # اگر متغیر مقدار داشته باشد، چاپ می‌شود

🔴 خروجی:

Variable exists

اگر متغیر var مقدار نداشته باشد، هیچ چیزی چاپ نمی‌شود.


جمع‌بندی

گسترش مقدار متغیرها در شل، ابزاری بسیار قدرتمند برای پردازش و دستکاری مقادیر متغیرها است. این امکان را به شما می‌دهد که:

  • متغیرها را به راحتی در رشته‌ها یا دستورها گنجانده و ترکیب کنید.
  • مقادیر پیش‌فرض برای متغیرهای خالی تعیین کنید.
  • عملیات مختلفی مانند جایگزینی، استخراج زیررشته، حذف بخش‌هایی از متغیر و بررسی وجود مقدار انجام دهید.

💡 گسترش متغیرها در شل به شما کمک می‌کند تا اسکریپت‌های خود را منظم‌تر، کارآمدتر و انعطاف‌پذیرتر بنویسید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مقدار پیش‌فرض برای متغیرها: ${variable:-default}” subtitle=”توضیحات کامل”]در شل، شما می‌توانید از گسترش متغیر برای تعیین مقدار پیش‌فرض استفاده کنید. این ویژگی به شما این امکان را می‌دهد که اگر یک متغیر مقداردهی نشده یا خالی باشد، به‌طور خودکار برای آن مقدار پیش‌فرضی تعیین کنید.


1. گسترش با ${variable:-default}

زمانی که از ساختار ${variable:-default} استفاده می‌کنید، شل ابتدا بررسی می‌کند که آیا متغیر مورد نظر مقدار دارد یا خیر. اگر متغیر مقداردهی نشده یا خالی باشد، مقدار "default" به آن اختصاص می‌دهد.

name=""
echo ${name:-"Default Name"}  # چاپ "Default Name" زیرا name خالی است

🔴 خروجی:

Default Name

در این مثال، چون متغیر name مقدار ندارد، مقدار "Default Name" به‌عنوان مقدار پیش‌فرض نمایش داده می‌شود.


2. استفاده در اسکریپت‌ها برای مدیریت متغیرهای خالی

این قابلیت به شما این امکان را می‌دهد که از آن برای اطمینان از وجود مقادیر در متغیرها استفاده کنید، به‌ویژه زمانی که مقادیر متغیرها از منابع مختلف مانند ورودی کاربر یا فایل‌های پیکربندی خوانده می‌شود.

username=""
echo "Welcome, ${username:-Guest}!"  # اگر username خالی باشد، "Guest" چاپ می‌شود

🔴 خروجی:

Welcome, Guest!

اگر متغیر username تنظیم نشده باشد یا خالی باشد، مقدار پیش‌فرض "Guest" نمایش داده می‌شود.


3. وقتی متغیر مقدار دارد

اگر متغیر مقداردهی شده و غیر خالی باشد، گسترش ${variable:-default} هیچ تغییری ایجاد نمی‌کند و مقدار واقعی متغیر چاپ می‌شود.

username="Alice"
echo "Welcome, ${username:-Guest}!"  # اگر username مقدار داشته باشد، مقدار واقعی آن چاپ می‌شود

🔴 خروجی:

Welcome, Alice!

در اینجا، چون username مقدار "Alice" دارد، همان مقدار چاپ می‌شود و مقدار "Guest" به‌عنوان پیش‌فرض مورد استفاده قرار نمی‌گیرد.


4. کاربرد در اسکریپت‌های خودکار

استفاده از گسترش متغیر با مقدار پیش‌فرض می‌تواند در اسکریپت‌های خودکار و در شرایطی که نیاز دارید از مقادیر پیش‌فرض استفاده کنید بسیار مفید باشد، مثلاً در زمانی که ورودی‌های ضروری از کاربر یا فایل‌های پیکربندی در دسترس نباشند.

output_dir=""
echo "Output directory: ${output_dir:-/tmp}"  # اگر متغیر output_dir خالی باشد، /tmp به‌عنوان مسیر پیش‌فرض نمایش داده می‌شود

🔴 خروجی:

Output directory: /tmp

چون متغیر output_dir خالی است، مسیر پیش‌فرض /tmp به‌عنوان مقدار نمایش داده می‌شود.


5. استفاده در پروژه‌ها برای تنظیم مقادیر پیش‌فرض

این روش در هنگام تنظیم متغیرهایی که ممکن است نیاز به مقداردهی در محیط‌های مختلف داشته باشند (مانند اسکریپت‌هایی که در محیط‌های مختلف اجرا می‌شوند) بسیار کاربردی است.

log_dir="${log_dir:-/var/log}"  # اگر log_dir تنظیم نشده باشد، مسیر پیش‌فرض /var/log به آن اختصاص داده می‌شود

🔴 خروجی:

/var/log

اگر متغیر log_dir از قبل تنظیم نشده باشد، مسیر پیش‌فرض /var/log به آن اختصاص داده می‌شود.


جمع‌بندی

گسترش متغیر با استفاده از ${variable:-default} یک روش بسیار مفید برای تعیین مقادیر پیش‌فرض در شل است. این امکان به شما کمک می‌کند تا از خطاهای ناشی از متغیرهای خالی یا تنظیم‌نشده جلوگیری کنید و در شرایط مختلف به‌طور خودکار از مقادیر پیش‌فرض استفاده کنید.

مزایای استفاده از ${variable:-default}:

  • جلوگیری از خطاها در صورت خالی بودن یا تنظیم نشدن متغیرها.
  • تسهیل مدیریت و تنظیمات در اسکریپت‌های خودکار.
  • بهبود خوانایی و نگهداری اسکریپت‌ها.

با استفاده از این ویژگی، می‌توانید اسکریپت‌های خود را مقاوم‌تر و انعطاف‌پذیرتر بسازید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی وجود متغیرها: ${variable:+value}” subtitle=”توضیحات کامل”]در شل، یکی از روش‌های مفید برای بررسی وجود یک متغیر و انجام عملیات‌های خاص بر اساس آن، استفاده از گسترش متغیرها با فرمت ${variable:+value} است. این ساختار به شما این امکان را می‌دهد که اگر متغیر مقدار داشته باشد (به غیر از خالی یا غیر تعریف شده)، یک مقدار خاص را بازگشت دهید.


1. ساختار ${variable:+value}

زمانی که از ساختار ${variable:+value} استفاده می‌کنید، شل ابتدا بررسی می‌کند که آیا متغیر مورد نظر دارای مقداری است یا خیر. اگر متغیر مقدار داشته باشد (نه خالی یا تعریف نشده)، مقدار value را برمی‌گرداند. در غیر این صورت، هیچ مقداری برنمی‌گرداند (خالی می‌شود).

name="John"
echo ${name:+Hello}  # چاپ "Hello" زیرا متغیر name مقداری دارد

🔴 خروجی:

Hello

در این مثال، چون متغیر name مقدار "John" را دارد، نتیجه گسترش ${name:+Hello} برابر با "Hello" خواهد بود.


2. زمانی که متغیر خالی است

اگر متغیر مورد نظر خالی باشد یا مقداردهی نشده باشد، مقدار بازگشتی این گسترش هیچ چیزی نخواهد بود.

name=""
echo ${name:+Hello}  # هیچ چیزی چاپ نمی‌شود چون متغیر name خالی است

🔴 خروجی:

[خالی]

در اینجا، چون متغیر name خالی است، هیچ مقداری به‌عنوان خروجی نمایش داده نمی‌شود.


3. بررسی استفاده در اسکریپت‌ها

این گسترش می‌تواند برای انجام اعمال خاصی در اسکریپت‌ها بسیار مفید باشد. به‌عنوان مثال، اگر بخواهید پیامی را تنها در صورتی که متغیر خاصی تنظیم شده باشد چاپ کنید، می‌توانید از ${variable:+value} استفاده کنید.

username="Alice"
echo "User: ${username:+$username}"  # چاپ "User: Alice" زیرا متغیر username مقدار دارد

🔴 خروجی:

User: Alice

اگر متغیر username مقداری نداشت، در این صورت echo چیزی نمایش نمی‌داد.


4. استفاده در شرایط مختلف

این قابلیت زمانی که بخواهید برای انجام عملیاتی خاص تنها در صورتی که یک متغیر مقداردهی شده باشد، عمل کنید، مفید است.

output_dir=""
echo "Output directory: ${output_dir:+$output_dir}"  # در صورت تنظیم نبودن، چیزی چاپ نمی‌شود

🔴 خروجی:

[خالی]

در اینجا، چون متغیر output_dir مقداردهی نشده است، چیزی چاپ نمی‌شود.


5. کاربرد در اسکریپت‌های خودکار و مقایسه با روش‌های دیگر

گسترش ${variable:+value} به‌ویژه زمانی مفید است که بخواهید عملیات خاصی را تنها در صورت وجود مقدار برای متغیر انجام دهید و در غیر این صورت هیچ‌گونه عملیاتی نداشته باشید.

log_dir="/var/log"
echo "Log directory is set: ${log_dir:+yes}"  # چون log_dir مقدار دارد، "yes" چاپ می‌شود

🔴 خروجی:

Log directory is set: yes

اگر متغیر log_dir خالی بود، به‌جای "yes" هیچ مقداری چاپ نمی‌شد.


جمع‌بندی

گسترش متغیر با استفاده از ${variable:+value} ابزاری مفید برای انجام عملیات‌ها بر اساس وجود یا عدم وجود مقادیر در متغیرها است. این ویژگی می‌تواند در زمان نوشتن اسکریپت‌های خودکار و برای مدیریت بهتر ورودی‌های متغیرها کاربردی باشد.

مزایای استفاده از ${variable:+value}:

  • انجام عملیات فقط در صورتی که متغیر مقداردهی شده باشد.
  • بهبود انعطاف‌پذیری و خوانایی اسکریپت‌ها.
  • جلوگیری از چاپ یا انجام عملیات غیر ضروری زمانی که متغیر خالی است.

با استفاده از این روش می‌توانید اسکریپت‌هایی بسازید که تنها زمانی اقدام به انجام کاری می‌کنند که اطلاعات لازم فراهم شده باشد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تغییر مقدار متغیرها در هنگام استفاده: ${variable:=new_value}” subtitle=”توضیحات کامل”]در شل، یکی از روش‌های مفید برای مقداردهی مجدد به متغیرها در حین استفاده، استفاده از گسترش متغیرها با فرمت ${variable:=new_value} است. این دستور به شما این امکان را می‌دهد که در صورتی که متغیر دارای مقدار نباشد یا خالی باشد، به آن مقدار جدیدی اختصاص دهید.


1. ساختار ${variable:=new_value}

زمانی که از این ساختار استفاده می‌کنید، شل ابتدا بررسی می‌کند که آیا متغیر مقدار دارد یا نه. اگر متغیر مقداردهی نشده یا خالی باشد، شل مقدار جدیدی که مشخص کرده‌اید (new_value) را به آن تخصیص می‌دهد. اگر متغیر قبلاً مقداری داشته باشد، هیچ تغییری در مقدار آن ایجاد نمی‌شود.

name=""
echo "Name before: ${name:=John}"  # اگر name خالی باشد، مقدار جدید به آن داده می‌شود
echo "Name after: $name"           # نام جدید که به متغیر داده شده است

🔴 خروجی:

Name before: John
Name after: John

در این مثال، چون متغیر name خالی بود، مقدار "John" به آن اختصاص یافت و در خروجی چاپ شد.


2. زمانی که متغیر مقداری داشته باشد

اگر متغیر قبلاً مقداری داشت، گسترش ${variable:=new_value} هیچ تغییری در مقدار آن ایجاد نمی‌کند و مقدار اولیه آن همچنان به‌عنوان مقدار متغیر باقی خواهد ماند.

name="Alice"
echo "Name before: ${name:=John}"  # مقدار اولیه name که Alice است چاپ می‌شود
echo "Name after: $name"           # نام قبل از تغییر که "Alice" است

🔴 خروجی:

Name before: Alice
Name after: Alice

در اینجا، چون متغیر name قبلاً مقدار "Alice" را داشت، هیچ تغییری در آن ایجاد نشد و در خروجی همان مقدار اولیه چاپ شد.


3. کاربرد در اسکریپت‌ها

این گسترش معمولاً برای تعیین مقادیر پیش‌فرض به‌کار می‌رود که در صورتی که متغیر مورد نظر هنوز مقداری نداشته باشد، یک مقدار از پیش‌تعریف‌شده به آن داده شود.

log_dir=""
echo "Log directory: ${log_dir:="/var/log"}"  # در صورتی که log_dir خالی باشد، مقدار پیش‌فرض به آن داده می‌شود
echo "Log directory after: $log_dir"

🔴 خروجی:

Log directory: /var/log
Log directory after: /var/log

در این مثال، چون متغیر log_dir خالی است، مقدار پیش‌فرض "/var/log" به آن داده می‌شود.


4. جلوگیری از مشکل متغیرهای خالی یا غیرمقداردهی‌شده

یکی از بزرگ‌ترین مزایای این روش، اطمینان از اینکه یک متغیر همیشه مقدار معتبری دارد، است. این روش به‌ویژه زمانی مفید است که بخواهید اسکریپت‌های خود را مقاوم‌تر و قابل اطمینان‌تر کنید.

output=""
echo "Output path: ${output:="No path provided"}"  # در صورت خالی بودن output، مقدار پیش‌فرض اختصاص داده می‌شود
echo "Output path after: $output"

🔴 خروجی:

Output path: No path provided
Output path after: No path provided

در اینجا، چون متغیر output خالی است، مقدار "No path provided" به آن داده می‌شود.


5. مقایسه با روش‌های دیگر

گسترش ${variable:=new_value} را می‌توان با روش‌های دیگر نیز مقایسه کرد. در حقیقت، این نوع گسترش مشابه با استفاده از دستور if برای بررسی مقدار متغیر است، با این تفاوت که در اینجا کار به‌صورت یک خط انجام می‌شود و خوانایی بهتری دارد.

# روش سنتی:
if [ -z "$variable" ]; then
    variable="default_value"
fi

# روش گسترش:
variable=${variable:="default_value"}

در روش گسترش، خط کد کوتاه‌تر و ساده‌تر است.


جمع‌بندی

گسترش ${variable:=new_value} ابزاری قدرتمند برای مدیریت مقادیر پیش‌فرض در شل است که به شما این امکان را می‌دهد که در صورت خالی یا تعریف‌نشده بودن متغیر، آن را به‌صورت خودکار با مقداری که مشخص کرده‌اید پر کنید. این قابلیت می‌تواند در نگارش اسکریپت‌های خودکار بسیار مفید باشد، زیرا اطمینان حاصل می‌کند که متغیرها همیشه مقدار دارند و از بروز خطاهای ناشی از متغیرهای خالی جلوگیری می‌شود.

مزایای استفاده از ${variable:=new_value}:

  • تخصیص مقدار پیش‌فرض در صورت خالی بودن یا تعریف‌نشده بودن متغیر.
  • سادگی و کوتاهی کد برای تعیین مقادیر پیش‌فرض.
  • بهبود اطمینان‌پذیری و خوانایی اسکریپت‌ها.

[/cdb_course_lesson][cdb_course_lesson title=”فصل 7. مدیریت متغیرهای خاص در شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”متغیرهای خاص در شل: $0, $1, $#, $?, $$” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، مجموعه‌ای از متغیرهای خاص وجود دارند که به‌طور خودکار توسط سیستم به‌روزرسانی می‌شوند و اطلاعات مفیدی در مورد وضعیت اسکریپت یا فرآیندهای در حال اجرا فراهم می‌کنند. این متغیرها بسیار مفید هستند و در بسیاری از مواقع برای پردازش آرگومان‌ها، بررسی وضعیت اجرای دستورات، یا ذخیره PID (شناسه فرآیند) استفاده می‌شوند.


1. $0: نام اسکریپت

متغیر $0 حاوی نام اسکریپت یا برنامه‌ای است که در حال اجراست. این متغیر معمولاً برای چاپ یا نمایش نام اسکریپت در هنگام اشکال‌زدایی و مستندسازی کاربرد دارد.

مثال:

#!/bin/bash
echo "This script is called: $0"

🔴 خروجی:

This script is called: ./my_script.sh

در این مثال، نام اسکریپت ($0) که در حال اجرای آن هستیم چاپ می‌شود.


2. $1, $2, $3, … : آرگومان‌های ورودی به اسکریپت

این متغیرها مقادیر آرگومان‌هایی که هنگام اجرای اسکریپت به آن ارسال می‌شوند را ذخیره می‌کنند. به‌طور مثال، $1 اولین آرگومان، $2 دومین آرگومان، و به همین ترتیب برای باقی آرگومان‌ها می‌باشد.

مثال:

#!/bin/bash
echo "First argument: $1"
echo "Second argument: $2"

اجرای اسکریپت به‌صورت زیر:

./my_script.sh arg1 arg2

🔴 خروجی:

First argument: arg1
Second argument: arg2

در این مثال، متغیر $1 و $2 مقادیر "arg1" و "arg2" را ذخیره می‌کنند.


3. $#: تعداد آرگومان‌های ورودی

متغیر $# تعداد آرگومان‌هایی را که به اسکریپت ارسال شده است نشان می‌دهد. این متغیر به‌ویژه زمانی مفید است که بخواهید بررسی کنید که آیا تعداد کافی آرگومان‌ها برای اجرای اسکریپت وارد شده است یا خیر.

مثال:

#!/bin/bash
echo "Number of arguments: $#"

اجرای اسکریپت به‌صورت زیر:

./my_script.sh arg1 arg2

🔴 خروجی:

Number of arguments: 2

در اینجا، متغیر $# تعداد آرگومان‌های وارد شده را نشان می‌دهد که برابر با ۲ است.


4. $?: وضعیت آخرین دستور اجرا شده

متغیر $? حاوی کد وضعیت آخرین دستور اجرا شده است. این کد وضعیت معمولاً برای بررسی موفقیت یا شکست اجرای دستور استفاده می‌شود. به‌طور کلی، اگر دستور با موفقیت اجرا شود، این مقدار برابر با 0 خواهد بود. اگر دستور با خطا مواجه شود، مقدار غیر صفر را برمی‌گرداند.

مثال:

#!/bin/bash
echo "Running a command"
ls /nonexistent_directory
echo "Last command exit status: $?"

🔴 خروجی:

Running a command
ls: cannot access '/nonexistent_directory': No such file or directory
Last command exit status: 2

در اینجا، دستور ls به دلیل وجود نداشتن دایرکتوری به خطا می‌افتد و متغیر $? وضعیت آن را (عدد 2 که نمایانگر خطای خاص است) چاپ می‌کند.


5. $$: شناسه فرآیند (PID) اسکریپت جاری

متغیر $$ شناسه فرآیند (PID) اسکریپت یا برنامه‌ای است که در حال اجراست. این متغیر معمولاً برای شناسایی یا پردازش‌های خاصی مانند نوشتن فایل‌های گزارش یا تخصیص نام‌های منحصر به‌فرد در سیستم‌های چندفرآیندی کاربرد دارد.

مثال:

#!/bin/bash
echo "Current script PID: $$"

🔴 خروجی:

Current script PID: 12345

در اینجا، متغیر $$ شناسه فرآیند اسکریپت را نمایش می‌دهد که در سیستم‌عامل در حال اجراست.


جمع‌بندی

متغیرهای خاص در شل ابزارهایی قدرتمند هستند که به شما کمک می‌کنند اطلاعات مهمی مانند نام اسکریپت، آرگومان‌های ورودی، تعداد آرگومان‌ها، وضعیت آخرین دستور، و شناسه فرآیند را دریافت کنید. این متغیرها در اسکریپت‌نویسی بسیار کاربردی بوده و باعث می‌شوند که شما بتوانید اسکریپت‌های خود را انعطاف‌پذیرتر، مؤثرتر و قابل اشکال‌زدایی‌تر بنویسید.

مزایای استفاده از متغیرهای خاص:

  • دسترسی آسان به اطلاعات مهم در مورد اسکریپت و فرآیندهای آن.
  • امکان بررسی وضعیت دستورات و مدیریت خطاها.
  • استفاده در پیاده‌سازی‌های پیچیده‌تر مانند پردازش آرگومان‌ها و پیگیری فرآیندها.

[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”کاربرد هر متغیر خاص در سناریوهای عملی” subtitle=”توضیحات کامل”]در ادامه، به بررسی کاربردهای عملی هر یک از متغیرهای خاص در شل می‌پردازیم. این متغیرها می‌توانند در سناریوهای مختلف بسیار مفید باشند و به شما در نوشتن اسکریپت‌های کارآمدتر و انعطاف‌پذیرتر کمک کنند.


1. $0: نام اسکریپت

متغیر $0 نام اسکریپت یا برنامه‌ای که در حال اجرا است را ذخیره می‌کند. این متغیر به‌ویژه در مواقعی که نیاز دارید نام اسکریپت خود را در پیغام‌ها یا گزارش‌ها نشان دهید، بسیار کاربردی است.

سناریو عملی: نمایش نام اسکریپت در پیغام‌ها

فرض کنید می‌خواهید اسکریپتی بنویسید که اطلاعاتی درباره خود اسکریپت را نمایش دهد، مثل نام اسکریپت و ورژن آن.

#!/bin/bash
echo "This is the script: $0"
echo "Version 1.0"

در اینجا، متغیر $0 نام اسکریپت را نشان می‌دهد و می‌توانید از آن برای نمایش اطلاعات مفید به کاربران استفاده کنید.


2. $1, $2, … : آرگومان‌های ورودی به اسکریپت

این متغیرها مقادیر ورودی به اسکریپت را نشان می‌دهند. این آرگومان‌ها به‌ویژه زمانی که اسکریپت نیاز به ورودی از کاربر داشته باشد یا شما بخواهید عملیاتی را بر اساس ورودی انجام دهید، مفید هستند.

سناریو عملی: استفاده از آرگومان‌ها برای انجام عملیاتی خاص

فرض کنید اسکریپت شما نیاز به گرفتن دو عدد از کاربر دارد و سپس مجموع آن‌ها را محاسبه می‌کند.

#!/bin/bash
echo "The sum of $1 and $2 is: $(($1 + $2))"

اجرای اسکریپت به‌صورت زیر:

./sum_script.sh 5 10

🔴 خروجی:

The sum of 5 and 10 is: 15

در اینجا، $1 و $2 به ترتیب نمایانگر اولین و دومین آرگومان وارد شده به اسکریپت هستند و عملیات جمع را انجام می‌دهند.


3. $#: تعداد آرگومان‌های ورودی

متغیر $# تعداد آرگومان‌های وارد شده به اسکریپت را نشان می‌دهد. این متغیر برای اعتبارسنجی تعداد ورودی‌های دریافتی از کاربر استفاده می‌شود.

سناریو عملی: بررسی تعداد آرگومان‌های وارد شده و پیغام خطا در صورت نادرست بودن تعداد آن‌ها

فرض کنید یک اسکریپت نیاز دارد که دقیقاً دو آرگومان ورودی دریافت کند. در صورتی که تعداد آرگومان‌ها صحیح نباشد، باید پیغام خطا نمایش داده شود.

#!/bin/bash
if [ $# -ne 2 ]; then
  echo "Error: You need to provide exactly two arguments."
  exit 1
fi
echo "First argument: $1"
echo "Second argument: $2"

🔴 خروجی در صورت وارد کردن تعداد آرگومان‌های نادرست:

Error: You need to provide exactly two arguments.

در این مثال، اگر تعداد آرگومان‌ها کمتر یا بیشتر از ۲ باشد، اسکریپت پیغام خطا را نشان می‌دهد.


4. $?: وضعیت آخرین دستور اجرا شده

این متغیر نشان‌دهنده وضعیت خروجی آخرین دستور است. اگر دستور موفق باشد، مقدار آن 0 است و اگر خطا رخ دهد، مقداری غیر صفر خواهد داشت. این متغیر برای تشخیص موفقیت یا شکست دستورات استفاده می‌شود.

سناریو عملی: بررسی موفقیت یا شکست یک دستور

فرض کنید می‌خواهید اسکریپتی بنویسید که تلاش می‌کند یک فایل را پیدا کند و پس از آن وضعیت فایل را گزارش کند.

#!/bin/bash
cat $1
if [ $? -eq 0 ]; then
  echo "File was displayed successfully."
else
  echo "Error: File not found or unreadable."
fi

اجرای اسکریپت به‌صورت زیر:

./check_file.sh my_file.txt

🔴 خروجی در صورت موفقیت:

File was displayed successfully.

🔴 خروجی در صورت خطا:

Error: File not found or unreadable.

در اینجا، متغیر $? برای بررسی اینکه آیا دستور cat با موفقیت اجرا شده است یا خیر استفاده می‌شود.


5. $$: شناسه فرآیند (PID) اسکریپت جاری

متغیر $$ شناسه فرآیند اسکریپت جاری را ذخیره می‌کند. این متغیر برای شناسایی فرآیند اسکریپت در سیستم یا برای نوشتن فایل‌های گزارش اختصاصی برای هر فرآیند کاربرد دارد.

سناریو عملی: استفاده از PID برای گزارش‌دهی یا ردیابی فرآیند

فرض کنید می‌خواهید برای هر اسکریپت در حال اجرا یک فایل گزارش ایجاد کنید که نام آن شامل شناسه فرآیند (PID) باشد تا از تداخل نام‌ها جلوگیری شود.

#!/bin/bash
logfile="process_log_$$.txt"
echo "Logging started for process $$" > $logfile

در اینجا، متغیر $$ برای ایجاد یک فایل گزارش منحصر به‌فرد برای هر اجرای اسکریپت استفاده می‌شود.


جمع‌بندی

متغیرهای خاص در شل می‌توانند در انواع سناریوهای عملی بسیار مفید واقع شوند. این متغیرها ابزارهایی قدرتمند برای مدیریت آرگومان‌ها، پیگیری وضعیت دستورات، شناسایی فرآیندها و گزارش‌دهی در اسکریپت‌ها هستند. با استفاده صحیح از این متغیرها، می‌توانید اسکریپت‌های خود را انعطاف‌پذیرتر و مؤثرتر کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 8. عیب‌یابی و اشکال‌زدایی متغیرها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از set -u برای هشدار در مورد متغیرهای تعریف‌نشده” subtitle=”توضیحات کامل”]در شل اسکریپت‌نویسی، یکی از مشکلات رایج زمانی اتفاق می‌افتد که به اشتباه از متغیری استفاده می‌کنید که هنوز مقداردهی نشده است. این موضوع می‌تواند باعث بروز خطا یا رفتار غیرمنتظره در اسکریپت شود. به‌ویژه زمانی که متغیرها از ورودی‌های کاربر یا سایر منابع دریافت می‌شوند، خطاهای ناشی از متغیرهای تعریف‌نشده می‌توانند مشکلات زیادی ایجاد کنند.

برای جلوگیری از این مشکلات، می‌توانید از دستور set -u در شل استفاده کنید. این دستور باعث می‌شود که هر زمان متغیر تعریف‌نشده‌ای استفاده شود، شل بلافاصله خطا دهد و اسکریپت متوقف شود.


نحوه استفاده از set -u

با فعال‌سازی گزینه -u، هر بار که اسکریپت به یک متغیر تعریف‌نشده دسترسی پیدا کند، پیغام خطا نمایش داده خواهد شد و اسکریپت قطع می‌شود.

نحوه فعال‌سازی set -u:

#!/bin/bash
set -u  # فعال‌سازی هشدار برای متغیرهای تعریف‌نشده

در این حالت، هر زمان که اسکریپت به متغیر تعریف‌نشده‌ای اشاره کند، خطای زیر را مشاهده خواهید کرد:

./script.sh: line 4: my_var: unbound variable

مثال عملی: هشدار برای متغیر تعریف‌نشده

فرض کنید می‌خواهید یک اسکریپت بنویسید که ورودی‌هایی را از کاربر دریافت کرده و آن‌ها را در متغیرهای مختلف ذخیره کند. اما اگر یکی از متغیرها تعریف نشده باشد، با استفاده از set -u می‌توانید از بروز خطا جلوگیری کنید.

#!/bin/bash
set -u  # فعال‌سازی هشدار برای متغیرهای تعریف‌نشده

echo "Enter your name: "
read name

echo "Enter your age: "
read age

# استفاده از متغیرهایی که ممکن است تعریف نشده باشند
echo "Hello, my name is $name and I am $age years old."

اگر یکی از این متغیرها (مثلاً age) در هنگام اجرا وارد نشود، با پیغام خطا مواجه خواهید شد:

./script.sh: line 12: age: unbound variable

توجه: مدیریت خطاها با استفاده از set -u

اگر قصد دارید که اسکریپت را به گونه‌ای بنویسید که در صورت بروز خطای متغیر تعریف‌نشده، پیام مناسبی برای کاربر نمایش دهد و اسکریپت متوقف نشود، می‌توانید از دستور set +u برای غیرفعال کردن این ویژگی در بخش‌های خاصی از اسکریپت استفاده کنید.

مثال: غیرفعال کردن set -u در شرایط خاص

#!/bin/bash
set -u  # فعال‌سازی هشدار برای متغیرهای تعریف‌نشده

echo "Enter your name: "
read name

# در صورتی که متغیر 'age' تعریف نشده باشد، از set +u استفاده می‌کنیم تا خطا را بگیریم
set +u
echo "Enter your age (optional): "
read age
set -u  # دوباره فعال‌سازی هشدار

echo "Hello, my name is $name and I am $age years old."

در این اسکریپت، تنها اگر متغیر name به درستی وارد نشود، اسکریپت متوقف می‌شود، اما برای متغیر age که ممکن است خالی بماند، خطا نمایش داده نمی‌شود.


جمع‌بندی

استفاده از set -u یک روش موثر برای جلوگیری از بروز مشکلات ناشی از متغیرهای تعریف‌نشده در اسکریپت‌های شل است. این گزینه به شما کمک می‌کند تا اسکریپت‌های پایدارتر و دقیق‌تری بنویسید و از اشتباهات رایج جلوگیری کنید. با این حال، در مواقع خاص که ممکن است نیاز به متغیرهای اختیاری داشته باشید، می‌توانید از set +u برای غیرفعال‌سازی موقت این ویژگی استفاده کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه شناسایی مشکلات مرتبط با متغیرها در اسکریپت‌ها” subtitle=”توضیحات کامل”]یکی از چالش‌های رایج در اسکریپت‌نویسی شل، مشکلاتی است که به دلیل استفاده نادرست از متغیرها ایجاد می‌شود. این مشکلات می‌توانند شامل اشتباهات در مقداردهی به متغیرها، استفاده از متغیرهای تعریف‌نشده، یا دسترسی اشتباه به مقادیر متغیرها باشند. این مسائل ممکن است باعث بروز خطاها یا رفتار غیرمنتظره در اسکریپت شوند.

برای شناسایی و رفع این مشکلات، ابزارها و تکنیک‌های مختلفی وجود دارد که می‌توانید از آن‌ها برای اشکال‌زدایی و بهبود کیفیت کد خود استفاده کنید.


1. استفاده از set -u برای شناسایی متغیرهای تعریف‌نشده

اگر در اسکریپت از متغیرهایی استفاده می‌کنید که ممکن است تعریف نشده باشند، می‌توانید از دستور set -u برای فعال‌سازی هشدار در صورت دسترسی به متغیرهای تعریف‌نشده استفاده کنید. با این کار، هر زمان که شل به یک متغیر تعریف‌نشده دسترسی پیدا کند، بلافاصله خطای «unbound variable» را گزارش می‌دهد و اسکریپت متوقف می‌شود.

مثال:

#!/bin/bash
set -u  # فعال‌سازی هشدار برای متغیرهای تعریف‌نشده

echo "Enter your name: "
read name

# اگر متغیر 'age' تعریف نشده باشد، خطا رخ خواهد داد
echo "Hello, my name is $name and I am $age years old."

اگر متغیر age تعریف نشده باشد، اسکریپت به‌طور خودکار متوقف می‌شود و پیغام خطای زیر نمایش داده می‌شود:

./script.sh: line 10: age: unbound variable

این روش به شما کمک می‌کند تا به‌راحتی مشکلات متغیرهای تعریف‌نشده را شناسایی کنید.


2. استفاده از set -x برای ردیابی دستورات

اگر می‌خواهید که در حین اجرای اسکریپت، دستورات آن را دنبال کنید و بررسی کنید که متغیرها در چه مقاطعی تغییر می‌کنند، می‌توانید از دستور set -x استفاده کنید. این دستور باعث می‌شود که هر دستور به همراه آرگومان‌ها و مقادیر آن چاپ شود. این ویژگی مفید است زمانی که می‌خواهید بدانید که متغیرها در کجا و چگونه مقداردهی شده‌اند.

مثال:

#!/bin/bash
set -x  # فعال‌سازی ردیابی دستورات

name="John"
age=25

echo "Hello, my name is $name and I am $age years old."

با فعال‌سازی set -x، خروجی اسکریپت به‌صورت زیر خواهد بود:

+ name=John
+ age=25
+ echo 'Hello, my name is John and I am 25 years old.'
Hello, my name is John and I am 25 years old.

این کار به شما کمک می‌کند تا بلافاصله متوجه شوید که مقادیر متغیرها در کجا تغییر کرده‌اند و آیا همه چیز به درستی انجام شده است.


3. استفاده از دستور echo برای بررسی مقدار متغیرها

یکی از ساده‌ترین روش‌ها برای شناسایی مشکلات مرتبط با متغیرها، استفاده از دستور echo است. با چاپ مقادیر متغیرها در نقاط مختلف اسکریپت، می‌توانید بررسی کنید که آیا مقادیر متغیرها به درستی به آن‌ها اختصاص داده شده‌اند یا خیر.

مثال:

#!/bin/bash

name="John"
age="25"

echo "Name: $name"
echo "Age: $age"

# تغییر مقدار متغیر
age="30"
echo "Updated Age: $age"

با این روش، مقادیر متغیرها در مراحل مختلف اجرای اسکریپت چاپ می‌شوند، و شما می‌توانید به‌راحتی متوجه شوید که آیا تغییرات به درستی اعمال شده‌اند یا خیر.


4. بررسی متغیرها با استفاده از دستورات شرطی

گاهی اوقات ممکن است بخواهید که ابتدا بررسی کنید که آیا متغیر مورد نظر به درستی تعریف شده یا نه، سپس عملیات خاصی انجام دهید. برای این کار می‌توانید از دستورات شرطی (مانند if) استفاده کنید.

مثال:

#!/bin/bash

if [ -z "$name" ]; then
  echo "Error: Name is not defined!"
  exit 1
fi

echo "Hello, $name!"

در این مثال، اگر متغیر name تعریف نشده یا خالی باشد (با استفاده از شرط -z)، پیغام خطا نمایش داده می‌شود و اسکریپت متوقف می‌شود.


5. بررسی خروجی دستور echo $? برای بررسی خطاهای دستوری

پس از هر دستور در شل، می‌توانید از دستور echo $? برای بررسی کد خروجی دستور قبلی استفاده کنید. کد خروجی 0 به معنای موفقیت‌آمیز بودن اجرای دستور است، و هر عدد دیگری نشان‌دهنده یک خطا است. این روش به شما کمک می‌کند تا مشکلات موجود در دستوراتی که به متغیرها بستگی دارند را شناسایی کنید.

مثال:

#!/bin/bash

name="John"

# اگر متغیر 'name' به درستی تعریف نشده باشد، دستور زیر خطا خواهد داد
echo $name
echo "Exit status: $?"  # کد خروجی دستور قبلی

در صورتی که متغیر name به درستی تعریف نشده باشد، خطای مربوطه نمایش داده می‌شود و کد خروجی غیر از ۰ خواهد بود.


جمع‌بندی

شناسایی مشکلات مرتبط با متغیرها در اسکریپت‌های شل می‌تواند به کمک تکنیک‌های مختلفی انجام شود. از استفاده از set -u برای هشدار در مورد متغیرهای تعریف‌نشده تا ردیابی دقیق دستورات با set -x و استفاده از echo برای بررسی مقادیر متغیرها، همه این روش‌ها ابزارهایی کارآمد برای شناسایی و رفع مشکلات هستند. این تکنیک‌ها به شما کمک می‌کنند تا اسکریپت‌هایی با کیفیت بالا و بدون خطا بنویسید.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش 4. عملگرها و دستورات شرطی”][cdb_course_lesson title=”فصل 1. مقدمه‌ای بر عملگرها در شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”آشنایی با عملگرهای ریاضی، منطقی، مقایسه‌ای و رشته‌ای در شل اسکریپتینگ” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، عملگرها نقش اساسی در انجام محاسبات، مقایسه مقادیر و تصمیم‌گیری در اجرای کد دارند. در این بخش، با انواع عملگرهای ریاضی، منطقی، مقایسه‌ای و رشته‌ای آشنا می‌شویم و نحوه استفاده از آن‌ها را همراه با مثال‌های عملی بررسی می‌کنیم.


۱. عملگرهای ریاضی در شل

عملگرهای ریاضی برای انجام محاسبات عددی استفاده می‌شوند. شل به‌طور پیش‌فرض فقط عملیات حسابی ساده را پشتیبانی می‌کند، اما برای محاسبات پیچیده‌تر می‌توان از ابزارهایی مانند expr، let و $(( )) استفاده کرد.

عملگرهای ریاضی اصلی
عملگر توضیح مثال
+ جمع echo $((3 + 5)) → خروجی: 8
- تفریق echo $((10 - 2)) → خروجی: 8
* ضرب echo $((4 * 3)) → خروجی: 12
/ تقسیم (عدد صحیح) echo $((9 / 2)) → خروجی: 4
% باقی‌مانده echo $((10 % 3)) → خروجی: 1
** توان echo $((2**3)) → خروجی: 8
مثال عملی: انجام عملیات ریاضی در شل
#!/bin/bash
num1=10
num2=5

sum=$((num1 + num2))
difference=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))
remainder=$((num1 % num2))

echo "جمع: $sum"
echo "تفریق: $difference"
echo "ضرب: $product"
echo "تقسیم: $quotient"
echo "باقی‌مانده: $remainder"

۲. عملگرهای مقایسه‌ای در شل

عملگرهای مقایسه‌ای برای مقایسه مقادیر استفاده می‌شوند و معمولاً در شرط‌ها (if، while و …) به کار می‌روند.

عملگرهای مقایسه‌ای عددی
عملگر توضیح مثال
-eq برابر با [ 5 -eq 5 ]True
-ne نابرابر [ 5 -ne 3 ]True
-gt بزرگ‌تر از [ 10 -gt 5 ]True
-lt کوچک‌تر از [ 3 -lt 7 ]True
-ge بزرگ‌تر یا مساوی [ 10 -ge 10 ]True
-le کوچک‌تر یا مساوی [ 2 -le 5 ]True
مثال عملی: استفاده از عملگرهای مقایسه‌ای
#!/bin/bash
num1=10
num2=20

if [ $num1 -lt $num2 ]; then
  echo "$num1 کوچکتر از $num2 است."
else
  echo "$num1 بزرگتر یا مساوی $num2 است."
fi

۳. عملگرهای منطقی در شل

عملگرهای منطقی برای ترکیب چندین شرط به‌کار می‌روند. این عملگرها شامل AND، OR و NOT هستند.

عملگر توضیح مثال
&& یا -a AND (همه شرط‌ها باید درست باشند) [ $a -gt 5 ] && [ $a -lt 10 ]
` یا-o`
! NOT (معکوس شرط) [ ! $a -eq 10 ]
مثال عملی: استفاده از عملگرهای منطقی
#!/bin/bash
num=15

if [ $num -gt 10 ] && [ $num -lt 20 ]; then
  echo "$num بین 10 و 20 است."
fi

if [ $num -eq 10 ] || [ $num -eq 15 ]; then
  echo "$num مقدار 10 یا 15 دارد."
fi

if [ ! $num -eq 5 ]; then
  echo "$num برابر 5 نیست."
fi

۴. عملگرهای رشته‌ای در شل

عملگرهای رشته‌ای برای مقایسه و کار با رشته‌ها استفاده می‌شوند.

عملگر توضیح مثال
= برابر بودن دو رشته [ "$str1" = "$str2" ]
!= نابرابر بودن دو رشته [ "$str1" != "$str2" ]
-z بررسی خالی بودن رشته [ -z "$str" ]True اگر $str خالی باشد
-n بررسی غیرخالی بودن رشته [ -n "$str" ]True اگر $str مقدار داشته باشد
مثال عملی: بررسی مقادیر رشته‌ای
#!/bin/bash
name="Ali"

if [ "$name" = "Ali" ]; then
  echo "نام برابر با Ali است."
fi

if [ -n "$name" ]; then
  echo "متغیر name مقدار دارد."
fi

if [ -z "$empty_string" ]; then
  echo "متغیر empty_string خالی است."
fi

۵. ترکیب عملگرهای مختلف در اسکریپت‌ها

گاهی لازم است که چندین نوع عملگر را در یک اسکریپت ترکیب کنیم. به‌عنوان مثال، می‌توانیم از عملگرهای ریاضی، منطقی و مقایسه‌ای در یک اسکریپت برای بررسی مقدار ورودی کاربر استفاده کنیم.

مثال: بررسی سن کاربر و نمایش پیام مناسب

#!/bin/bash

echo "لطفاً سن خود را وارد کنید: "
read age

if [ $age -ge 18 ] && [ $age -lt 65 ]; then
  echo "شما در سن کار هستید."
elif [ $age -lt 18 ]; then
  echo "شما هنوز کودک هستید."
else
  echo "شما بازنشسته هستید."
fi

خروجی‌های احتمالی:

لطفاً سن خود را وارد کنید: 
25
شما در سن کار هستید.
لطفاً سن خود را وارد کنید: 
70
شما بازنشسته هستید.

جمع‌بندی

در این بخش، با انواع عملگرها در شل اسکریپتینگ آشنا شدیم:

  • عملگرهای ریاضی برای انجام محاسبات عددی.
  • عملگرهای مقایسه‌ای برای مقایسه اعداد.
  • عملگرهای منطقی برای ترکیب شرط‌ها.
  • عملگرهای رشته‌ای برای بررسی و مقایسه رشته‌ها.

با استفاده از این عملگرها، می‌توانیم اسکریپت‌های قدرتمندی برای پردازش داده‌ها و انجام تصمیم‌گیری‌های هوشمند ایجاد کنیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از عملگرهای فایل برای بررسی خصوصیات فایل‌ها” subtitle=”توضیحات کامل”]عملگرهای فایل در شل اسکریپتینگ ابزاری مفید برای بررسی خصوصیات فایل‌ها و دایرکتوری‌ها هستند. این عملگرها به‌ویژه در زمانی که نیاز به انجام عملیات خاصی بر روی فایل‌ها داریم، بسیار کاربردی‌اند. به کمک این عملگرها می‌توانیم بررسی کنیم که آیا یک فایل موجود است یا خیر، آیا فایل یک دایرکتوری است، آیا فایل قابل خواندن یا نوشتن است، و موارد دیگری که در مدیریت فایل‌ها اهمیت دارند.

در این بخش، به معرفی مهم‌ترین عملگرهای فایل می‌پردازیم و همراه با مثال‌های عملی نحوه استفاده از آن‌ها را بررسی می‌کنیم.


۱. عملگرهای فایل در شل

عملگرهای فایل برای بررسی ویژگی‌های مختلف یک فایل یا دایرکتوری به‌کار می‌روند. در اینجا مهم‌ترین عملگرهای فایل آورده شده است:

عملگر توضیح مثال
-e بررسی وجود فایل یا دایرکتوری [ -e filename ]
-f بررسی فایل معمولی (نه دایرکتوری یا فایل خاص دیگر) [ -f filename ]
-d بررسی دایرکتوری بودن [ -d directory ]
-r بررسی قابل خواندن بودن فایل [ -r filename ]
-w بررسی قابل نوشتن بودن فایل [ -w filename ]
-x بررسی قابل اجرا بودن فایل [ -x filename ]
-s بررسی اینکه فایل خالی نیست [ -s filename ]
-L بررسی لینک نرم‌افزاری بودن [ -L filename ]

۲. مثال‌های عملی از عملگرهای فایل

بررسی وجود فایل یا دایرکتوری

عملگر -e برای بررسی وجود یک فایل یا دایرکتوری استفاده می‌شود. این عملگر به شما کمک می‌کند تا قبل از انجام عملیات، مطمئن شوید که فایل یا دایرکتوری مورد نظر موجود است.

#!/bin/bash
if [ -e "test.txt" ]; then
  echo "فایل test.txt وجود دارد."
else
  echo "فایل test.txt وجود ندارد."
fi

خروجی‌های ممکن:

  • اگر فایل test.txt موجود باشد:
    فایل test.txt وجود دارد.
    
  • اگر فایل test.txt موجود نباشد:
    فایل test.txt وجود ندارد.
    
بررسی فایل معمولی بودن

اگر بخواهید بررسی کنید که آیا یک فایل معمولی است (یعنی نه دایرکتوری و نه فایل خاص دیگری)، می‌توانید از عملگر -f استفاده کنید.

#!/bin/bash
if [ -f "test.txt" ]; then
  echo "test.txt یک فایل معمولی است."
else
  echo "test.txt یک فایل معمولی نیست."
fi
بررسی دایرکتوری بودن

برای بررسی اینکه یک مسیر خاص یک دایرکتوری است، از عملگر -d استفاده می‌کنیم.

#!/bin/bash
if [ -d "mydir" ]; then
  echo "mydir یک دایرکتوری است."
else
  echo "mydir یک دایرکتوری نیست."
fi
بررسی قابل خواندن بودن فایل

اگر بخواهید بررسی کنید که آیا یک فایل قابل خواندن است یا خیر، می‌توانید از عملگر -r استفاده کنید.

#!/bin/bash
if [ -r "test.txt" ]; then
  echo "فایل test.txt قابل خواندن است."
else
  echo "فایل test.txt قابل خواندن نیست."
fi
بررسی قابل نوشتن بودن فایل

برای بررسی اینکه آیا یک فایل قابل نوشتن است یا خیر، از عملگر -w استفاده می‌کنیم.

#!/bin/bash
if [ -w "test.txt" ]; then
  echo "فایل test.txt قابل نوشتن است."
else
  echo "فایل test.txt قابل نوشتن نیست."
fi
بررسی قابل اجرا بودن فایل

اگر بخواهید بررسی کنید که آیا یک فایل قابل اجرا است (برای مثال یک اسکریپت یا برنامه اجرایی)، از عملگر -x استفاده می‌کنیم.

#!/bin/bash
if [ -x "script.sh" ]; then
  echo "فایل script.sh قابل اجرا است."
else
  echo "فایل script.sh قابل اجرا نیست."
fi
بررسی اینکه فایل خالی نیست

عملگر -s برای بررسی اینکه فایل دارای محتوی است و خالی نیست، استفاده می‌شود.

#!/bin/bash
if [ -s "test.txt" ]; then
  echo "فایل test.txt خالی نیست."
else
  echo "فایل test.txt خالی است."
fi
بررسی لینک نرم‌افزاری بودن

برای بررسی اینکه یک فایل یک لینک نرم‌افزاری است یا خیر، از عملگر -L استفاده می‌کنیم.

#!/bin/bash
if [ -L "mylink" ]; then
  echo "mylink یک لینک نرم‌افزاری است."
else
  echo "mylink یک لینک نرم‌افزاری نیست."
fi

۳. ترکیب عملگرهای فایل با دستورات شرطی

عملگرهای فایل می‌توانند با دستورات شرطی مثل if و while ترکیب شوند تا عملیات پیچیده‌تری انجام دهند. به‌عنوان مثال، می‌توانید بررسی کنید که آیا فایل موجود است و در عین حال قابل خواندن و قابل اجرا نیز هست.

#!/bin/bash
if [ -e "script.sh" ] && [ -r "script.sh" ] && [ -x "script.sh" ]; then
  echo "فایل script.sh موجود، قابل خواندن و قابل اجرا است."
else
  echo "فایل script.sh مشکل دارد."
fi

جمع‌بندی

در این بخش، با عملگرهای فایل در شل اسکریپتینگ آشنا شدیم. این عملگرها به ما کمک می‌کنند تا ویژگی‌های مختلف فایل‌ها و دایرکتوری‌ها را بررسی کنیم، از جمله:

  • بررسی وجود یا عدم وجود فایل.
  • بررسی اینکه فایل یک فایل معمولی، دایرکتوری یا لینک نرم‌افزاری است.
  • بررسی ویژگی‌های دسترسی مانند قابل خواندن، قابل نوشتن و قابل اجرا بودن فایل‌ها.

این ابزارها در مدیریت فایل‌ها و انجام عملیات شرطی بر روی آن‌ها بسیار کاربردی هستند و به شما امکان می‌دهند که اسکریپت‌هایی منعطف و قدرتمند بنویسید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. دستورات شرطی اصلی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ساختار دستور if-else” subtitle=”توضیحات کامل”]در شل اسکریپتینگ، دستور if-else برای انجام تصمیم‌گیری‌ها و اجرای بخش‌های مختلف کد بر اساس شرایط مختلف استفاده می‌شود. این دستور به شما امکان می‌دهد که بسته به نتیجه یک یا چند شرط، مسیری خاص از کد را اجرا کنید.

در این بخش، به توضیح ساختار دستور if-else و نحوه استفاده از آن همراه با مثال‌های کاربردی می‌پردازیم.


۱. ساختار کلی دستور if-else

ساختار اصلی دستور if-else به این صورت است:

if [ condition ]; then
  # دستوراتی که در صورت درست بودن شرط اجرا می‌شوند
else
  # دستوراتی که در صورت نادرست بودن شرط اجرا می‌شوند
fi
  • [ condition ]: شرطی است که بررسی می‌شود.
  • then: پس از آن دستورات مربوط به شرایط درست اجرا می‌شوند.
  • else: اگر شرط درست نباشد، دستورات پس از else اجرا می‌شوند.
  • fi: این کلمه کلیدی نشان‌دهنده پایان ساختار if-else است.

۲. استفاده از دستورات شرطی برای تصمیم‌گیری

در مثال‌های زیر، نحوه استفاده از دستور if-else برای انجام عملیات مختلف بر اساس شرایط مختلف را بررسی می‌کنیم.

۲.۱. مثال ساده با استفاده از دستور if-else

در این مثال، بررسی می‌شود که آیا یک عدد بزرگتر از 10 است یا خیر. اگر شرط درست باشد، پیغام “عدد بزرگتر از 10 است” نمایش داده می‌شود و در غیر این صورت پیغام “عدد کمتر از یا مساوی 10 است” نشان داده می‌شود.

#!/bin/bash

number=5

if [ $number -gt 10 ]; then
  echo "عدد بزرگتر از 10 است."
else
  echo "عدد کمتر از یا مساوی 10 است."
fi

خروجی:

عدد کمتر از یا مساوی 10 است.
۲.۲. مثال با استفاده از دستور if-else برای بررسی وجود فایل

در این مثال، بررسی می‌شود که آیا فایل test.txt موجود است یا خیر. اگر موجود باشد، پیغام “فایل موجود است” چاپ می‌شود، و در غیر این صورت پیغام “فایل موجود نیست” نمایش داده می‌شود.

#!/bin/bash

if [ -e "test.txt" ]; then
  echo "فایل موجود است."
else
  echo "فایل موجود نیست."
fi

خروجی‌ها:

  • اگر فایل test.txt موجود باشد:
    فایل موجود است.
    
  • اگر فایل test.txt موجود نباشد:
    فایل موجود نیست.
    
۲.۳. استفاده از elif برای شرایط چندگانه

اگر بخواهید چندین شرط را بررسی کنید، می‌توانید از دستور elif (else if) برای اضافه کردن شرایط اضافی استفاده کنید.

#!/bin/bash

number=15

if [ $number -gt 20 ]; then
  echo "عدد بزرگتر از 20 است."
elif [ $number -eq 15 ]; then
  echo "عدد برابر با 15 است."
else
  echo "عدد کمتر از 15 است."
fi

خروجی:

عدد برابر با 15 است.

۳. مقایسه‌ی دستورات و عملگرهای شرطی در if-else

در دستورات شرطی if، می‌توانید از عملگرهای مختلف برای مقایسه مقادیر استفاده کنید. این عملگرها می‌توانند برای مقایسه عددی، رشته‌ای، یا حتی برای بررسی ویژگی‌های فایل‌ها به‌کار روند.

۳.۱. عملگرهای عددی
عملگر توضیح مثال
-eq برابر با [ $a -eq $b ]
-ne نابرابر با [ $a -ne $b ]
-gt بزرگتر از [ $a -gt $b ]
-lt کوچکتر از [ $a -lt $b ]
-ge بزرگتر یا برابر با [ $a -ge $b ]
-le کوچکتر یا برابر با [ $a -le $b ]
۳.۲. عملگرهای رشته‌ای
عملگر توضیح مثال
= برابر با [ "$str1" = "$str2" ]
!= نابرابر با [ "$str1" != "$str2" ]
-z رشته خالی [ -z "$str" ]
-n رشته غیر خالی [ -n "$str" ]
۳.۳. عملگرهای فایل

عملگرهای فایل به‌طور ویژه برای بررسی ویژگی‌های فایل‌ها استفاده می‌شوند و به‌طور معمول در ترکیب با دستور if برای انجام عملیات خاص مورد استفاده قرار می‌گیرند. به‌عنوان مثال:

#!/bin/bash

if [ -f "myfile.txt" ]; then
  echo "myfile.txt یک فایل معمولی است."
else
  echo "myfile.txt یک فایل معمولی نیست."
fi

۴. استفاده از عملگرهای منطقی در if-else

شما می‌توانید از عملگرهای منطقی برای ترکیب چندین شرط در دستورات if استفاده کنید.

عملگر توضیح مثال
&& AND منطقی [ condition1 ] && [ condition2 ]
` `
مثال: ترکیب دو شرط با && (AND منطقی)
#!/bin/bash

a=10
b=20

if [ $a -gt 5 ] && [ $b -lt 30 ]; then
  echo "هر دو شرط درست هستند."
else
  echo "یکی از شرایط نادرست است."
fi

خروجی:

هر دو شرط درست هستند.
مثال: ترکیب دو شرط با || (OR منطقی)
#!/bin/bash

a=10
b=5

if [ $a -gt 5 ] || [ $b -gt 10 ]; then
  echo "حداقل یکی از شرایط درست است."
else
  echo "هیچ‌کدام از شرایط درست نیستند."
fi

خروجی:

حداقل یکی از شرایط درست است.

جمع‌بندی

در این بخش، با دستور if-else و نحوه استفاده از آن در شل اسکریپتینگ آشنا شدیم. این دستور به شما این امکان را می‌دهد که با توجه به نتایج شرایط مختلف، قسمت‌های مختلفی از کد را اجرا کنید.

ما همچنین با عملگرهای شرطی مختلف (عدد، رشته، فایل) و همچنین عملگرهای منطقی (AND و OR) آشنا شدیم. این ابزارها به شما این امکان را می‌دهند که اسکریپت‌هایی پیچیده‌تر و انعطاف‌پذیرتر بنویسید و به‌طور دقیق‌تری رفتار سیستم را کنترل کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از elif برای بررسی شرایط چندگانه” subtitle=”توضیحات کامل”]در شل اسکریپتینگ، زمانی که بخواهیم چندین شرط مختلف را بررسی کنیم، به‌جای استفاده از چندین دستور if جداگانه، می‌توانیم از دستور elif (که مخفف else if است) برای بررسی شرایط مختلف به‌صورت پشت سر هم استفاده کنیم. این امر موجب می‌شود که کد خواناتر و کاراتر باشد، چرا که شما می‌توانید تمامی شرایط ممکن را در یک ساختار به‌صورت منطقی مدیریت کنید.


۱. ساختار کلی دستور if-elif-else

ساختار کلی استفاده از if-elif-else به این صورت است:

if [ condition1 ]; then
  # دستورات برای شرط اول
elif [ condition2 ]; then
  # دستورات برای شرط دوم
elif [ condition3 ]; then
  # دستورات برای شرط سوم
else
  # دستورات برای زمانی که هیچ‌کدام از شرایط درست نباشند
fi
  • if: برای بررسی اولین شرط.
  • elif: برای بررسی شرایط اضافی (می‌توانید چندین elif داشته باشید).
  • else: برای زمانی که هیچ‌کدام از شرایط قبلی درست نباشند.
  • fi: پایان ساختار if-else در شل.

۲. مثال‌هایی از استفاده از elif

۲.۱. مثال ساده با elif

در این مثال، بررسی می‌شود که یک عدد کدام‌یک از سه حالت زیر را دارد:

  • بزرگتر از 10
  • برابر با 10
  • کوچکتر از 10
#!/bin/bash

number=15

if [ $number -gt 10 ]; then
  echo "عدد بزرگتر از 10 است."
elif [ $number -eq 10 ]; then
  echo "عدد برابر با 10 است."
else
  echo "عدد کوچکتر از 10 است."
fi

خروجی:

عدد بزرگتر از 10 است.

در این مثال، ابتدا بررسی می‌شود که آیا عدد بزرگتر از 10 است. اگر درست نباشد، دستور elif بررسی می‌کند که آیا عدد برابر با 10 است. اگر هیچ‌کدام از این دو شرط درست نباشد، دستور else اجرا می‌شود.

۲.۲. مثال با استفاده از elif برای بررسی وضعیت یک فایل

در این مثال، بررسی می‌شود که آیا یک فایل موجود است و اگر موجود نباشد، بررسی می‌شود که آیا دایرکتوری است یا خیر.

#!/bin/bash

file="testfile.txt"

if [ -e $file ]; then
  echo "فایل موجود است."
elif [ -d $file ]; then
  echo "این یک دایرکتوری است."
else
  echo "فایل یا دایرکتوری وجود ندارد."
fi

خروجی‌ها:

  • اگر testfile.txt موجود باشد:
    فایل موجود است.
    
  • اگر testfile.txt یک دایرکتوری باشد:
    این یک دایرکتوری است.
    
  • اگر هیچ‌کدام از شرایط درست نباشد:
    فایل یا دایرکتوری وجود ندارد.
    
۲.۳. مثال با استفاده از elif برای بررسی وضعیت کاربر

در این مثال، بررسی می‌شود که آیا کاربر وارد شده به سیستم، کاربر ریشه (root) است یا نه.

#!/bin/bash

user=$(whoami)

if [ "$user" = "root" ]; then
  echo "شما کاربر ریشه (root) هستید."
elif [ "$user" = "admin" ]; then
  echo "شما کاربر مدیر (admin) هستید."
else
  echo "شما یک کاربر معمولی هستید."
fi

خروجی‌ها:

  • اگر کاربر ریشه باشد:
    شما کاربر ریشه (root) هستید.
    
  • اگر کاربر مدیر باشد:
    شما کاربر مدیر (admin) هستید.
    
  • در غیر این صورت:
    شما یک کاربر معمولی هستید.
    

۳. نکات مهم در استفاده از elif

  • ترتیب بررسی شرایط مهم است. اولین شرطی که درست باشد اجرا می‌شود و بعد از آن دیگر دستورات elif و else نادیده گرفته می‌شوند.
  • شما می‌توانید از هر تعداد elif که نیاز دارید، استفاده کنید.
  • در صورت نیاز، می‌توانید شرط‌های پیچیده‌ای را در if و elif به‌کار ببرید.
  • اگر هیچ‌کدام از شرایط درست نباشد، دستور else اجرا می‌شود (در صورتی که else وجود داشته باشد).

جمع‌بندی

در این بخش، با استفاده از دستور if-elif-else برای مدیریت چندین شرط مختلف آشنا شدیم. این ساختار به شما این امکان را می‌دهد که شرایط مختلف را به‌طور منظم و خوانا بررسی کنید و به‌طور مؤثری تصمیمات مختلف را در اسکریپت‌های خود بگیرید.

از elif برای افزودن شرایط اضافی به دستور if استفاده می‌شود، که این باعث می‌شود کد شما از لحاظ ساختار منطقی‌تر و ساده‌تر باشد. با استفاده از این دستور، می‌توانید برای شرایط پیچیده‌تر اسکریپت‌هایی بنویسید که قادر به انجام عملیات مختلف براساس وضعیت‌های متعدد هستند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”دستور case برای جایگزینی شرط‌های پیچیده” subtitle=”توضیحات کامل”]دستور case در شل اسکریپتینگ یک روش مفید برای جایگزینی چندین شرط پیچیده است که معمولاً از دستور if-elif-else استفاده می‌شود. این دستور به‌ویژه زمانی که با ورودی‌های مختلف و شناخته‌شده سر و کار داریم، می‌تواند کد را ساده‌تر و خواناتر کند.

در دستور case، شما می‌توانید چندین گزینه را برای یک متغیر بررسی کنید و براساس آن‌ها اقداماتی را انجام دهید. این دستور برای بررسی مقادیر خاص یا مطابقت با الگوها بسیار مفید است.


۱. ساختار کلی دستور case

ساختار کلی دستور case به‌صورت زیر است:

case $variable in
  pattern1)
    # دستورات برای pattern1
    ;;
  pattern2)
    # دستورات برای pattern2
    ;;
  pattern3)
    # دستورات برای pattern3
    ;;
  *)
    # دستورات پیش‌فرض در صورت عدم تطابق
    ;;
esac
  • variable: متغیری که می‌خواهید مقدار آن را بررسی کنید.
  • pattern: الگوی‌هایی که می‌خواهید با مقدار متغیر تطبیق دهید.
  • ;;: نشان‌دهنده پایان دستور مربوط به یک الگو.
  • *: برای مقدار پیش‌فرض استفاده می‌شود که در صورت عدم تطابق با هیچ الگوی دیگری اجرا می‌شود.
  • esac: معکوس case است و نشان‌دهنده پایان دستور case است.

۲. مثال‌هایی از استفاده از دستور case

۲.۱. مثال ساده با case

در این مثال، یک متغیر نام روز هفته را بررسی می‌کنیم و بر اساس آن پیامی چاپ می‌کنیم.

#!/bin/bash

day="Monday"

case $day in
  "Monday")
    echo "امروز روز دوشنبه است."
    ;;
  "Tuesday")
    echo "امروز روز سه‌شنبه است."
    ;;
  "Wednesday")
    echo "امروز روز چهارشنبه است."
    ;;
  *)
    echo "روز دیگری است."
    ;;
esac

خروجی:

امروز روز دوشنبه است.

در این مثال، day با الگوهای مختلف تطبیق داده می‌شود. اگر روز یکشنبه باشد، پیام مربوط به یکشنبه چاپ می‌شود، در غیر این صورت دستور پیش‌فرض اجرا می‌شود.

۲.۲. استفاده از الگوهای مختلف در case

در این مثال، ورودی کاربر را می‌گیریم و بر اساس آن پیامی چاپ می‌کنیم. از الگوهای wildcard (مانند * و ?) نیز استفاده می‌کنیم.

#!/bin/bash

echo "لطفاً یک کلمه وارد کنید:"
read word

case $word in
  [a-z]*)
    echo "کلمه‌ای با حرف کوچک وارد کردید."
    ;;
  [A-Z]*)
    echo "کلمه‌ای با حرف بزرگ وارد کردید."
    ;;
  ?*)
    echo "کلمه وارد شده حداقل یک حرف دارد."
    ;;
  *)
    echo "کلمه وارد شده خالی است."
    ;;
esac

خروجی‌ها:

  • اگر کاربر کلمه‌ای با حروف کوچک وارد کند:
    کلمه‌ای با حرف کوچک وارد کردید.
    
  • اگر کاربر کلمه‌ای با حرف بزرگ وارد کند:
    کلمه‌ای با حرف بزرگ وارد کردید.
    
  • اگر کاربر فقط یک حرف وارد کند:
    کلمه وارد شده حداقل یک حرف دارد.
    
  • اگر هیچ کلمه‌ای وارد نشود:
    کلمه وارد شده خالی است.
    
۲.۳. استفاده از دستور case برای بررسی ورودی‌های عددی

در این مثال، یک عدد وارد می‌شود و بر اساس آن پیامی چاپ می‌شود.

#!/bin/bash

echo "یک عدد وارد کنید:"
read number

case $number in
  1)
    echo "عدد یک وارد شده است."
    ;;
  2)
    echo "عدد دو وارد شده است."
    ;;
  3)
    echo "عدد سه وارد شده است."
    ;;
  *)
    echo "عدد دیگری وارد شده است."
    ;;
esac

خروجی‌ها:

  • اگر عدد 1 وارد شود:
    عدد یک وارد شده است.
    
  • اگر عدد 2 وارد شود:
    عدد دو وارد شده است.
    
  • اگر عدد 3 وارد شود:
    عدد سه وارد شده است.
    
  • در غیر این صورت:
    عدد دیگری وارد شده است.
    

۳. نکات مهم در استفاده از دستور case

  • در دستور case، مقایسه‌ها دقیقاً با مقادیر متغیر انجام می‌شود و معمولاً از مقایسه دقیق (case-sensitive) استفاده می‌شود. اگر بخواهید مقایسه غیرحساس به حالت (case-insensitive) داشته باشید، می‌توانید از دستور shopt -s nocaseglob استفاده کنید.
  • * به‌عنوان wild card عمل می‌کند و به معنای هر چیزی است که با الگو تطابق کند.
  • در case، اگر هیچ‌یک از الگوها با مقدار متغیر تطابق نداشته باشد، بخش * که به عنوان پیش‌فرض تعیین شده است، اجرا می‌شود.
  • از ;; برای پایان هر گزینه و ادامه بررسی الگوها استفاده می‌شود.
  • استفاده از case می‌تواند کد را مرتب‌تر و خواناتر کند، به‌ویژه زمانی که تعداد زیادی شرط وجود داشته باشد.

جمع‌بندی

دستور case ابزاری مفید برای جایگزینی شرط‌های پیچیده و متعدد در اسکریپت‌های شل است. این دستور به‌ویژه برای زمانی که باید مقادیر مختلف را با یک متغیر مقایسه کنید یا ورودی‌های پیچیده‌ای داشته باشید، بسیار کارآمد است. به‌جای استفاده از چندین دستور if-elif-else، دستور case به‌طور قابل توجهی کد شما را ساده‌تر، خواناتر و مدیریت‌پذیرتر می‌کند.

این دستور برای مقایسه مقادیر، الگوها و همچنین انجام عملیات مختلف براساس ورودی‌های متعدد به‌صورت مرتب و سازمان‌یافته طراحی شده است.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. مقایسه و ارزیابی شرط‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مقایسه اعداد و رشته‌ها در شل” subtitle=”توضیحات کامل”]در شل اسکریپتینگ، مقایسه اعداد و رشته‌ها اغلب در دستورات شرطی مانند if, while, و case انجام می‌شود. تفاوت‌هایی در نحوه مقایسه اعداد و رشته‌ها وجود دارد که باید آن‌ها را درک کنیم. این تفاوت‌ها به‌ویژه زمانی که با داده‌های ورودی و مقادیر متغیرها سر و کار داریم اهمیت بیشتری پیدا می‌کنند.

در شل، مقایسه اعداد و رشته‌ها نیازمند استفاده از عملگرهای متفاوت است. در این بخش، به بررسی نحوه مقایسه هرکدام و استفاده از عملگرهای مناسب خواهیم پرداخت.


۱. مقایسه اعداد

برای مقایسه اعداد در شل، باید از عملگرهای خاصی استفاده کنیم که برای مقایسه اعداد طراحی شده‌اند. این عملگرها در قالب دستور test یا [[ ... ]] برای مقایسه اعداد درون دستورات شرطی قرار می‌گیرند.

عملگرهای مقایسه اعداد در شل:

عملگر توضیح مثال
-eq برابر است a -eq b
-ne نابرابر است a -ne b
-lt کمتر از است a -lt b
-le کمتر یا برابر است a -le b
-gt بزرگتر از است a -gt b
-ge بزرگتر یا برابر است a -ge b

۱.۱. مثال مقایسه اعداد

در این مثال، دو عدد را مقایسه می‌کنیم و پیام مناسب را چاپ می‌کنیم.

#!/bin/bash

a=5
b=10

if [ $a -lt $b ]; then
  echo "$a کمتر از $b است."
else
  echo "$a بزرگتر یا برابر با $b است."
fi

خروجی:

5 کمتر از 10 است.

در اینجا، با استفاده از عملگر -lt (کمتر از)، مقایسه انجام می‌شود. در صورتی که عدد اول از عدد دوم کمتر باشد، پیام مربوط به آن چاپ می‌شود.


۲. مقایسه رشته‌ها

مقایسه رشته‌ها در شل به‌طور متفاوتی انجام می‌شود. برای مقایسه رشته‌ها از عملگرهای خاص استفاده می‌کنیم. این عملگرها معمولاً در قالب دستور test یا [[ ... ]] در دستورات شرطی قرار می‌گیرند.

عملگرهای مقایسه رشته‌ها در شل:

عملگر توضیح مثال
= برابر است str1 = str2
!= نابرابر است str1 != str2
< کمتر از (برای مقایسه رشته‌ها به‌صورت لغوی) str1 < str2
> بزرگتر از (برای مقایسه رشته‌ها به‌صورت لغوی) str1 > str2
-z خالی بودن رشته -z "$str"
-n پر بودن رشته -n "$str"

۲.۱. مثال مقایسه رشته‌ها

در این مثال، دو رشته را مقایسه می‌کنیم و پیامی مطابق با نتیجه مقایسه چاپ می‌کنیم.

#!/bin/bash

str1="hello"
str2="world"

if [ "$str1" = "$str2" ]; then
  echo "رشته‌ها برابر هستند."
else
  echo "رشته‌ها برابر نیستند."
fi

خروجی:

رشته‌ها برابر نیستند.

در اینجا، رشته‌ها با استفاده از عملگر = مقایسه می‌شوند. چون مقادیر رشته‌ها برابر نیستند، پیام مربوط به نابرابری چاپ می‌شود.


۳. مقایسه ترکیبی اعداد و رشته‌ها

در برخی مواقع، ممکن است بخواهیم اعداد و رشته‌ها را در کنار یکدیگر مقایسه کنیم. در چنین شرایطی باید دقت کرد که برای مقایسه رشته‌ها باید از عملگرهای مناسب رشته‌ای و برای مقایسه اعداد از عملگرهای عددی استفاده کرد.

۳.۱. مثال مقایسه ترکیبی اعداد و رشته‌ها

در این مثال، یک عدد و یک رشته را با هم مقایسه می‌کنیم.

#!/bin/bash

num=5
str="5"

if [ "$num" -eq "$str" ]; then
  echo "عدد و رشته برابر هستند."
else
  echo "عدد و رشته برابر نیستند."
fi

خروجی:

عدد و رشته برابر هستند.

در اینجا، چون شل خودکار رشته‌ای که عددی باشد را به‌عنوان عدد تلقی می‌کند، مقایسه 5 (عدد) و "5" (رشته) با استفاده از عملگر عددی -eq به درستی انجام می‌شود.


۴. مقایسه با دستور [[ ... ]] در شل

دستور [[ ... ]] پیشرفته‌تر از دستور [ است و برای مقایسه رشته‌ها و اعداد بسیار مناسب است. این دستور امکانات بیشتری مانند پشتیبانی از الگوها و مقایسه رشته‌ها به‌صورت لغوی را فراهم می‌آورد.

۴.۱. مثال مقایسه رشته‌ها با دستور [[ ... ]]
#!/bin/bash

str1="apple"
str2="banana"

if [[ "$str1" < "$str2" ]]; then
  echo "$str1 کوچکتر از $str2 است."
else
  echo "$str1 بزرگتر یا برابر با $str2 است."
fi

خروجی:

apple کوچکتر از banana است.

در اینجا، مقایسه رشته‌ها به‌صورت لغوی (lexicographically) انجام می‌شود.

۴.۲. مثال مقایسه اعداد با دستور [[ ... ]]
#!/bin/bash

a=10
b=5

if [[ $a -gt $b ]]; then
  echo "$a بزرگتر از $b است."
else
  echo "$a کوچکتر یا برابر با $b است."
fi

خروجی:

10 بزرگتر از 5 است.

جمع‌بندی

در شل اسکریپتینگ، برای مقایسه اعداد از عملگرهای خاص عددی مانند -eq، -ne، -lt و غیره استفاده می‌کنیم، در حالی که برای مقایسه رشته‌ها از عملگرهای متنی مانند =، != و < استفاده می‌شود. هنگام مقایسه اعداد و رشته‌ها باید دقت داشته باشیم که مقایسه عددی نباید به‌طور تصادفی روی رشته‌ها اعمال شود.

استفاده از دستور [[ ... ]] برای مقایسه‌ها بهتر است زیرا امکانات بیشتری برای مقایسه رشته‌ها به‌صورت لغوی فراهم می‌کند و خطاهای ناشی از مقایسه‌های اشتباه را کاهش می‌دهد.

به‌طور کلی، آگاهی از نحوه و قوانین مقایسه در شل به شما کمک خواهد کرد که در نوشتن اسکریپت‌های کارآمدتر و بدون خطا موفق‌تر باشید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ترکیب شرط‌ها با عملگرهای منطقی (&&, ||)” subtitle=”توضیحات کامل”]در شل اسکریپتینگ، معمولاً نیاز داریم که چندین شرط را با هم ترکیب کنیم. این کار برای ایجاد منطق پیچیده‌تر و انجام چندین بررسی به‌طور هم‌زمان انجام می‌شود. در چنین مواقعی از عملگرهای منطقی && (و منطقی) و || (یا منطقی) استفاده می‌کنیم.

عملگرهای منطقی به شما این امکان را می‌دهند که چندین دستور شرطی را به‌طور ترکیبی اجرا کنید، به‌گونه‌ای که شرط‌ها به هم وابسته باشند و نتیجه آن‌ها بر یکدیگر تأثیر بگذارد.

در اینجا به‌طور مفصل به کاربرد عملگرهای منطقی && و || در ترکیب شرط‌ها پرداخته‌ایم.


۱. عملگر && (و منطقی)

عملگر && برای ترکیب چندین شرط استفاده می‌شود و تنها در صورتی که همه شرایط برابر با درست (True) باشند، بخش بعدی اجرا می‌شود. به عبارت دیگر، اگر شرط اول درست باشد، شرط دوم هم ارزیابی می‌شود و اگر آن هم درست بود، دستور بعدی اجرا می‌شود.

ساختار استفاده از &&:

if [ condition1 ] && [ condition2 ]; then
    # دستورات اجرا می‌شود اگر هر دو شرط درست باشند
fi

اگر هر یک از شرایط نادرست باشد، دستورات در داخل then اجرا نخواهند شد.


۱.۱. مثال استفاده از &&:

فرض کنید می‌خواهیم بررسی کنیم که آیا یک فایل وجود دارد و آیا یک دایرکتوری در مسیر خاص موجود است.

#!/bin/bash

file="/path/to/file.txt"
directory="/path/to/directory"

if [ -f "$file" ] && [ -d "$directory" ]; then
    echo "فایل موجود است و دایرکتوری نیز موجود است."
else
    echo "یا فایل وجود ندارد یا دایرکتوری موجود نیست."
fi

توضیح:
در این اسکریپت، ابتدا بررسی می‌شود که فایل وجود دارد (-f برای فایل معمولی) و سپس بررسی می‌شود که دایرکتوری وجود دارد (-d برای دایرکتوری). اگر هر دو شرط صحیح باشند، پیام موفقیت نمایش داده می‌شود.


۲. عملگر || (یا منطقی)

عملگر || به‌معنای “یا” است و اگر هر یک از شرایط درست نباشد، بخش بعدی اجرا خواهد شد. به عبارت دیگر، اگر اولین شرط نادرست باشد، شرط دوم ارزیابی می‌شود و در صورت درست بودن آن، دستور بعدی اجرا می‌شود.

ساختار استفاده از ||:

if [ condition1 ] || [ condition2 ]; then
    # دستورات اجرا می‌شود اگر یکی از شرایط درست باشد
fi

در صورتی که یکی از شرایط درست باشد، دستورات در داخل then اجرا می‌شود.


۲.۱. مثال استفاده از ||:

در این مثال، می‌خواهیم بررسی کنیم که آیا یک فایل وجود ندارد یا یک دایرکتوری اشتباه است.

#!/bin/bash

file="/path/to/file.txt"
directory="/path/to/directory"

if [ ! -f "$file" ] || [ ! -d "$directory" ]; then
    echo "یا فایل وجود ندارد یا دایرکتوری اشتباه است."
else
    echo "فایل موجود است و دایرکتوری صحیح است."
fi

توضیح:
در اینجا، ابتدا بررسی می‌شود که آیا فایل وجود ندارد (! -f به معنی عدم وجود فایل) و سپس بررسی می‌شود که آیا دایرکتوری وجود ندارد (! -d برای عدم وجود دایرکتوری). اگر یکی از شرایط نادرست باشد، پیام خطا نمایش داده می‌شود.


۳. ترکیب && و || برای شرط‌های پیچیده‌تر

می‌توانیم از ترکیب && و || برای ایجاد منطق پیچیده‌تری در اسکریپت‌ها استفاده کنیم. در این حالت، دستورات به‌صورت چپ به راست ارزیابی می‌شوند و اگر شرطی برقرار باشد، دستورات مناسب اجرا می‌شوند.

ساختار ترکیب && و ||:

if [ condition1 ] && [ condition2 ] || [ condition3 ]; then
    # دستورات اجرا می‌شود اگر condition1 و condition2 درست باشد یا condition3 درست باشد
fi

۳.۱. مثال ترکیب && و ||:

در این مثال، بررسی می‌کنیم که آیا یک فایل وجود دارد و یک دایرکتوری معتبر است یا یک شرط دیگر برقرار است.

#!/bin/bash

file="/path/to/file.txt"
directory="/path/to/directory"
other_condition=true

if [ -f "$file" ] && [ -d "$directory" ] || [ "$other_condition" == true ]; then
    echo "فایل و دایرکتوری معتبر هستند یا شرط دیگر برقرار است."
else
    echo "شرایط نامعتبر است."
fi

توضیح:
در اینجا، ابتدا بررسی می‌شود که فایل وجود دارد و دایرکتوری معتبر است، در صورتی که هر دو درست باشد، دستور بعدی اجرا می‌شود. اگر این شرایط نادرست بود، سپس بررسی می‌شود که آیا شرط دیگر برقرار است یا نه. اگر یکی از شرایط درست باشد، دستور مربوط به آن اجرا می‌شود.


۴. استفاده از دستور set -e و ترکیب شرط‌ها

برای جلوگیری از اجرای دستورات اشتباه و انجام ترکیب‌های منطقی پیچیده‌تر، می‌توانید از دستور set -e برای قطع کردن اجرای اسکریپت در صورت بروز خطا استفاده کنید.

#!/bin/bash
set -e

# دستورات و شرط‌ها
if [ -f "$file" ] && [ -d "$directory" ]; then
    echo "همه شرایط درست است."
fi

در اینجا، در صورتی که یکی از شرایط نادرست باشد، اسکریپت به‌طور کامل متوقف می‌شود.


جمع‌بندی

عملگرهای منطقی && و || در شل اسکریپتینگ ابزارهای مهمی برای ترکیب شرایط مختلف هستند. با استفاده از &&، می‌توانیم اطمینان حاصل کنیم که همه شرایط باید درست باشند تا دستورات بعدی اجرا شوند، در حالی که با || می‌توانیم تضمین کنیم که اگر یکی از شرایط درست باشد، دستورات اجرا شوند. ترکیب این دو عملگر در کنار هم می‌تواند منطق پیچیده‌تری را ایجاد کند که در اسکریپت‌های پیشرفته کاربرد زیادی دارد.

استفاده درست از این عملگرها باعث می‌شود که بتوانید اسکریپت‌های کاربردی و منعطفی بنویسید که شرایط مختلف را به‌خوبی بررسی کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از شرط‌های تو در تو” subtitle=”توضیحات کامل”]در شل اسکریپتینگ، شرط‌های تو در تو (Nested Conditions) به شما این امکان را می‌دهند که از دستورات شرطی در داخل دیگر دستورات شرطی استفاده کنید. این ویژگی زمانی کاربرد دارد که بخواهید چندین بررسی متفاوت را انجام دهید که به نتیجه یکدیگر وابسته هستند.

شرط‌های تو در تو می‌توانند شامل if-else، elif و حتی case باشند و باعث می‌شوند که منطق پیچیده‌تری در اسکریپت‌های شل پیاده‌سازی شود. در اینجا نحوه استفاده از شرط‌های تو در تو با مثال‌های عملی توضیح داده می‌شود.


۱. استفاده از شرط‌های if تو در تو

شرط‌های if تو در تو زمانی استفاده می‌شوند که شما بخواهید یک بررسی اولیه انجام دهید و سپس بررسی‌های اضافی در داخل آن داشته باشید. به‌عبارت‌دیگر، اگر شرط اول درست باشد، بررسی‌های بعدی ادامه پیدا می‌کنند.

ساختار شرط‌های if تو در تو:

if [ condition1 ]; then
    if [ condition2 ]; then
        # دستوراتی که وقتی هر دو شرط درست باشند اجرا می‌شوند
    else
        # دستوراتی که وقتی شرط دوم نادرست باشد اجرا می‌شوند
    fi
else
    # دستوراتی که وقتی شرط اول نادرست باشد اجرا می‌شوند
fi

۱.۱. مثال شرط‌های if تو در تو:

در این مثال، ابتدا بررسی می‌شود که آیا یک فایل وجود دارد و سپس بررسی می‌شود که آیا آن فایل قابل نوشتن است.

#!/bin/bash

file="/path/to/file.txt"

if [ -f "$file" ]; then
    echo "فایل موجود است."
    if [ -w "$file" ]; then
        echo "فایل قابل نوشتن است."
    else
        echo "فایل قابل نوشتن نیست."
    fi
else
    echo "فایل موجود نیست."
fi

توضیح:
در این اسکریپت ابتدا بررسی می‌شود که فایل وجود دارد (با استفاده از شرط -f). اگر این شرط درست باشد، بررسی می‌شود که آیا فایل قابل نوشتن است (با استفاده از شرط -w). در صورتی که هر دو شرط صحیح باشد، پیام مربوطه نمایش داده می‌شود.


۲. استفاده از شرط‌های elif تو در تو

اگر نیاز دارید که شرایط مختلفی را بررسی کنید، می‌توانید از دستور elif در داخل یک شرط if استفاده کنید. این کار به شما این امکان را می‌دهد که به صورت سلسله‌مراتبی چندین شرط مختلف را بررسی کنید.

ساختار شرط‌های if-elif-else تو در تو:

if [ condition1 ]; then
    # دستورات زمانی که condition1 درست باشد
elif [ condition2 ]; then
    # دستورات زمانی که condition2 درست باشد
else
    # دستورات زمانی که هیچ‌یک از شرایط درست نباشد
fi

۲.۱. مثال شرط‌های elif تو در تو:

در این مثال، بررسی می‌کنیم که آیا یک فایل وجود دارد و اگر وجود ندارد، بررسی می‌کنیم که آیا یک دایرکتوری وجود دارد.

#!/bin/bash

file="/path/to/file.txt"
directory="/path/to/directory"

if [ -f "$file" ]; then
    echo "فایل موجود است."
elif [ -d "$directory" ]; then
    echo "دایرکتوری موجود است."
else
    echo "هیچ‌یک از این‌ها وجود ندارد."
fi

توضیح:
در اینجا ابتدا بررسی می‌شود که آیا فایل وجود دارد. اگر وجود نداشت، سپس بررسی می‌شود که آیا دایرکتوری موجود است. اگر هیچ‌کدام از این دو شرط برقرار نباشد، پیام مناسبی نمایش داده می‌شود.


۳. استفاده از شرط‌های case تو در تو

شرط‌های case نیز می‌توانند به‌صورت تو در تو استفاده شوند. این نوع شرط‌ها زمانی مفید هستند که نیاز به بررسی چندین گزینه دارید و هر کدام از گزینه‌ها ممکن است شرط‌های مختلفی داشته باشند.

ساختار شرط‌های case تو در تو:

case $variable in
    pattern1)
        case $sub_variable in
            sub_pattern1)
                # دستورات
                ;;
            sub_pattern2)
                # دستورات
                ;;
        esac
        ;;
    pattern2)
        # دستورات برای pattern2
        ;;
    *)
        # دستورات برای شرایط دیگر
        ;;
esac

۳.۱. مثال شرط‌های case تو در تو:

در این مثال، ورودی کاربر بررسی می‌شود که اگر یک عدد وارد کند، سپس بررسی شود که آیا آن عدد مثبت یا منفی است.

#!/bin/bash

read -p "یک عدد وارد کنید: " number

case $number in
    +([0-9]))
        case $number in
            0)
                echo "عدد صفر است."
                ;;
            *)
                echo "عدد مثبت است."
                ;;
        esac
        ;;
    -([0-9]))
        echo "عدد منفی است."
        ;;
    *)
        echo "ورودی معتبر نیست."
        ;;
esac

توضیح:
در اینجا، ابتدا ورودی کاربر بررسی می‌شود که آیا یک عدد صحیح است. اگر عدد مثبت باشد، یک case دیگر بررسی می‌کند که آیا عدد صفر است یا یک عدد مثبت. اگر عدد منفی باشد، شرط دیگری اجرا می‌شود.


۴. نکات مهم در استفاده از شرط‌های تو در تو

  • هنگام استفاده از شرط‌های تو در تو، توجه کنید که کد می‌تواند پیچیده و سخت‌خوان شود. بنابراین، بهتر است از مستندسازی و کامنت‌گذاری استفاده کنید تا دیگران بتوانند کد شما را راحت‌تر درک کنند.
  • شرط‌های تو در تو باید به‌صورت منطقی ساختاربندی شوند تا خطاهای احتمالی در ارزیابی شرط‌ها به حداقل برسد.
  • برای کاهش پیچیدگی می‌توانید از متغیرهای موقتی یا توابع استفاده کنید تا خوانایی کد افزایش یابد.

جمع‌بندی

استفاده از شرط‌های تو در تو در شل اسکریپتینگ به شما این امکان را می‌دهد که منطق پیچیده‌تری را پیاده‌سازی کنید و چندین بررسی را به‌طور تدریجی و متناسب با نتایج قبلی انجام دهید. این روش به‌ویژه در شرایطی که نیاز به بررسی چندین پارامتر یا وضعیت مختلف دارید بسیار مفید است. ترکیب صحیح این نوع شرط‌ها با دستورات if-else، elif و case باعث می‌شود که اسکریپت شما انعطاف‌پذیر و قدرت‌مند باشد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. مدیریت خطاها در اسکریپت‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی خروجی دستورات با $?” subtitle=”توضیحات کامل”]در شل اسکریپتینگ، متغیر ویژه $? برای بررسی وضعیت خروجی آخرین دستوری که اجرا شده استفاده می‌شود. این متغیر مقدار کد بازگشتی (exit status) آخرین دستور را ذخیره می‌کند. کد خروجی یک دستور به شما نشان می‌دهد که آیا دستور با موفقیت اجرا شده یا خیر. به‌طور خاص:

  • مقدار ۰ معمولاً نشان‌دهنده موفقیت است.
  • هر مقدار غیر صفر معمولاً نشان‌دهنده وجود خطا در اجرای دستور است.

این قابلیت به شما کمک می‌کند تا در اسکریپت‌های شل وضعیت دستورات مختلف را پیگیری کرده و تصمیمات مناسب را بر اساس موفقیت یا شکست آن‌ها اتخاذ کنید.


۱. نحوه استفاده از $?

پس از اجرای هر دستور در شل، شما می‌توانید بلافاصله مقدار $? را برای مشاهده وضعیت خروجی آن دستور بررسی کنید.

ساختار استفاده از $?:

command
echo $?

۱.۱. مثال ساده:

در این مثال یک دستور موفق و یک دستور ناموفق اجرا می‌کنیم و وضعیت خروجی آن‌ها را بررسی می‌کنیم.

#!/bin/bash

# دستور موفق
echo "Hello, World!"
echo "کد خروجی دستور اول: $?"

# دستور ناموفق (برای مثال فایل موجود نیست)
ls /nonexistentfile
echo "کد خروجی دستور دوم: $?"

توضیح:
در این اسکریپت، ابتدا دستور echo "Hello, World!" اجرا می‌شود که یک دستور موفق است و بنابراین $? باید برابر با ۰ باشد. سپس دستور ls /nonexistentfile اجرا می‌شود که به دلیل عدم وجود فایل، با خطا مواجه خواهد شد و بنابراین $? باید مقدار غیر صفر (معمولاً ۲) باشد.

خروجی احتمالی:

Hello, World!
کد خروجی دستور اول: 0
ls: cannot access '/nonexistentfile': No such file or directory
کد خروجی دستور دوم: 2

۲. بررسی وضعیت‌های مختلف خروجی

کدهای خروجی به شما اطلاعات دقیقی از وضعیت دستورات مختلف می‌دهند. در اینجا برخی از کدهای خروجی متداول و معنای آن‌ها آورده شده است:

  • 0: دستور با موفقیت اجرا شده است.
  • 1: خطای عمومی.
  • 2: دستور به دلیل خطای نحوی یا پارامتر نادرست شکست خورده است.
  • کدهای بزرگتر از ۲: معمولاً به مشکلات خاص‌تر و پیچیده‌تر اشاره دارند که مربوط به دستور خاصی هستند.

شما می‌توانید از این کدها برای اجرای دستورهای مختلف و تصمیم‌گیری در مورد اقدام بعدی استفاده کنید.


۳. استفاده از $? برای تصمیم‌گیری در اسکریپت‌ها

شما می‌توانید از متغیر $? برای اتخاذ تصمیمات مختلف در اسکریپت‌های خود استفاده کنید. این کار معمولاً با استفاده از دستورات شرطی if یا case انجام می‌شود.

ساختار شرطی با استفاده از $?:

command
if [ $? -eq 0 ]; then
    echo "دستور با موفقیت اجرا شد."
else
    echo "خطا در اجرای دستور."
fi

۳.۱. مثال استفاده از $? برای بررسی موفقیت یا شکست دستور:

در این مثال، ابتدا سعی می‌کنیم یک فایل را ایجاد کنیم و سپس با استفاده از $? بررسی می‌کنیم که آیا عملیات موفق بوده یا خیر.

#!/bin/bash

touch /path/to/file.txt

# بررسی کد خروجی دستور touch
if [ $? -eq 0 ]; then
    echo "فایل با موفقیت ایجاد شد."
else
    echo "خطا در ایجاد فایل."
fi

توضیح:
در این اسکریپت، دستور touch /path/to/file.txt برای ایجاد یک فایل جدید اجرا می‌شود. سپس وضعیت اجرای دستور با استفاده از $? بررسی می‌شود. اگر کد خروجی صفر باشد، نشان‌دهنده موفقیت است و پیام مربوطه چاپ می‌شود. در غیر این صورت، پیامی مبنی بر خطا چاپ خواهد شد.


۴. استفاده از $? در اسکریپت‌های پیچیده‌تر

در اسکریپت‌های پیچیده‌تر، شما می‌توانید از $? در ترکیب با دستورات متعدد استفاده کنید تا مراحل مختلف یک فرایند را بررسی کنید و در صورت بروز خطا، اقدامات خاصی انجام دهید.

مثال:
در این مثال، چندین دستور به ترتیب اجرا می‌شوند و در صورت بروز هرگونه خطا، اسکریپت متوقف می‌شود.

#!/bin/bash

echo "مرحله اول: شروع"
cp /path/to/source/file.txt /path/to/destination/
if [ $? -ne 0 ]; then
    echo "خطا در کپی کردن فایل!"
    exit 1
fi

echo "مرحله دوم: فایل کپی شد، ادامه عملیات..."
# دستورات بعدی

توضیح:
در این اسکریپت ابتدا دستور کپی کردن فایل اجرا می‌شود و سپس وضعیت آن بررسی می‌شود. اگر کد خروجی غیر صفر باشد، به این معنی است که دستور با خطا مواجه شده و اسکریپت با کد خطای ۱ متوقف می‌شود. در غیر این صورت، اسکریپت به مرحله بعدی ادامه می‌دهد.


جمع‌بندی

متغیر $? یکی از ابزارهای قدرتمند در شل اسکریپتینگ است که به شما این امکان را می‌دهد که وضعیت اجرای دستورات مختلف را بررسی کنید. با استفاده از این متغیر می‌توانید تصمیمات منطقی در اسکریپت‌های خود اتخاذ کنید، مانند اجرای دستورات خاص در صورت موفقیت یا شکست یک دستور. درک صحیح و استفاده بهینه از $? می‌تواند باعث ساخت اسکریپت‌های مقاوم‌تر و خطاپذیرتر شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از دستور || و && برای مدیریت خطاها” subtitle=”توضیحات کامل”]در شل اسکریپتینگ، دستورات || و && برای مدیریت شرط‌های منطقی و کنترل جریان اجرای دستورات استفاده می‌شوند. این دستورات به شما کمک می‌کنند تا نحوه واکنش به موفقیت یا شکست دستورات را تعیین کنید و به این ترتیب اسکریپت‌های پیچیده‌تر و انعطاف‌پذیرتر ایجاد کنید.

دستور && برای اجرای دستورات در صورتی که دستور قبلی با موفقیت انجام شود و دستور || برای اجرای دستورات در صورت بروز خطا یا شکست دستور قبلی به کار می‌روند.


۱. استفاده از && (اجرای دستور بعدی در صورت موفقیت دستور قبلی)

دستور && به شما این امکان را می‌دهد که یک دستور را تنها در صورتی اجرا کنید که دستور قبلی با موفقیت اجرا شده باشد (کد خروجی آن صفر باشد).

ساختار استفاده از &&:

command1 && command2

توضیح:
در اینجا، command2 تنها در صورتی اجرا می‌شود که command1 با موفقیت اجرا شود (کد خروجی command1 برابر ۰ باشد).


۱.۱. مثال استفاده از &&:

در این مثال، یک فایل ایجاد می‌شود و تنها در صورتی که فایل با موفقیت ایجاد شود، یک پیام موفقیت چاپ می‌شود.

#!/bin/bash

touch /path/to/file.txt && echo "فایل با موفقیت ایجاد شد."

توضیح:
در اینجا دستور touch برای ایجاد فایل اجرا می‌شود و تنها اگر این دستور با موفقیت انجام شود (کد خروجی ۰)، پیام “فایل با موفقیت ایجاد شد.” نمایش داده خواهد شد. اگر دستور touch با خطا مواجه شود، هیچ پیامی نمایش داده نخواهد شد.


۲. استفاده از || (اجرای دستور بعدی در صورت شکست دستور قبلی)

دستور || برای اجرای دستور بعدی تنها در صورتی که دستور قبلی با شکست مواجه شده باشد (کد خروجی آن غیر صفر باشد) استفاده می‌شود.

ساختار استفاده از ||:

command1 || command2

توضیح:
در اینجا، command2 تنها در صورتی اجرا می‌شود که command1 شکست خورده باشد (کد خروجی command1 غیر صفر باشد).


۲.۱. مثال استفاده از ||:

در این مثال، اگر دستور mkdir برای ایجاد پوشه با خطا مواجه شود (مثلاً به دلیل وجود پوشه‌ای با همین نام)، پیام خطا چاپ خواهد شد.

#!/bin/bash

mkdir /path/to/existing_directory || echo "خطا در ایجاد پوشه!"

توضیح:
در اینجا، اگر پوشه‌ای که می‌خواهیم ایجاد کنیم قبلاً وجود داشته باشد، دستور mkdir با خطا مواجه می‌شود و سپس دستور echo "خطا در ایجاد پوشه!" اجرا خواهد شد.


۳. ترکیب && و || برای مدیریت خطاها

در بسیاری از مواقع، می‌توانید از ترکیب && و || برای کنترل بیشتر جریان اجرای دستورات استفاده کنید. به این ترتیب، می‌توانید اقداماتی را برای هر دو حالت موفقیت و شکست پیش‌بینی کنید.

ساختار ترکیب && و ||:

command1 && command2 || command3

توضیح:
در اینجا:

  • اگر command1 با موفقیت اجرا شود، دستور command2 اجرا خواهد شد.
  • اگر command1 با شکست مواجه شود یا command2 با خطا مواجه شود، دستور command3 اجرا خواهد شد.

۳.۱. مثال ترکیب && و ||:

در این مثال، ابتدا تلاش می‌کنیم یک پوشه ایجاد کنیم و اگر این دستور موفق بود، پیامی برای موفقیت چاپ می‌شود. اگر دستور ایجاد پوشه شکست خورد، یک پیام خطا نمایش داده می‌شود.

#!/bin/bash

mkdir /path/to/new_directory && echo "پوشه با موفقیت ایجاد شد." || echo "خطا در ایجاد پوشه."

توضیح:
در اینجا:

  • اگر دستور mkdir با موفقیت اجرا شود، پیام “پوشه با موفقیت ایجاد شد.” نمایش داده می‌شود.
  • اگر دستور mkdir با خطا مواجه شود، پیام “خطا در ایجاد پوشه.” نمایش داده می‌شود.

این ساختار همچنین مفید است زمانی که شما بخواهید در صورت موفقیت یک دستور، دستور دیگری را اجرا کنید و در صورت بروز خطا، به‌طور خاص پیامی چاپ کنید.


۴. استفاده از set -e برای توقف فوری اسکریپت در صورت بروز خطا

همچنین می‌توانید از دستور set -e برای توقف فوری اسکریپت در صورتی که هر دستور با شکست مواجه شود استفاده کنید. این دستور می‌تواند در ترکیب با && و || برای جلوگیری از اجرای دستورات بعدی در صورت بروز خطا بسیار مفید باشد.

ساختار استفاده از set -e:

set -e
command1
command2

توضیح:
با استفاده از set -e، اگر هر یک از دستورات command1 یا command2 با خطا مواجه شود، اسکریپت فوراً متوقف می‌شود و دستورات بعدی اجرا نخواهند شد.


جمع‌بندی

دستورات && و || ابزارهای مفیدی در شل اسکریپتینگ هستند که برای مدیریت موفقیت و شکست دستورات و کنترل جریان اجرای اسکریپت‌ها استفاده می‌شوند. با استفاده از && می‌توانیم دستورات را تنها در صورت موفقیت دستور قبلی اجرا کنیم و با استفاده از || می‌توانیم دستورات را تنها در صورت شکست دستور قبلی اجرا کنیم. ترکیب این دستورات به شما این امکان را می‌دهد که اسکریپت‌های پیچیده‌تری با مدیریت خطای بهتر ایجاد کنید.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش 5. حلقه‌ها (Loops)”][cdb_course_lesson title=”فصل 1. مقدمه ای از حلقه‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”معرفی حلقه‌ها و نقش آنها در اسکریپت‌نویسی” subtitle=”توضیحات کامل”]حلقه‌ها یکی از اجزای اساسی در برنامه‌نویسی و اسکریپت‌نویسی هستند که به ما این امکان را می‌دهند که یک دستور یا مجموعه‌ای از دستورات را به‌طور مکرر اجرا کنیم. این ابزار برای کاهش پیچیدگی و افزایش کارایی اسکریپت‌ها بسیار مفید است، زیرا به جای نوشتن چندین بار کد مشابه، می‌توانیم از یک حلقه برای اجرای کدهای مشابه در چندین مرحله استفاده کنیم.

در شل اسکریپتینگ، سه نوع حلقه اصلی وجود دارد:

  1. حلقه for
  2. حلقه while
  3. حلقه until

هرکدام از این حلقه‌ها کاربرد خاص خود را دارند و انتخاب هرکدام بستگی به نوع نیاز و شرایط اجرای اسکریپت دارد.


1. حلقه for: اجرای دستورات برای مجموعه‌ای از مقادیر

حلقه for برای تکرار دستورات در یک مجموعه از مقادیر استفاده می‌شود. به‌عنوان مثال، می‌توانیم از آن برای تکرار روی مجموعه‌ای از فایل‌ها، اعداد یا حتی خروجی‌های یک دستور دیگر استفاده کنیم.

ساختار حلقه for:

for variable in list
do
    command
done

توضیح:
در این ساختار، حلقه for به‌صورت اتوماتیک به ازای هر مقدار در لیست list، دستور command را اجرا می‌کند. مقادیر داخل list می‌توانند شامل لیستی از اعداد، رشته‌ها یا حتی خروجی‌های یک دستور دیگر باشند.


1.1. مثال استفاده از حلقه for:

فرض کنید می‌خواهیم از طریق حلقه for به تمام فایل‌های موجود در یک دایرکتوری دسترسی داشته باشیم و نام هر فایل را چاپ کنیم.

#!/bin/bash

for file in /path/to/directory/*
do
    echo "فایل موجود: $file"
done

توضیح:
در اینجا، حلقه for به‌ازای هر فایل موجود در دایرکتوری /path/to/directory/ یک بار اجرا می‌شود و نام هر فایل را چاپ می‌کند.


2. حلقه while: اجرای دستورات تا زمانی که شرط خاصی برقرار باشد

حلقه while دستورات را تا زمانی که یک شرط خاص برقرار باشد اجرا می‌کند. این حلقه معمولاً زمانی استفاده می‌شود که تعداد دفعات تکرار مشخص نباشد و تا زمان برآورده شدن شرط، تکرار ادامه یابد.

ساختار حلقه while:

while condition
do
    command
done

توضیح:
در این ساختار، حلقه while تا زمانی که شرط condition برقرار باشد، دستورات داخل بلوک do ... done را اجرا می‌کند. پس از هر بار اجرای دستورات، شرط مجدداً بررسی می‌شود.


2.1. مثال استفاده از حلقه while:

فرض کنید می‌خواهیم تعداد دفعاتی که کاربر عددی را وارد کرده است، بشماریم و آن را چاپ کنیم. حلقه while می‌تواند برای ادامه گرفتن ورودی از کاربر تا زمانی که عدد مثبت وارد شود استفاده شود.

#!/bin/bash

count=0
while [ $count -lt 5 ]
do
    echo "لطفاً یک عدد وارد کنید:"
    read number
    ((count++))
done
echo "شما 5 عدد وارد کردید."

توضیح:
در اینجا، حلقه while تا زمانی که شمارش به ۵ نرسیده باشد ادامه پیدا می‌کند و از کاربر می‌خواهد که عددی وارد کند. پس از آنکه پنج عدد وارد شد، پیام “شما 5 عدد وارد کردید.” نمایش داده می‌شود.


3. حلقه until: اجرای دستورات تا زمانی که شرط نادرست باشد

حلقه until مشابه حلقه while است، با این تفاوت که دستورات داخل این حلقه تا زمانی اجرا می‌شوند که شرط مشخص‌شده نادرست باشد. به عبارت دیگر، حلقه until تکرار می‌کند تا زمانی که شرط برقرار نشود.

ساختار حلقه until:

until condition
do
    command
done

توضیح:
در این ساختار، حلقه until تا زمانی که شرط condition برقرار نباشد، دستورات داخل بلوک do ... done را اجرا می‌کند. پس از هر بار اجرای دستورات، شرط دوباره بررسی می‌شود.


3.1. مثال استفاده از حلقه until:

فرض کنید می‌خواهیم از کاربر ورودی بگیریم تا زمانی که ورودی او یک عدد مثبت باشد. اگر عدد منفی وارد کند، دوباره از او خواسته می‌شود که عدد جدیدی وارد کند.

#!/bin/bash

number=-1
until [ $number -ge 0 ]
do
    echo "لطفاً یک عدد مثبت وارد کنید:"
    read number
done
echo "شما عدد مثبت وارد کردید: $number"

توضیح:
در اینجا، حلقه until تا زمانی که کاربر یک عدد مثبت وارد کند، از او درخواست ورودی می‌کند. وقتی عدد مثبت وارد شد، حلقه خاتمه پیدا می‌کند و پیامی مبنی بر وارد کردن عدد مثبت نمایش داده می‌شود.


4. حلقه‌های تو در تو: استفاده از حلقه‌ها در داخل حلقه‌ها

حلقه‌ها می‌توانند داخل یکدیگر قرار بگیرند، یعنی می‌توانیم از یک حلقه در داخل حلقه دیگر استفاده کنیم تا وظایف پیچیده‌تری را انجام دهیم. این ویژگی بسیار مفید است زمانی که نیاز داریم به چندین مجموعه داده دسترسی پیدا کنیم.

ساختار حلقه‌های تو در تو:

for i in 1 2 3
do
    for j in A B C
    do
        echo "$i - $j"
    done
done

توضیح:
در اینجا، حلقه اول برای مقادیر 1، 2 و 3 اجرا می‌شود و برای هرکدام از این مقادیر، حلقه داخلی برای مقادیر A، B و C اجرا می‌شود. خروجی آن به شکل زیر خواهد بود:

1 - A
1 - B
1 - C
2 - A
2 - B
2 - C
3 - A
3 - B
3 - C

5. استفاده از break و continue در حلقه‌ها

در شل اسکریپت‌ها، از دستورات break و continue می‌توانیم برای کنترل جریان حلقه‌ها استفاده کنیم. دستور break باعث می‌شود که حلقه فوراً خاتمه یابد، در حالی که دستور continue موجب می‌شود که فقط به تکرار بعدی حلقه برویم و دستورات باقی‌مانده در آن دور از حلقه نادیده گرفته شوند.

5.1. مثال استفاده از break:
#!/bin/bash

for i in {1..10}
do
    if [ $i -eq 5 ]
    then
        break
    fi
    echo $i
done

توضیح:
در اینجا، حلقه for از 1 تا 10 اجرا می‌شود، اما با رسیدن به عدد 5، دستور break اجرا شده و حلقه خاتمه می‌یابد. خروجی این اسکریپت:

1
2
3
4
5.2. مثال استفاده از continue:
#!/bin/bash

for i in {1..10}
do
    if [ $i -eq 5 ]
    then
        continue
    fi
    echo $i
done

توضیح:
در اینجا، حلقه for از 1 تا 10 اجرا می‌شود، اما وقتی به عدد 5 می‌رسد، دستور continue باعث می‌شود که آن تکرار از حلقه نادیده گرفته شود و حلقه به اجرای خود ادامه دهد. خروجی این اسکریپت:

1
2
3
4
6
7
8
9
10

جمع‌بندی

حلقه‌ها یکی از اجزای کلیدی اسکریپت‌نویسی در لینوکس هستند که به ما این امکان را می‌دهند که دستورات را به‌صورت تکراری اجرا کنیم. انواع مختلفی از حلقه‌ها وجود دارد، از جمله حلقه‌های for، while و until که هرکدام در شرایط خاص کاربرد دارند. علاوه بر این، دستورات break و continue به ما این امکان را می‌دهند که کنترل بیشتری روی نحوه اجرای حلقه‌ها داشته باشیم و آنها را به شکلی دقیق‌تر و کارآمدتر مدیریت کنیم.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. انواع حلقه‌ها در شل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”حلقه for” subtitle=”توضیحات کامل”]حلقه for یکی از پرکاربردترین و قدرتمندترین ابزارها در اسکریپت‌نویسی شل است که به ما این امکان را می‌دهد که مجموعه‌ای از دستورات را به تعداد مشخص یا در یک مجموعه از مقادیر خاص تکرار کنیم. این حلقه به‌ویژه زمانی که نیاز به تکرار یک عمل برای هر عنصر از یک مجموعه داشته باشیم، بسیار مفید است.


ساختار حلقه for

ساختار کلی حلقه for به شکل زیر است:

for variable in list
do
    command
done
  • variable: متغیری که در هر تکرار، مقدار آن از لیست list می‌شود.
  • list: مجموعه‌ای از مقادیر است که حلقه for باید به ازای هرکدام از آن‌ها یکبار اجرا شود.
  • command: دستور یا مجموعه‌ای از دستورات است که برای هر مقدار در لیست اجرا خواهد شد.

مثال‌های ساده استفاده از حلقه for

مثال 1: چاپ یک لیست از اعداد

فرض کنید می‌خواهیم اعداد 1 تا 5 را چاپ کنیم. از حلقه for برای این کار می‌توانیم استفاده کنیم.

#!/bin/bash

for i in 1 2 3 4 5
do
    echo "عدد: $i"
done

توضیح:
در این مثال، حلقه for مقادیر 1 تا 5 را یکی یکی به متغیر i اختصاص می‌دهد و در هر تکرار دستور echo برای چاپ مقدار i اجرا می‌شود. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4
عدد: 5

مثال 2: استفاده از آرایه در حلقه for

در این مثال، از حلقه for برای پیمایش در یک آرایه و چاپ مقادیر آن استفاده می‌کنیم.

#!/bin/bash

fruits=("سیب" "موز" "پرتقال" "توت فرنگی")

for fruit in "${fruits[@]}"
do
    echo "میوه: $fruit"
done

توضیح:
در اینجا، آرایه fruits که حاوی چند میوه است، به ازای هر عنصر در آرایه، دستور echo را اجرا می‌کند و هر میوه را چاپ می‌کند. خروجی به این شکل خواهد بود:

میوه: سیب
میوه: موز
میوه: پرتقال
میوه: توت فرنگی

مثال 3: استفاده از حلقه for با بازه عددی

یکی از کاربردهای معمول حلقه for استفاده از آن برای اجرای دستورات در یک بازه عددی است. این کار می‌تواند با استفاده از دستورات خاصی مانند {start..end} در شل انجام شود.

#!/bin/bash

for i in {1..5}
do
    echo "عدد: $i"
done

توضیح:
در اینجا، حلقه for برای مقادیر از 1 تا 5 اجرا می‌شود و دستور echo در هر تکرار اجرا می‌شود. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4
عدد: 5

استفاده از حلقه for برای تکرار دستورات بر روی فایل‌ها

فرض کنید می‌خواهیم اسکریپتی بنویسیم که همه فایل‌ها در یک دایرکتوری خاص را لیست کرده و برای هرکدام عملی را انجام دهد. می‌توانیم از حلقه for برای تکرار بر روی فایل‌ها استفاده کنیم.

#!/bin/bash

for file in /path/to/directory/*
do
    echo "در حال پردازش: $file"
done

توضیح:
در اینجا، حلقه for برای هر فایل موجود در دایرکتوری /path/to/directory/ اجرا می‌شود و نام فایل را با استفاده از دستور echo چاپ می‌کند.


حلقه for و دستورات ترکیبی

حلقه‌های for می‌توانند با دستورات ترکیبی یا چند خطی استفاده شوند. به‌عنوان مثال، اگر بخواهیم برای هر فایل موجود در یک دایرکتوری دستوراتی خاص اجرا کنیم (مثل جابه‌جایی یا کپی کردن فایل‌ها)، می‌توانیم از یک ساختار چند خطی در داخل حلقه استفاده کنیم.

#!/bin/bash

for file in /path/to/directory/*
do
    if [ -f "$file" ]; then
        echo "فایل: $file"
        # کدهایی مانند کپی کردن یا جابه‌جایی فایل
    fi
done

توضیح:
در اینجا، حلقه for به ازای هر فایل موجود در دایرکتوری خاص، بررسی می‌کند که آیا آن یک فایل است یا خیر و سپس دستوراتی را برای فایل‌های معمولی اجرا می‌کند.


حلقه for با استفاده از دستورات break و continue

حلقه‌های for می‌توانند با دستورات کنترل مانند break و continue ترکیب شوند تا جریان کنترل را تغییر دهند.

  • دستور break باعث می‌شود که حلقه به‌صورت ناگهانی متوقف شود.
  • دستور continue باعث می‌شود که حلقه به تکرار بعدی خود برود و دستورات بعدی در آن دور از حلقه نادیده گرفته شوند.

مثال استفاده از break:

#!/bin/bash

for i in {1..10}
do
    if [ $i -eq 5 ]; then
        break
    fi
    echo "عدد: $i"
done

توضیح:
در اینجا، هنگامی که مقدار i به ۵ رسید، دستور break باعث می‌شود که حلقه فوراً متوقف شود. خروجی:

عدد: 1
عدد: 2
عدد: 3
عدد: 4

مثال استفاده از continue:

#!/bin/bash

for i in {1..10}
do
    if [ $i -eq 5 ]; then
        continue
    fi
    echo "عدد: $i"
done

توضیح:
در اینجا، زمانی که مقدار i به ۵ رسید، دستور continue باعث می‌شود که آن تکرار از حلقه نادیده گرفته شود و حلقه ادامه یابد. خروجی:

عدد: 1
عدد: 2
عدد: 3
عدد: 4
عدد: 6
عدد: 7
عدد: 8
عدد: 9
عدد: 10

جمع‌بندی

حلقه for در شل اسکریپتینگ ابزاری قدرتمند برای انجام کارهای تکراری است. این حلقه می‌تواند برای پیمایش در لیست‌ها، آرایه‌ها، یا بازه‌های عددی استفاده شود و همچنین می‌تواند در ترکیب با دستورات break و continue برای کنترل بهتر روند اجرای برنامه‌ها به‌کار رود. حلقه for همچنین یکی از ابزارهای کلیدی برای پردازش فایل‌ها و انجام عملیات بر روی آن‌ها است که در بسیاری از اسکریپت‌ها و وظایف اتوماسیون استفاده می‌شود.

 [/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”حلقه while” subtitle=”توضیحات کامل”]حلقه while یکی از مهم‌ترین ابزارها در اسکریپت‌نویسی شل است که برای تکرار اجرای دستورات تا زمانی که یک شرط معین برقرار باشد، استفاده می‌شود. برخلاف حلقه‌های for که تعداد تکرارها مشخص است، در حلقه while تعداد تکرارها تا زمانی که شرط موردنظر برقرار باشد، ادامه می‌یابد. این حلقه زمانی مناسب است که بخواهید یک عمل را مکرراً انجام دهید تا یک شرط خاص محقق شود.


ساختار حلقه while

ساختار کلی حلقه while به شکل زیر است:

while condition
do
    command
done
  • condition: شرطی است که در هر تکرار بررسی می‌شود. تا زمانی که این شرط درست باشد (true)، دستورات داخل بلوک do اجرا می‌شوند.
  • command: دستوری است که در هر تکرار اجرا می‌شود.
  • این حلقه به محض اینکه شرط condition به false تغییر کند، خاتمه می‌یابد.

مثال‌های ساده استفاده از حلقه while

مثال 1: حلقه while برای چاپ اعداد از 1 تا 5

در این مثال، از حلقه while برای چاپ اعداد از 1 تا 5 استفاده می‌کنیم.

#!/bin/bash

i=1
while [ $i -le 5 ]
do
    echo "عدد: $i"
    ((i++))
done

توضیح:
در اینجا، ابتدا متغیر i به مقدار 1 تنظیم می‌شود. سپس حلقه while اجرا می‌شود و در هر تکرار، مقدار i چاپ شده و سپس با دستور ((i++)) مقدار i افزایش می‌یابد. حلقه تا زمانی که مقدار i از 5 بیشتر نشود، ادامه می‌یابد. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4
عدد: 5

مثال 2: حلقه while برای دریافت ورودی از کاربر

در این مثال، از حلقه while برای دریافت ورودی از کاربر و تکرار درخواست ورودی تا زمانی که کاربر عبارت “خروج” را وارد کند، استفاده می‌کنیم.

#!/bin/bash

while true
do
    read -p "لطفاً عبارتی وارد کنید (برای خروج 'خروج' را تایپ کنید): " input
    if [ "$input" == "خروج" ]; then
        echo "خروج از برنامه."
        break
    fi
    echo "شما وارد کردید: $input"
done

توضیح:
در اینجا، حلقه while true به معنای یک حلقه بی‌پایان است که تنها با دستور break متوقف می‌شود. در هر تکرار، از کاربر ورودی خواسته می‌شود و اگر ورودی “خروج” باشد، حلقه متوقف می‌شود و پیام خروج نمایش داده می‌شود. در غیر این صورت، ورودی کاربر چاپ می‌شود.


مثال 3: استفاده از حلقه while برای انجام عملیات روی فایل‌ها

در این مثال، از حلقه while برای پیمایش در فایل‌ها و چاپ نام آن‌ها استفاده می‌کنیم.

#!/bin/bash

files=$(ls /path/to/directory)
while read -r file
do
    echo "در حال پردازش: $file"
done <<< "$files"

توضیح:
در اینجا، از دستور ls برای گرفتن لیست فایل‌ها در یک دایرکتوری خاص استفاده می‌کنیم و سپس با استفاده از دستور read هر فایل را در حلقه while پردازش می‌کنیم. در این مثال، پیام‌هایی مبنی بر پردازش فایل‌ها چاپ می‌شود.


استفاده از دستورات break و continue در حلقه while

استفاده از break

دستور break می‌تواند برای خروج از حلقه while در هر زمان که شرایط خاصی محقق شد، استفاده شود. این دستور معمولاً زمانی مفید است که نیاز دارید حلقه به طور ناگهانی متوقف شود.

#!/bin/bash

count=1
while [ $count -le 10 ]
do
    if [ $count -eq 5 ]; then
        break
    fi
    echo "عدد: $count"
    ((count++))
done

توضیح:
در اینجا، حلقه while از 1 تا 10 اجرا می‌شود، اما به محض اینکه مقدار متغیر count به 5 برسد، دستور break اجرا می‌شود و حلقه متوقف می‌شود. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4

استفاده از continue

دستور continue باعث می‌شود که حلقه به تکرار بعدی خود ادامه دهد و دستورات بعد از آن نادیده گرفته شوند. این دستور زمانی مفید است که بخواهید شرایط خاصی را برای نادیده گرفتن یک تکرار اعمال کنید.

#!/bin/bash

count=1
while [ $count -le 10 ]
do
    if [ $count -eq 5 ]; then
        ((count++))
        continue
    fi
    echo "عدد: $count"
    ((count++))
done

توضیح:
در اینجا، وقتی که مقدار count به 5 رسید، دستور continue باعث می‌شود که آن تکرار نادیده گرفته شود و حلقه به تکرار بعدی ادامه دهد. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4
عدد: 6
عدد: 7
عدد: 8
عدد: 9
عدد: 10

استفاده از حلقه while با متغیرهای خاص

فرض کنید بخواهید با استفاده از حلقه while تعداد فایل‌ها یا دایرکتوری‌های موجود در یک مسیر خاص را بشمارید. برای این کار می‌توانیم از متغیرهای خاصی مانند $? که نشان‌دهنده وضعیت آخرین دستور است، استفاده کنیم.

#!/bin/bash

count=0
while [ -e /path/to/file$count ]
do
    echo "در حال پردازش: /path/to/file$count"
    ((count++))
done

توضیح:
در اینجا، حلقه while با استفاده از متغیر count برای ایجاد مسیر فایل‌هایی مانند /path/to/file0, /path/to/file1, … تلاش می‌کند و تا زمانی که فایل وجود داشته باشد، ادامه می‌دهد.


جمع‌بندی

حلقه while در شل اسکریپتینگ ابزاری قدرتمند برای تکرار دستورات است تا زمانی که یک شرط معین برقرار باشد. این حلقه زمانی مفید است که تعداد دقیق تکرارها مشخص نباشد و نیاز به تکرار دستورات تا زمان تحقق یک شرط خاص داشته باشیم. همچنین، دستورات break و continue می‌توانند به ما در کنترل جریان اجرای حلقه کمک کنند تا از آن برای خروج زودهنگام یا نادیده گرفتن تکرارهای خاص استفاده کنیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”حلقه until” subtitle=”توضیحات کامل”]حلقه until یکی دیگر از انواع حلقه‌ها در اسکریپت‌های شل است که مشابه به حلقه while عمل می‌کند، با این تفاوت که در حلقه while شرط باید درست باشد تا حلقه اجرا شود، اما در حلقه until شرط باید غلط (false) باشد تا حلقه اجرا شود. به عبارت دیگر، حلقه until تا زمانی که شرط غلط باشد، ادامه می‌یابد. زمانی که شرط به true تبدیل شود، حلقه متوقف می‌شود.


ساختار حلقه until

ساختار کلی حلقه until به شکل زیر است:

until condition
do
    command
done
  • condition: شرطی است که در هر تکرار بررسی می‌شود. حلقه تا زمانی که این شرط غلط باشد (false)، دستورات داخل بلوک do اجرا می‌شوند.
  • command: دستوری است که در هر تکرار اجرا می‌شود.
  • حلقه تنها زمانی متوقف می‌شود که شرط به true تبدیل شود.

مثال‌های استفاده از حلقه until

مثال 1: حلقه until برای چاپ اعداد از 1 تا 5

در این مثال، از حلقه until برای چاپ اعداد از 1 تا 5 استفاده می‌کنیم. این مثال مشابه مثال حلقه while است، با این تفاوت که در اینجا شرط معکوس است.

#!/bin/bash

i=1
until [ $i -gt 5 ]
do
    echo "عدد: $i"
    ((i++))
done

توضیح:
در اینجا، حلقه until تا زمانی که مقدار i از 5 بزرگتر نباشد، ادامه می‌یابد. هر بار که مقدار i به 1 افزایش می‌یابد، عدد آن چاپ می‌شود. این حلقه زمانی متوقف می‌شود که i از 5 بیشتر شود. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4
عدد: 5

مثال 2: حلقه until برای دریافت ورودی از کاربر

در این مثال، از حلقه until برای دریافت ورودی از کاربر استفاده می‌کنیم. حلقه ادامه می‌یابد تا زمانی که کاربر “خروج” را وارد کند.

#!/bin/bash

until [ "$input" == "خروج" ]
do
    read -p "لطفاً عبارتی وارد کنید (برای خروج 'خروج' را تایپ کنید): " input
    echo "شما وارد کردید: $input"
done

echo "خروج از برنامه."

توضیح:
در اینجا، حلقه until ادامه می‌یابد تا زمانی که کاربر عبارت “خروج” را وارد کند. پس از آن، پیام “خروج از برنامه” چاپ شده و حلقه متوقف می‌شود.


مثال 3: استفاده از حلقه until برای شمارش معکوس

در این مثال، از حلقه until برای انجام شمارش معکوس از 10 به 1 استفاده می‌کنیم.

#!/bin/bash

count=10
until [ $count -lt 1 ]
do
    echo "شماره: $count"
    ((count--))
done

توضیح:
در اینجا، حلقه until تا زمانی که مقدار count به کمتر از 1 برسد، اجرا می‌شود و در هر تکرار عدد فعلی شمارش معکوس چاپ می‌شود. خروجی به این شکل خواهد بود:

شماره: 10
شماره: 9
شماره: 8
شماره: 7
شماره: 6
شماره: 5
شماره: 4
شماره: 3
شماره: 2
شماره: 1

استفاده از دستورات break و continue در حلقه until

استفاده از break

در حلقه‌های until نیز می‌توان از دستور break برای متوقف کردن حلقه به‌صورت ناگهانی استفاده کرد. این دستور معمولاً در شرایط خاص به‌کار می‌رود که بخواهید زودتر از انتظار حلقه را متوقف کنید.

#!/bin/bash

count=1
until [ $count -gt 10 ]
do
    if [ $count -eq 5 ]; then
        break
    fi
    echo "عدد: $count"
    ((count++))
done

توضیح:
در اینجا، حلقه until از 1 تا 10 اجرا می‌شود. اما زمانی که مقدار count برابر 5 شود، دستور break اجرا شده و حلقه متوقف می‌شود. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4

استفاده از continue

دستور continue در حلقه until مشابه به حلقه‌های دیگر عمل می‌کند. این دستور باعث می‌شود که یک تکرار خاص نادیده گرفته شود و حلقه به تکرار بعدی خود ادامه دهد.

#!/bin/bash

count=1
until [ $count -gt 10 ]
do
    if [ $count -eq 5 ]; then
        ((count++))
        continue
    fi
    echo "عدد: $count"
    ((count++))
done

توضیح:
در اینجا، زمانی که مقدار count به 5 برسد، دستور continue اجرا می‌شود و آن تکرار نادیده گرفته می‌شود. سپس حلقه به تکرار بعدی ادامه می‌دهد. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4
عدد: 6
عدد: 7
عدد: 8
عدد: 9
عدد: 10

جمع‌بندی

حلقه until یکی از انواع حلقه‌های مهم در اسکریپت‌نویسی شل است که به‌طور معکوس نسبت به حلقه while عمل می‌کند. این حلقه تا زمانی که شرط مورد نظر غلط باشد اجرا می‌شود و به محض اینکه شرط به درست تغییر کند، متوقف می‌شود. حلقه until برای شرایطی مناسب است که بخواهید تا زمانی که یک حالت خاص محقق نشود، دستوراتی را تکرار کنید. همچنین، از دستورات break و continue می‌توان برای کنترل جریان اجرای حلقه استفاده کرد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. کنترل جریان در حلقه‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”دستور break” subtitle=”توضیحات کامل”]دستور break یکی از دستورات مهم در زبان‌های برنامه‌نویسی است که برای کنترل جریان اجرای برنامه در حلقه‌ها استفاده می‌شود. این دستور به‌ویژه در حلقه‌های for، while و until کاربرد دارد. وقتی دستور break درون یک حلقه اجرا می‌شود، حلقه بلافاصله متوقف می‌شود و کنترل به دستور بعد از حلقه منتقل می‌شود. این دستور معمولاً زمانی استفاده می‌شود که نیاز به پایان زودهنگام حلقه بر اساس یک شرط خاص باشد.


ساختار دستور break

ساختار دستور break به این صورت است:

break
  • بدون هیچ شرطی: به‌صورت پیش‌فرض، دستور break حلقه را متوقف می‌کند و از آن خارج می‌شود.

مثال‌های استفاده از دستور break

مثال 1: استفاده از break برای متوقف کردن حلقه for

در این مثال، از دستور break برای متوقف کردن حلقه for استفاده می‌کنیم. هدف این است که حلقه از 1 تا 10 اجرا شود، اما اگر به عدد 5 رسیدیم، حلقه متوقف شود.

#!/bin/bash

for i in {1..10}
do
    if [ $i -eq 5 ]; then
        echo "حلقه متوقف شد در عدد $i"
        break
    fi
    echo "عدد: $i"
done

توضیح:
در اینجا، حلقه for از 1 تا 10 اجرا می‌شود. اما زمانی که مقدار i برابر با 5 شود، دستور break اجرا شده و حلقه متوقف می‌شود. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد: 3
عدد: 4
حلقه متوقف شد در عدد 5

مثال 2: استفاده از break در حلقه while

در این مثال، از دستور break در حلقه while استفاده می‌کنیم تا وقتی عددی وارد شد که کمتر از 0 باشد، حلقه متوقف شود.

#!/bin/bash

while true
do
    read -p "لطفاً یک عدد وارد کنید (برای خروج عدد منفی وارد کنید): " number
    if [ $number -lt 0 ]; then
        echo "عدد منفی وارد شد. حلقه متوقف شد."
        break
    fi
    echo "شما وارد کردید: $number"
done

توضیح:
در اینجا، حلقه while به‌طور نامحدود اجرا می‌شود تا زمانی که کاربر عددی کمتر از 0 وارد کند. وقتی این اتفاق می‌افتد، دستور break اجرا شده و حلقه متوقف می‌شود. خروجی ممکن است به شکل زیر باشد:

لطفاً یک عدد وارد کنید (برای خروج عدد منفی وارد کنید): 5
شما وارد کردید: 5
لطفاً یک عدد وارد کنید (برای خروج عدد منفی وارد کنید): 10
شما وارد کردید: 10
لطفاً یک عدد وارد کنید (برای خروج عدد منفی وارد کنید): -1
عدد منفی وارد شد. حلقه متوقف شد.

مثال 3: استفاده از break در حلقه until

در این مثال، از دستور break در حلقه until برای متوقف کردن حلقه پس از رسیدن به یک شرط خاص استفاده می‌کنیم. در اینجا، حلقه از 1 شروع می‌شود و تا زمانی که به عدد 5 نرسیده باشد، اجرا می‌شود. اما اگر عدد 5 وارد شد، حلقه متوقف می‌شود.

#!/bin/bash

count=1
until [ $count -gt 5 ]
do
    if [ $count -eq 3 ]; then
        echo "حلقه متوقف شد در عدد $count"
        break
    fi
    echo "عدد: $count"
    ((count++))
done

توضیح:
در اینجا، حلقه until از 1 شروع می‌شود و تا زمانی که مقدار count از 5 بزرگتر نشود، اجرا می‌شود. اما زمانی که مقدار count برابر 3 شود، دستور break اجرا شده و حلقه متوقف می‌شود. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
حلقه متوقف شد در عدد 3

استفاده از break در حلقه‌های تو در تو

دستور break همچنین در حلقه‌های تو در تو (حلقه‌های داخل حلقه) نیز کاربرد دارد. اگر بخواهید تنها حلقه داخلی را متوقف کنید، باید از break به‌صورت معمولی استفاده کنید. اما اگر بخواهید حلقه خارجی را نیز متوقف کنید، باید از پارامتر break با یک عدد مشخص (نمایانگر تعداد حلقه‌های داخلی که می‌خواهید از آنها خارج شوید) استفاده کنید.

مثال 4: استفاده از break برای متوقف کردن حلقه داخلی و خارجی

#!/bin/bash

for i in {1..3}
do
    for j in {1..3}
    do
        echo "i: $i, j: $j"
        if [ $i -eq 2 ] && [ $j -eq 2 ]; then
            echo "خروج از حلقه‌ها"
            break 2
        fi
    done
done

توضیح:
در اینجا، از دستور break 2 استفاده شده است که باعث می‌شود هر دو حلقه (حلقه داخلی و خارجی) متوقف شوند زمانی که i و j هر دو برابر 2 شوند. خروجی به شکل زیر خواهد بود:

i: 1, j: 1
i: 1, j: 2
i: 1, j: 3
i: 2, j: 1
i: 2, j: 2
خروج از حلقه‌ها

جمع‌بندی

دستور break ابزاری است برای متوقف کردن یک حلقه در اسکریپت‌های شل. این دستور به‌ویژه زمانی کاربرد دارد که بخواهیم بر اساس یک شرط خاص، اجرای حلقه را به‌طور زودهنگام متوقف کنیم. استفاده از break در حلقه‌های for، while و until بسیار مفید است و می‌تواند در شرایط مختلف باعث کاهش پیچیدگی برنامه‌ها و بهبود کارایی آن‌ها شود. همچنین در حلقه‌های تو در تو، می‌توان از پارامتر عددی همراه با break برای متوقف کردن چند حلقه به‌صورت همزمان استفاده کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”دستور continue” subtitle=”توضیحات کامل”]دستور continue یکی دیگر از دستورات مفید در زبان‌های برنامه‌نویسی است که برای کنترل جریان اجرای حلقه‌ها استفاده می‌شود. این دستور در حلقه‌های for، while و until کاربرد دارد. زمانی که دستور continue درون یک حلقه اجرا می‌شود، حلقه به‌طور مستقیم به مرحله بعدی اجرا می‌رود و بقیه دستورات موجود در حلقه که پس از دستور continue قرار دارند، نادیده گرفته می‌شوند.

در حقیقت، دستور continue به حلقه می‌گوید که مرحله فعلی را رها کرده و به تکرار بعدی حلقه ادامه دهد. این دستور معمولاً زمانی استفاده می‌شود که بخواهیم به‌طور مشروط از ادامه‌ی دستورات در حلقه صرف‌نظر کنیم و به مرحله‌ی بعدی حلقه برویم.


ساختار دستور continue

ساختار دستور continue به‌صورت زیر است:

continue
  • بدون هیچ پارامتر یا شرطی: دستور continue حلقه را برای تکرار بعدی ادامه می‌دهد.

مثال‌های استفاده از دستور continue

مثال 1: استفاده از continue در حلقه for

در این مثال، از دستور continue برای پرش به مرحله بعدی حلقه استفاده می‌کنیم. اگر عددی فرد باشد، ادامه اجرای دستورات در حلقه را نادیده می‌گیریم و به مرحله بعدی حلقه می‌رویم.

#!/bin/bash

for i in {1..10}
do
    if [ $(($i % 2)) -eq 1 ]; then
        echo "عدد فرد: $i"
        continue
    fi
    echo "عدد زوج: $i"
done

توضیح:
در اینجا، حلقه از 1 تا 10 اجرا می‌شود. اگر عدد مورد نظر فرد باشد، دستور continue اجرا شده و از ادامه‌ی دستورات داخل حلقه صرف‌نظر می‌کند. در نتیجه فقط عددهای زوج چاپ می‌شوند و برای اعداد فرد پیام “عدد فرد” نمایش داده می‌شود. خروجی به این شکل خواهد بود:

عدد زوج: 2
عدد زوج: 4
عدد زوج: 6
عدد زوج: 8
عدد زوج: 10

مثال 2: استفاده از continue در حلقه while

در این مثال، از دستور continue در حلقه while استفاده می‌کنیم تا در صورتی که ورودی عدد منفی باشد، حلقه به‌طور مستقیم به تکرار بعدی ادامه دهد.

#!/bin/bash

while true
do
    read -p "لطفاً یک عدد وارد کنید (برای خروج عدد منفی وارد کنید): " number
    if [ $number -lt 0 ]; then
        echo "عدد منفی وارد شد. حلقه به پایان رسید."
        break
    fi
    if [ $number -eq 0 ]; then
        echo "عدد صفر وارد شد، ادامه می‌دهیم..."
        continue
    fi
    echo "شما وارد کردید: $number"
done

توضیح:
در اینجا، حلقه while به‌طور نامحدود اجرا می‌شود. اگر کاربر عدد 0 وارد کند، دستور continue اجرا می‌شود و حلقه به‌طور مستقیم به مرحله بعدی می‌رود. اگر کاربر عدد منفی وارد کند، دستور break اجرا می‌شود و حلقه متوقف می‌شود. خروجی ممکن است به این شکل باشد:

لطفاً یک عدد وارد کنید (برای خروج عدد منفی وارد کنید): 3
شما وارد کردید: 3
لطفاً یک عدد وارد کنید (برای خروج عدد منفی وارد کنید): 0
عدد صفر وارد شد، ادامه می‌دهیم...
لطفاً یک عدد وارد کنید (برای خروج عدد منفی وارد کنید): -1
عدد منفی وارد شد. حلقه به پایان رسید.

مثال 3: استفاده از continue در حلقه until

در این مثال، از دستور continue در حلقه until استفاده می‌کنیم تا اگر شمارنده از 5 کمتر از 3 بود، به‌طور مستقیم به مرحله بعدی حلقه برویم.

#!/bin/bash

count=1
until [ $count -gt 5 ]
do
    if [ $count -eq 3 ]; then
        echo "عدد 3 رسید. ادامه دادن به حلقه."
        continue
    fi
    echo "عدد: $count"
    ((count++))
done

توضیح:
در اینجا، حلقه until از 1 تا 5 اجرا می‌شود. زمانی که شمارنده به 3 می‌رسد، دستور continue اجرا می‌شود و حلقه به مرحله بعدی ادامه پیدا می‌کند بدون اینکه دستورات بعد از continue اجرا شوند. خروجی به این شکل خواهد بود:

عدد: 1
عدد: 2
عدد 3 رسید. ادامه دادن به حلقه.
عدد: 4
عدد: 5

استفاده از continue در حلقه‌های تو در تو

دستور continue می‌تواند در حلقه‌های تو در تو نیز استفاده شود. با استفاده از continue، می‌توانیم تنها حلقه داخلی یا خارجی را تحت تاثیر قرار دهیم. در صورتی که بخواهیم حلقه داخلی را نادیده بگیریم و به مرحله بعدی حلقه خارجی برویم، از continue در حلقه داخلی استفاده می‌کنیم.

مثال 4: استفاده از continue در حلقه‌های تو در تو

#!/bin/bash

for i in {1..3}
do
    for j in {1..3}
    do
        if [ $j -eq 2 ]; then
            echo "پرش از ج: $j در i: $i"
            continue
        fi
        echo "i: $i, j: $j"
    done
done

توضیح:
در این مثال، زمانی که j برابر با 2 می‌شود، دستور continue اجرا می‌شود و از اجرای دستورات باقی‌مانده در حلقه داخلی صرف‌نظر می‌شود. این باعث می‌شود که در هر تکرار حلقه داخلی، زمانی که j برابر با 2 شود، پرش صورت گیرد و دیگر دستورات اجرا نشوند. خروجی به این شکل خواهد بود:

i: 1, j: 1
پرش از ج: 2 در i: 1
i: 1, j: 3
i: 2, j: 1
پرش از ج: 2 در i: 2
i: 2, j: 3
i: 3, j: 1
پرش از ج: 2 در i: 3
i: 3, j: 3

جمع‌بندی

دستور continue ابزاری است برای کنترل جریان در حلقه‌ها که به ما این امکان را می‌دهد که به مرحله بعدی حلقه برویم و از اجرای باقی‌مانده دستورات در حلقه صرف‌نظر کنیم. این دستور در حلقه‌های for، while و until کاربرد دارد و معمولاً زمانی استفاده می‌شود که بخواهیم یک بخش از حلقه را نادیده بگیریم و به تکرار بعدی آن برویم. در حلقه‌های تو در تو، استفاده از continue به ما این امکان را می‌دهد که فقط حلقه داخلی یا خارجی را تحت تاثیر قرار دهیم و از پیچیدگی‌های اضافی جلوگیری کنیم.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. حلقه‌های تو در تو”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”حلقه‌های تو در تو: تعریف و کاربردها” subtitle=”توضیحات کامل”]حلقه‌های تو در تو (Nested Loops) به زمانی اطلاق می‌شود که یک حلقه (مثل for، while یا until) درون حلقه‌ی دیگری قرار گیرد. این نوع حلقه‌ها به‌طور خاص برای انجام وظایف پیچیده‌تری استفاده می‌شوند که نیاز به اجرای تعدادی حلقه داخلی برای هر تکرار حلقه خارجی دارند. در واقع، حلقه‌های تو در تو زمانی کاربرد دارند که بخواهیم از تعداد زیادی داده یا مجموعه‌ها به‌طور همزمان پردازش کنیم.

در اسکریپت‌های شل، این نوع حلقه‌ها معمولاً برای انجام عملیات روی آرایه‌ها، ماتریس‌ها یا داده‌های چند بعدی، مدیریت فایل‌ها در دایرکتوری‌های مختلف، و حتی انجام کارهای پیچیده‌تر مانند جستجو و مقایسه استفاده می‌شوند.


ساختار حلقه‌های تو در تو

یک حلقه تو در تو معمولاً از یک حلقه خارجی و یک یا چند حلقه داخلی تشکیل شده است. ساختار کلی یک حلقه تو در تو به شکل زیر است:

for i in {1..5}           # حلقه خارجی
do
    for j in {1..3}       # حلقه داخلی
    do
        # دستورات اجرا شده برای هر ترکیب i و j
    done
done

در این مثال، حلقه خارجی از 1 تا 5 تکرار می‌شود و به ازای هر تکرار حلقه خارجی، حلقه داخلی از 1 تا 3 تکرار خواهد شد. در مجموع، این حلقه تو در تو 15 بار اجرا خواهد شد (5 * 3).


کاربردهای حلقه‌های تو در تو

حلقه‌های تو در تو در اسکریپت‌های شل کاربردهای مختلفی دارند. برخی از کاربردهای رایج آنها عبارتند از:

  1. پردازش داده‌های چند بعدی (مانند ماتریس‌ها): برای پردازش داده‌هایی که به‌صورت جدول یا آرایه‌های چند بعدی ذخیره شده‌اند، می‌توان از حلقه‌های تو در تو استفاده کرد.
  2. پردازش مجموعه‌های بزرگ داده: زمانی که بخواهیم به‌طور همزمان به چندین مجموعه داده دسترسی پیدا کنیم، این حلقه‌ها مفید خواهند بود.
  3. مدیریت فایل‌ها و دایرکتوری‌ها: برای انجام عملیات روی فایل‌ها و دایرکتوری‌های مختلف به‌طور همزمان، از حلقه‌های تو در تو استفاده می‌کنیم.
  4. شبیه‌سازی فرآیندهای پیچیده‌تر: در الگوریتم‌های شبیه‌سازی، هنگامی که فرآیندهای متعدد یا تکرارهای متعددی نیاز است، حلقه‌های تو در تو به کار می‌آیند.

مثال‌های عملی از حلقه‌های تو در تو

مثال 1: پردازش یک آرایه دو بعدی

در این مثال، یک آرایه دو بعدی (مانند یک ماتریس) را تعریف می‌کنیم و سپس از حلقه‌های تو در تو برای دسترسی به عناصر آن استفاده می‌کنیم.

#!/bin/bash

# تعریف آرایه دو بعدی
matrix=(
    "1 2 3"
    "4 5 6"
    "7 8 9"
)

# حلقه تو در تو برای نمایش عناصر ماتریس
for row in "${matrix[@]}"
do
    for element in $row
    do
        echo -n "$element "
    done
    echo ""  # برای رفتن به خط بعد
done

توضیح:
در این اسکریپت، یک آرایه دو بعدی تعریف شده که شامل سه ردیف و سه ستون است. حلقه خارجی روی ردیف‌ها می‌چرخد و حلقه داخلی روی عناصر هر ردیف می‌رود. خروجی به شکل زیر خواهد بود:

1 2 3
4 5 6
7 8 9

مثال 2: جستجو در دایرکتوری‌های تو در تو

در این مثال، از حلقه‌های تو در تو برای جستجو در دایرکتوری‌ها و فایل‌های مختلف استفاده می‌کنیم.

#!/bin/bash

# بررسی دایرکتوری‌ها و فایل‌ها در دایرکتوری‌های فرعی
for dir in $(find . -type d)
do
    echo "بررسی دایرکتوری: $dir"
    for file in $(find $dir -type f)
    do
        echo "  فایل: $file"
    done
done

توضیح:
در این اسکریپت، ابتدا با استفاده از دستور find تمام دایرکتوری‌ها (و فایل‌ها) پیدا می‌شوند. حلقه خارجی برای هر دایرکتوری اجرا می‌شود و حلقه داخلی برای هر فایل موجود در دایرکتوری اجرا خواهد شد. این روش معمولاً برای مدیریت دایرکتوری‌های پیچیده و انجام عملیات روی فایل‌ها در سطوح مختلف دایرکتوری‌ها کاربرد دارد.


مثال 3: استفاده از حلقه‌های تو در تو برای مرتب‌سازی

در این مثال، از حلقه‌های تو در تو برای مرتب‌سازی یک آرایه استفاده می‌کنیم. این الگوریتم ساده را می‌توان برای توضیح نحوه کارکرد حلقه‌های تو در تو در فرآیند مرتب‌سازی به‌کار برد.

#!/bin/bash

# آرایه برای مرتب‌سازی
arr=(5 3 8 6 2 7)

# مرتب‌سازی با استفاده از حلقه‌های تو در تو
for ((i = 0; i < ${#arr[@]}; i++))
do
    for ((j = i + 1; j < ${#arr[@]}; j++))
    do
        if [ ${arr[$i]} -gt ${arr[$j]} ]; then
            # تعویض مقادیر
            temp=${arr[$i]}
            arr[$i]=${arr[$j]}
            arr[$j]=$temp
        fi
    done
done

# چاپ آرایه مرتب شده
echo "آرایه مرتب شده: ${arr[@]}"

توضیح:
در این اسکریپت، الگوریتمی مشابه “Bubble Sort” برای مرتب‌سازی یک آرایه به کار رفته است. حلقه خارجی به‌طور تک‌تک به هر عنصر آرایه نگاه می‌کند، و حلقه داخلی هر دو عنصر را مقایسه کرده و در صورت نیاز آنها را تعویض می‌کند. خروجی به این شکل خواهد بود:

آرایه مرتب شده: 2 3 5 6 7 8

جمع‌بندی

حلقه‌های تو در تو ابزار بسیار قدرتمندی در برنامه‌نویسی شل هستند که به ما این امکان را می‌دهند تا به‌طور همزمان با چندین مجموعه داده یا ساختار مختلف درگیر شویم. این حلقه‌ها به‌ویژه برای پردازش داده‌های چند بعدی، مدیریت فایل‌ها و دایرکتوری‌ها، و انجام عملیات پیچیده مفید هستند. در اسکریپت‌نویسی شل، حلقه‌های تو در تو می‌توانند به ما کمک کنند تا فرآیندهای پیچیده را به‌طور کارآمد و با کنترل بهتر روی داده‌ها انجام دهیم.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. کار با لیست‌ها و داده‌ها در حلقه‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پردازش فایل‌ها و داده‌ها با حلقه‌ها” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، پردازش فایل‌ها و داده‌ها یک وظیفه رایج است که می‌توان آن را با استفاده از حلقه‌ها انجام داد. حلقه‌ها به ما این امکان را می‌دهند که به‌طور خودکار و پیوسته به فایل‌ها و داده‌های موجود در آن‌ها دسترسی پیدا کرده و پردازش‌های مختلفی انجام دهیم. این پردازش‌ها می‌توانند شامل خواندن خطوط، جستجوی داده خاص، تغییر محتوای فایل یا اعمال پردازش‌های مختلف روی داده‌ها باشند.

حلقه‌ها به‌ویژه زمانی که تعداد زیادی فایل یا داده داشته باشیم بسیار مفید خواهند بود، زیرا این امکان را فراهم می‌کنند که عملیات مشابهی را روی مجموعه‌ای از فایل‌ها یا داده‌ها انجام دهیم بدون نیاز به تکرار کد برای هر فایل یا داده به‌طور مجزا.


پردازش خطوط یک فایل با استفاده از حلقه

یکی از رایج‌ترین استفاده‌های حلقه‌ها در اسکریپت‌نویسی شل، پردازش هر خط از یک فایل است. این کار معمولاً با استفاده از دستور while و دستور read انجام می‌شود.

مثال 1: خواندن خطوط یک فایل و پردازش آن‌ها

در این مثال، از حلقه while و دستور read برای خواندن هر خط از یک فایل و پردازش آن استفاده می‌کنیم.

#!/bin/bash

# نام فایل مورد نظر
file="example.txt"

# بررسی وجود فایل
if [ ! -f "$file" ]; then
    echo "فایل وجود ندارد."
    exit 1
fi

# خواندن هر خط از فایل و پردازش آن
while IFS= read -r line
do
    # انجام هر عملیاتی که لازم است با هر خط از فایل
    echo "خط خوانده شده: $line"
done < "$file"

توضیح:
در این اسکریپت، ابتدا فایل بررسی می‌شود که آیا وجود دارد یا خیر. سپس با استفاده از حلقه while و دستور read هر خط از فایل خوانده می‌شود و عملیات مورد نظر (در اینجا چاپ خط) روی آن انجام می‌شود.

  • IFS (Internal Field Separator) برای جلوگیری از تقسیم‌بندی ناخواسته رشته‌ها هنگام خواندن خطوط استفاده می‌شود.
  • -r در دستور read به‌منظور جلوگیری از تغییراتی است که ممکن است در رشته (مثل escape characters) رخ دهد.

خروجی این اسکریپت به‌صورت زیر خواهد بود:

خط خوانده شده: اولین خط از فایل
خط خوانده شده: دومین خط از فایل
خط خوانده شده: سومین خط از فایل

پردازش فایل‌های چندگانه با استفاده از حلقه

گاهی اوقات ممکن است بخواهیم عملیات مشابهی را روی چندین فایل انجام دهیم. برای این منظور می‌توانیم از حلقه‌های تو در تو یا حتی حلقه‌های ساده استفاده کنیم.

مثال 2: پردازش چندین فایل در یک دایرکتوری

در این مثال، از حلقه for برای پردازش تمام فایل‌های موجود در یک دایرکتوری استفاده می‌کنیم.

#!/bin/bash

# دایرکتوری حاوی فایل‌ها
directory="documents"

# بررسی وجود دایرکتوری
if [ ! -d "$directory" ]; then
    echo "دایرکتوری یافت نشد."
    exit 1
fi

# پردازش همه فایل‌ها در دایرکتوری
for file in "$directory"/*
do
    # اگر فایل است، عملیات را انجام بده
    if [ -f "$file" ]; then
        echo "در حال پردازش فایل: $file"
        # فرض کنید که ما خط اول هر فایل را می‌خوانیم
        head -n 1 "$file"
    fi
done

توضیح:
در این اسکریپت، از دستور for برای پردازش هر فایل در دایرکتوری documents استفاده می‌شود. دستور head -n 1 "$file" برای خواندن خط اول هر فایل به‌کار رفته است. این روش معمولاً برای پردازش فایل‌هایی که شامل داده‌های مختلف هستند بسیار کاربردی است.


جستجو در فایل‌ها و داده‌ها با استفاده از حلقه‌ها

یکی از قابلیت‌های دیگر حلقه‌ها در شل، جستجوی داده‌ها در فایل‌ها است. با استفاده از حلقه‌ها می‌توانیم به‌راحتی از طریق داده‌ها جستجو کنیم و در صورت یافتن داده مورد نظر، اقداماتی مانند حذف یا تغییر آن را انجام دهیم.

مثال 3: جستجو برای یک کلمه خاص در فایل

در این مثال، از حلقه‌ها برای جستجو در یک فایل و چاپ خطوطی که شامل کلمه خاصی هستند استفاده می‌کنیم.

#!/bin/bash

# فایل و کلمه جستجو
file="example.txt"
search_word="error"

# بررسی وجود فایل
if [ ! -f "$file" ]; then
    echo "فایل وجود ندارد."
    exit 1
fi

# جستجو در فایل برای کلمه خاص
while IFS= read -r line
do
    if [[ "$line" == *"$search_word"* ]]; then
        echo "کلمه '$search_word' در خط یافت شد: $line"
    fi
done < "$file"

توضیح:
در این اسکریپت، برای هر خط از فایل بررسی می‌شود که آیا شامل کلمه “error” است یا خیر. اگر خط حاوی این کلمه باشد، آن را چاپ می‌کند.

این روش می‌تواند برای جستجو در فایل‌های بزرگ، گزارش‌های سیستم، و بسیاری از سناریوهای دیگر مفید باشد.


تغییر محتوای فایل‌ها با استفاده از حلقه‌ها

گاهی اوقات ممکن است نیاز داشته باشیم محتوای یک فایل را به‌طور برنامه‌ریزی شده تغییر دهیم. برای این کار می‌توانیم از حلقه‌ها برای پردازش و ویرایش هر خط استفاده کنیم.

مثال 4: تغییر داده‌ها در فایل

در این مثال، قصد داریم تمام کلمات خاصی در یک فایل را با کلمه‌ای دیگر جایگزین کنیم.

#!/bin/bash

# فایل و کلمات
file="example.txt"
old_word="old"
new_word="new"

# بررسی وجود فایل
if [ ! -f "$file" ]; then
    echo "فایل وجود ندارد."
    exit 1
fi

# خواندن فایل و جایگزینی کلمه‌ها
while IFS= read -r line
do
    updated_line="${line//$old_word/$new_word}"
    echo "$updated_line"
done < "$file" > temp.txt && mv temp.txt "$file"

توضیح:
در این اسکریپت، هر خط از فایل خوانده می‌شود و کلمه old با کلمه new جایگزین می‌شود. سپس تغییرات به فایل اصلی برمی‌گردد. در نهایت، فایل موقت temp.txt به‌جای فایل اصلی قرار می‌گیرد.


جمع‌بندی

پردازش فایل‌ها و داده‌ها با استفاده از حلقه‌ها در شل یکی از مهم‌ترین تکنیک‌های اسکریپت‌نویسی است. با استفاده از حلقه‌ها می‌توانیم عملیات مختلفی نظیر خواندن، جستجو، و تغییر داده‌ها را در فایل‌ها انجام دهیم. این روش‌ها به‌ویژه زمانی که با حجم زیادی از داده‌ها روبه‌رو هستیم یا نیاز به انجام عملیات مشابه روی چندین فایل داریم، بسیار کارآمد خواهند بود.[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. کاربردهای عملی حلقه‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”کاربردهای عملی حلقه‌ها در وظایف اتوماسیون” subtitle=”توضیحات کامل”]حلقه‌ها در شل اسکریپت‌نویسی به‌عنوان ابزاری ضروری برای انجام وظایف تکراری و خودکار استفاده می‌شوند. از آنجایی که بسیاری از وظایف مدیریت سیستم و اتوماسیون به‌طور مداوم و به‌طور مشابه در سیستم‌های مختلف انجام می‌شوند، حلقه‌ها نقش بزرگی در ساده‌سازی و اتوماسیون این فرآیندها دارند.

در اینجا به برخی از رایج‌ترین کاربردهای حلقه‌ها در وظایف اتوماسیون اشاره خواهیم کرد. این وظایف معمولاً شامل مدیریت فایل‌ها، پشتیبان‌گیری از داده‌ها، نصب و بروزرسانی نرم‌افزارها، پردازش داده‌ها و بسیاری موارد دیگر هستند.


1. پشتیبان‌گیری خودکار از فایل‌ها و دایرکتوری‌ها

یکی از مهم‌ترین کاربردهای حلقه‌ها در اسکریپت‌نویسی شل، اتوماسیون فرآیند پشتیبان‌گیری از فایل‌ها و دایرکتوری‌ها است. با استفاده از حلقه‌ها می‌توانیم به‌طور خودکار فایل‌ها را کپی کرده و به مکان‌های دیگر انتقال دهیم.

مثال: پشتیبان‌گیری از چند دایرکتوری

در این مثال، از حلقه برای پشتیبان‌گیری از چند دایرکتوری به یک مقصد استفاده می‌کنیم.

#!/bin/bash

# دایرکتوری‌های برای پشتیبان‌گیری
directories=("/home/user/documents" "/home/user/pictures" "/home/user/videos")

# دایرکتوری مقصد برای ذخیره پشتیبان‌ها
backup_dir="/home/user/backup"

# بررسی وجود دایرکتوری مقصد
if [ ! -d "$backup_dir" ]; then
    echo "دایرکتوری پشتیبان وجود ندارد. ساخت دایرکتوری..."
    mkdir -p "$backup_dir"
fi

# پشتیبان‌گیری از دایرکتوری‌ها
for dir in "${directories[@]}"
do
    if [ -d "$dir" ]; then
        backup_name="$(basename "$dir")_$(date +'%Y%m%d%H%M').tar.gz"
        echo "پشتیبان‌گیری از $dir ..."
        tar -czf "$backup_dir/$backup_name" "$dir"
    else
        echo "دایرکتوری $dir پیدا نشد!"
    fi
done

توضیح:
در این اسکریپت، از یک حلقه for برای پشتیبان‌گیری از چند دایرکتوری استفاده می‌شود. هر دایرکتوری با استفاده از دستور tar به یک فایل فشرده تبدیل می‌شود. این اسکریپت می‌تواند برای پشتیبان‌گیری خودکار از داده‌ها به‌طور روزانه، هفتگی یا حتی ساعتی به‌کار رود.


2. نصب و به‌روزرسانی نرم‌افزارها

حلقه‌ها در فرآیند نصب و به‌روزرسانی نرم‌افزارها می‌توانند به‌طور خودکار تمام پکیج‌ها یا نرم‌افزارهای مورد نظر را نصب یا به‌روزرسانی کنند. این کار به‌ویژه در محیط‌هایی که باید تعداد زیادی نرم‌افزار به‌طور همزمان نصب یا بروزرسانی شوند، بسیار مفید است.

مثال: نصب و به‌روزرسانی نرم‌افزارها

در این مثال، از حلقه for برای نصب و به‌روزرسانی مجموعه‌ای از نرم‌افزارها استفاده می‌کنیم.

#!/bin/bash

# لیست نرم‌افزارهای مورد نظر برای نصب یا بروزرسانی
packages=("curl" "git" "vim" "htop")

# نصب و به‌روزرسانی نرم‌افزارها
for package in "${packages[@]}"
do
    if dpkg -l | grep -q "$package"; then
        echo "$package نصب شده است. بروزرسانی..."
        sudo apt-get install --only-upgrade "$package" -y
    else
        echo "$package نصب نشده است. در حال نصب..."
        sudo apt-get install "$package" -y
    fi
done

توضیح:
این اسکریپت ابتدا بررسی می‌کند که هر پکیج در سیستم نصب شده است یا نه. اگر نصب شده باشد، آن را به‌روزرسانی می‌کند و اگر نصب نشده باشد، اقدام به نصب آن می‌کند. این اسکریپت می‌تواند به‌طور خودکار نرم‌افزارها را در سیستم مدیریت کند.


3. نظارت و گزارش‌گیری از منابع سیستم

برای نظارت بر منابع سیستم مانند CPU، RAM، و فضای دیسک، می‌توان از حلقه‌ها برای جمع‌آوری داده‌ها و گزارش‌گیری به‌طور مداوم استفاده کرد. این کار می‌تواند برای جمع‌آوری اطلاعات و تولید گزارش‌های خودکار مفید باشد.

مثال: گزارش‌گیری از استفاده CPU

در این مثال، از حلقه while برای نظارت بر استفاده از CPU و تولید یک گزارش مداوم استفاده می‌کنیم.

#!/bin/bash

# گزارش استفاده از CPU در هر 5 ثانیه
while true
do
    cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
    echo "استفاده از CPU: $cpu_usage%"
    sleep 5
done

توضیح:
در این اسکریپت، از دستور top برای گرفتن اطلاعات مربوط به استفاده از CPU استفاده می‌شود و با استفاده از awk، درصد استفاده از CPU محاسبه می‌شود. این اطلاعات هر 5 ثانیه یک‌بار به‌روز رسانی می‌شود. این روش برای نظارت بر منابع سیستم در زمان واقعی کاربردی است.


4. حذف فایل‌های قدیمی و پاکسازی سیستم

حلقه‌ها می‌توانند برای مدیریت فایل‌ها و دایرکتوری‌های سیستم استفاده شوند. یکی از کاربردهای معمول این است که فایل‌های قدیمی‌تر از یک تاریخ خاص را پیدا کرده و حذف کنیم.

مثال: حذف فایل‌های قدیمی‌تر از 30 روز

در این مثال، از حلقه برای حذف فایل‌هایی که بیش از 30 روز از آخرین تغییر آن‌ها گذشته است، استفاده می‌کنیم.

#!/bin/bash

# دایرکتوری که باید فایل‌ها از آن حذف شوند
directory="/home/user/tmp"

# حذف فایل‌های قدیمی‌تر از 30 روز
find "$directory" -type f -mtime +30 -exec rm -f {} \;
echo "فایل‌های قدیمی‌تر از 30 روز حذف شدند."

توضیح:
در این اسکریپت، از دستور find برای یافتن فایل‌های قدیمی‌تر از 30 روز در دایرکتوری tmp استفاده می‌شود. سپس با استفاده از دستور rm این فایل‌ها حذف می‌شوند. این روش می‌تواند برای پاکسازی خودکار سیستم و آزادسازی فضا استفاده شود.


5. ارسال ایمیل‌های هشدار

حلقه‌ها می‌توانند برای ارسال هشدار به مدیر سیستم در صورت بروز مشکلات مختلف نیز به‌کار روند. به‌عنوان مثال، می‌توان از حلقه‌ها برای بررسی وضعیت سرویس‌ها و ارسال ایمیل هشدار در صورت توقف آن‌ها استفاده کرد.

مثال: ارسال ایمیل در صورت توقف سرویس

#!/bin/bash

# نام سرویس‌هایی که باید بررسی شوند
services=("apache2" "mysql" "ssh")

# بررسی وضعیت هر سرویس
for service in "${services[@]}"
do
    if ! systemctl is-active --quiet "$service"; then
        echo "$service متوقف شده است!" | mail -s "$service: هشدار" admin@example.com
        echo "ایمیل هشدار برای سرویس $service ارسال شد."
    else
        echo "$service در حال اجرا است."
    fi
done

توضیح:
این اسکریپت سرویس‌های apache2، mysql و ssh را بررسی می‌کند و در صورت متوقف بودن هرکدام، یک ایمیل هشدار برای مدیر سیستم ارسال می‌کند.


جمع‌بندی

حلقه‌ها یکی از ابزارهای اساسی در اسکریپت‌نویسی شل هستند که کاربردهای گسترده‌ای در اتوماسیون وظایف مختلف دارند. از جمله وظایفی که می‌توان با استفاده از حلقه‌ها به‌طور خودکار انجام داد، پشتیبان‌گیری از داده‌ها، نصب و به‌روزرسانی نرم‌افزارها، نظارت بر منابع سیستم، حذف فایل‌های قدیمی، و ارسال ایمیل‌های هشدار است. با استفاده از حلقه‌ها می‌توان کارهایی را که نیاز به تکرار دارند به‌طور خودکار انجام داد و زمان و منابع سیستم را بهینه‌سازی کرد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 7. بهینه‌سازی حلقه‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نکات کلیدی برای بهینه‌سازی حلقه‌ها” subtitle=”توضیحات کامل”]حلقه‌ها در شل اسکریپت‌نویسی ابزار قدرتمندی برای انجام وظایف تکراری هستند. با این حال، اگر حلقه‌ها به درستی طراحی یا بهینه‌سازی نشوند، می‌توانند باعث کاهش کارایی اسکریپت و مصرف منابع سیستم شوند. در این بخش، به نکات کلیدی برای بهینه‌سازی حلقه‌ها پرداخته می‌شود تا کارایی اسکریپت‌ها بالا برود و زمان اجرا کاهش یابد.


1. کاهش تعداد دستورات درون حلقه

هرچه تعداد دستورات درون حلقه کمتر باشد، حلقه سریع‌تر اجرا خواهد شد. بهتر است از اجرای دستورات پیچیده یا فراخوانی توابع در هر تکرار حلقه اجتناب کنید، مگر اینکه لازم باشد. اگر دستور یا تابعی را به طور مکرر در داخل حلقه فراخوانی می‌کنید، بهتر است آن را از حلقه بیرون آورده و فقط یکبار فراخوانی کنید.

مثال: فراخوانی تابع به خارج از حلقه

#!/bin/bash

# دستور پرکاربرد که در هر تکرار حلقه اجرا می‌شود
expensive_command="date +%Y-%m-%d"

# بهینه‌سازی: خارج کردن دستور پرهزینه از حلقه
for i in {1..10000}
do
    current_date=$($expensive_command)
    echo "Iteration $i: Current Date is $current_date"
done

توضیح:
در این مثال، دستور date که برای دریافت تاریخ جاری به کار می‌رود، درون حلقه تکرار قرار داشت و در هر تکرار اجرا می‌شد. با خروج آن از حلقه، تنها یکبار مقدار تاریخ محاسبه و سپس استفاده می‌شود که کارایی را به طور قابل توجهی افزایش می‌دهد.


2. استفاده از متغیرهای محلی به جای متغیرهای سراسری

متغیرهای محلی سریع‌تر از متغیرهای سراسری هستند. در صورت امکان، سعی کنید متغیرهایی که فقط در داخل حلقه به آن‌ها نیاز دارید را به‌صورت محلی تعریف کنید.

مثال: استفاده از متغیرهای محلی

#!/bin/bash

for i in {1..10000}
do
    # تعریف متغیر محلی داخل حلقه
    local_var=$((i * 2))
    echo "Iteration $i: Value is $local_var"
done

توضیح:
در این اسکریپت، متغیر local_var به صورت محلی تعریف شده است تا فقط در داخل حلقه استفاده شود. این کار باعث می‌شود که حافظه کمتری مصرف شود و عملیات سریع‌تر انجام شود.


3. اجتناب از استفاده از دستورات پرهزینه مانند echo یا printf در داخل حلقه‌ها

اگر حلقه‌ شما نیاز به چاپ داده‌ها دارد، بهتر است از ذخیره‌سازی مقادیر در یک متغیر استفاده کنید و در آخر کار، تمام خروجی‌ها را یکجا چاپ کنید. این کار به کاهش فراخوانی‌های اضافی و افزایش کارایی کمک می‌کند.

مثال: ذخیره‌سازی داده‌ها و چاپ آن‌ها به‌طور یکجا

#!/bin/bash

output=""

for i in {1..10000}
do
    output="$output Iteration $i"
done

echo "$output"

توضیح:
در این اسکریپت، به جای چاپ خروجی در هر تکرار حلقه، تمام داده‌ها در متغیر output ذخیره می‌شوند و در پایان یکبار چاپ می‌شوند. این روش نسبت به فراخوانی مکرر دستور echo به‌طور قابل توجهی سریع‌تر است.


4. استفاده از دستور break به‌طور بهینه

در صورتیکه شرایطی در حلقه وجود دارد که پس از آن نیازی به ادامه حلقه نیست (مثلاً پیدا کردن یک نتیجه خاص یا رسیدن به یک مقدار خاص)، از دستور break برای خاتمه حلقه استفاده کنید. این کار باعث می‌شود که از اجرای بیهوده حلقه جلوگیری شود و کارایی افزایش یابد.

مثال: استفاده از break برای توقف حلقه در صورت پیدا کردن مقدار مورد نظر

#!/bin/bash

for i in {1..10000}
do
    if [ $i -eq 5000 ]; then
        echo "Found 5000! Breaking the loop."
        break
    fi
done

توضیح:
در این مثال، به محض اینکه مقدار i به 5000 رسید، حلقه با استفاده از دستور break خاتمه می‌یابد. این کار از انجام تکرارهای بی‌مورد جلوگیری می‌کند و باعث بهینه شدن زمان اجرای اسکریپت می‌شود.


5. استفاده از read و ورودی‌ها به‌طور بهینه

در صورتی که حلقه نیاز به ورودی از کاربر یا فایل داشته باشد، بهینه‌سازی نحوه خواندن داده‌ها از اهمیت ویژه‌ای برخوردار است. برای جلوگیری از پردازش بیش از حد یا تکرار فراخوانی دستور read در هر تکرار، داده‌ها را یکجا خوانده و سپس از آن‌ها استفاده کنید.

مثال: خواندن یک فایل و پردازش خط به خط

#!/bin/bash

# خواندن یک فایل و پردازش خط به خط به‌طور بهینه
while IFS= read -r line
do
    echo "Processing: $line"
done < input.txt

توضیح:
در این مثال، با استفاده از دستور while و read داده‌ها از فایل input.txt به‌صورت خط به خط خوانده می‌شوند. این روش برای پردازش فایل‌های بزرگ بسیار کارآمد است و از بارگذاری داده‌ها به‌طور یکجا و اشغال حافظه اضافی جلوگیری می‌کند.


6. استفاده از دستورات داخلی به‌جای دستورات خارجی

در اسکریپت‌های شل، برخی دستورات به‌طور پیش‌فرض از برنامه‌های خارجی مانند grep, awk, یا sed استفاده می‌کنند. این دستورات ممکن است از لحاظ کارایی کمی کندتر باشند، به‌ویژه اگر درون حلقه‌ها به‌طور مکرر اجرا شوند. استفاده از دستورات داخلی شل مانند [[ ]] برای مقایسه‌ها و سایر عملیات داخلی می‌تواند سرعت را افزایش دهد.

مثال: مقایسه با استفاده از [[ ]] به جای grep

#!/bin/bash

for file in *.txt
do
    if [[ -f "$file" && "$file" =~ ^report.*\.txt$ ]]; then
        echo "Found report file: $file"
    fi
done

توضیح:
در این اسکریپت، از دستور [[ ]] برای مقایسه استفاده شده است، که نسبت به استفاده از grep یا دیگر ابزارهای خارجی سریع‌تر است.


7. استفاده از دستورات کم‌هزینه

در نهایت، برای بهینه‌سازی حلقه‌ها، مهم است که از دستورات کم‌هزینه و ساده استفاده کنید. از دستوراتی مانند echo, cat, و ls در داخل حلقه‌ها تنها در صورت لزوم استفاده کنید. این دستورات به‌ویژه زمانی که در داخل حلقه‌های بزرگ اجرا می‌شوند، می‌توانند باعث کند شدن اسکریپت شوند.


جمع‌بندی

بهینه‌سازی حلقه‌ها در اسکریپت‌نویسی شل می‌تواند تأثیر زیادی بر کارایی اسکریپت‌ها داشته باشد. با کاهش تعداد دستورات درون حلقه، استفاده از متغیرهای محلی، و اجتناب از دستورات پرهزینه مانند echo و printf، می‌توان زمان اجرا را کاهش داد. همچنین، استفاده از دستور break و continue به‌طور بهینه و به‌کارگیری دستورات داخلی شل می‌تواند باعث سرعت‌بخشی به اسکریپت‌ها شود. به‌کارگیری این روش‌ها در اسکریپت‌های خود، به‌ویژه در وظایف تکراری و اتوماسیون، می‌تواند بهره‌وری سیستم را بهبود بخشد.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش 6. توابع و آرگومان‌ها”][cdb_course_lesson title=”فصل 1. تعریف توابع”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مفهوم توابع در شل اسکریپت” subtitle=”توضیحات کامل”]توابع در شل اسکریپت‌ها به عنوان واحدهایی از کد تعریف می‌شوند که می‌توانند برای انجام وظایف خاص یا عملیات تکراری مورد استفاده قرار گیرند. استفاده از توابع در شل اسکریپت‌ها نه تنها موجب خوانایی بیشتر کد می‌شود، بلکه به سازماندهی و مدیریت بهتر اسکریپت‌ها نیز کمک می‌کند. در این بخش به مفهوم توابع، نحوه تعریف، استفاده، پارامترها و دیگر ویژگی‌های آن‌ها پرداخته می‌شود.


1. تعریف تابع در شل اسکریپت

توابع در شل اسکریپت‌ها به‌راحتی با استفاده از دستور function یا فقط با نام تابع تعریف می‌شوند. هر تابع معمولاً شامل یک یا چند دستور است که برای انجام یک وظیفه خاص در اسکریپت به کار می‌رود.

مثال: تعریف تابع ساده

#!/bin/bash

# تعریف یک تابع ساده برای چاپ پیغام
greet() {
    echo "Hello, welcome to shell scripting!"
}

# فراخوانی تابع
greet

توضیح:
در این مثال، تابع greet تعریف شده که تنها یک پیغام را چاپ می‌کند. پس از تعریف تابع، آن را با نوشتن نام تابع greet فراخوانی کرده‌ایم.


2. توابع با پارامتر (آرگومان)

توابع می‌توانند ورودی‌هایی دریافت کنند که به آن‌ها پارامتر یا آرگومان می‌گوییم. این پارامترها می‌توانند در داخل تابع مورد استفاده قرار گیرند و رفتار تابع را متناسب با ورودی تغییر دهند.

مثال: تابع با پارامتر

#!/bin/bash

# تعریف تابع برای چاپ سلام به یک نام خاص
greet() {
    echo "Hello, $1!"
}

# فراخوانی تابع با پارامتر
greet "Alice"
greet "Bob"

توضیح:
در این مثال، تابع greet یک پارامتر به نام $1 دریافت می‌کند که در داخل تابع چاپ می‌شود. با فراخوانی تابع و ارسال آرگومان‌های مختلف، تابع برای هر نام، پیغام مخصوصی را چاپ می‌کند.


3. استفاده از چندین پارامتر در توابع

توابع می‌توانند چندین پارامتر دریافت کنند. در این صورت، می‌توان به هر پارامتر به ترتیب از $1 تا $n دسترسی پیدا کرد.

مثال: تابع با چندین پارامتر

#!/bin/bash

# تعریف تابع برای جمع دو عدد
add_numbers() {
    sum=$(( $1 + $2 ))
    echo "The sum of $1 and $2 is: $sum"
}

# فراخوانی تابع با دو پارامتر
add_numbers 5 10

توضیح:
در این مثال، تابع add_numbers دو پارامتر دریافت می‌کند و مجموع آن‌ها را محاسبه و چاپ می‌کند. توجه داشته باشید که پارامترهای ورودی با استفاده از $1, $2 و … دسترسی پیدا می‌کنند.


4. دسترسی به تمام پارامترهای ورودی با $@ و $*

در شل، می‌توان به تمامی پارامترهای ورودی تابع از طریق متغیرهای ویژه $@ یا $* دسترسی پیدا کرد. این‌ها تمامی آرگومان‌های داده شده به تابع را در قالب یک لیست ذخیره می‌کنند.

مثال: استفاده از $@ و $*

#!/bin/bash

# تعریف تابع برای چاپ تمام پارامترها
print_all_params() {
    echo "All parameters: $@"
}

# فراخوانی تابع با چندین پارامتر
print_all_params "apple" "banana" "cherry"

توضیح:
در این مثال، تابع print_all_params تمامی پارامترهای ورودی را با استفاده از $@ چاپ می‌کند. توجه داشته باشید که استفاده از $@ و $* در شرایط خاص (مثلاً وجود فاصله‌ها در پارامترها) ممکن است تفاوت‌هایی داشته باشد.


5. بازگشت مقدار از تابع با استفاده از دستور return

در شل اسکریپت‌ها، توابع می‌توانند مقداری را به فراخوانی خود بازگردانند. این کار معمولاً با استفاده از دستور return صورت می‌گیرد. مقادیر برگشتی از توابع معمولاً به‌عنوان کد خروجی تابع استفاده می‌شوند، اما می‌توان آن‌ها را در متغیرها ذخیره کرد.

مثال: استفاده از return برای بازگشت مقدار

#!/bin/bash

# تعریف تابع برای انجام یک عملیات جمع و بازگشت نتیجه
add_numbers() {
    result=$(( $1 + $2 ))
    return $result
}

# فراخوانی تابع و ذخیره مقدار بازگشتی در متغیر
add_numbers 3 4
sum=$?

echo "The sum is: $sum"

توضیح:
در این مثال، تابع add_numbers عملیات جمع را انجام می‌دهد و نتیجه را با استفاده از دستور return باز می‌گرداند. سپس، مقدار برگشتی در متغیر sum ذخیره شده و چاپ می‌شود. توجه داشته باشید که دستور return تنها مقادیر کد خروجی (بین 0 تا 255) را می‌تواند بازگرداند. برای بازگشت مقادیر بزرگ‌تر، باید از روش‌های دیگری استفاده کرد (مانند تغییر مقادیر متغیرها).


6. توابع بازگشتی (Recursive Functions)

توابع می‌توانند به‌صورت بازگشتی (یعنی تابعی که خود را فراخوانی می‌کند) نوشته شوند. این ویژگی در بسیاری از الگوریتم‌ها مانند فاکتوریل یا حل مسائل بازگشتی مفید است.

مثال: تابع بازگشتی برای محاسبه فاکتوریل

#!/bin/bash

# تابع بازگشتی برای محاسبه فاکتوریل
factorial() {
    if [ $1 -le 1 ]; then
        echo 1
    else
        result=$(( $1 * $(factorial $(( $1 - 1 ))) ))
        echo $result
    fi
}

# فراخوانی تابع برای محاسبه فاکتوریل 5
factorial 5

توضیح:
در این مثال، تابع factorial به‌صورت بازگشتی تعریف شده است که برای محاسبه فاکتوریل عدد ورودی استفاده می‌شود. اگر ورودی برابر یا کمتر از 1 باشد، 1 را برمی‌گرداند و در غیر این صورت خود را با ورودی کاهش یافته فراخوانی می‌کند.


7. تنظیمات محلی در توابع

داخل هر تابع، می‌توان از متغیرهای محلی استفاده کرد تا از تداخل متغیرها با سایر بخش‌های اسکریپت جلوگیری شود. برای تعریف یک متغیر محلی، از دستور local استفاده می‌کنیم.

مثال: استفاده از local برای متغیرهای محلی

#!/bin/bash

# تابعی که از متغیرهای محلی استفاده می‌کند
calculate_sum() {
    local sum=$(( $1 + $2 ))
    echo "Sum is: $sum"
}

# فراخوانی تابع
calculate_sum 5 10

توضیح:
در این مثال، متغیر sum به‌صورت محلی در داخل تابع calculate_sum تعریف شده است. این به این معناست که متغیر sum تنها درون این تابع معتبر است و هیچ تأثیری بر متغیرهای خارج از تابع ندارد.


جمع‌بندی

توابع در شل اسکریپت‌ها ابزارهایی کارآمد برای سازماندهی کد و انجام وظایف تکراری هستند. با استفاده از توابع، می‌توان کدهای قابل استفاده مجدد ایجاد کرد که خوانایی و نگهداری اسکریپت‌ها را تسهیل می‌کنند. توابع می‌توانند پارامترهایی دریافت کنند و با استفاده از دستور return مقدار بازگشتی داشته باشند. استفاده از توابع بازگشتی نیز در حل مسائل پیچیده مفید است. به علاوه، با استفاده از متغیرهای محلی می‌توان از تداخل متغیرها در توابع مختلف جلوگیری کرد. توابع با ویژگی‌های خود می‌توانند به‌طور چشمگیری بر روی عملکرد و بهینه‌سازی اسکریپت‌ها تأثیر بگذارند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه تعریف یک تابع با استفاده از کلمات کلیدی function و بدون آن” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، توابع را می‌توان به دو روش تعریف کرد:

  1. استفاده از کلمه کلیدی function
  2. بدون استفاده از کلمه کلیدی function

هر دو روش مشابه یکدیگر عمل می‌کنند و تنها تفاوت در نحوه نوشتن آن‌ها است. در ادامه به تفصیل هر دو روش را بررسی خواهیم کرد.


1. تعریف تابع با استفاده از کلمه کلیدی function

در این روش، تابع با استفاده از کلمه کلیدی function و سپس نام تابع تعریف می‌شود. این روش بیشتر در شل‌های جدیدتر (مثل Bash) رایج است و به شل این امکان را می‌دهد که از ویژگی‌های اضافی برای توابع استفاده کند.

مثال:

#!/bin/bash

# تعریف تابع با استفاده از کلمه کلیدی function
function greet() {
    echo "Hello, World!"
}

# فراخوانی تابع
greet

توضیح:
در این مثال، تابع greet با استفاده از کلمه کلیدی function تعریف شده است. پس از تعریف، می‌توان آن را با نوشتن نام تابع (greet) فراخوانی کرد تا پیغام “Hello, World!” چاپ شود.


2. تعریف تابع بدون استفاده از کلمه کلیدی function

در این روش، تابع بدون استفاده از کلمه کلیدی function و تنها با نوشتن نام تابع و دستوراتی که قرار است در آن اجرا شوند، تعریف می‌شود. این روش در اکثر شل‌ها (از جمله نسخه‌های قدیمی‌تر Bash) قابل استفاده است و به‌طور گسترده‌ای در اسکریپت‌های شل استفاده می‌شود.

مثال:

#!/bin/bash

# تعریف تابع بدون استفاده از کلمه کلیدی function
greet() {
    echo "Hello, World!"
}

# فراخوانی تابع
greet

توضیح:
در اینجا، تابع greet به‌طور مستقیم با استفاده از نام تابع و دستوراتی که در داخل آن قرار دارند تعریف شده است. این روش ساده‌تر و کوتاه‌تر است، و عملکرد مشابه روش قبلی دارد.


3. تفاوت‌های میان دو روش

  1. خوانایی و سبک کدنویسی:
    • روش استفاده از function ممکن است در پروژه‌های بزرگ‌تر و شل‌هایی که ویژگی‌های خاصی دارند، کمی واضح‌تر به نظر برسد. به‌ویژه در پروژه‌های تیمی که کدنویسی با استانداردهای خاص انجام می‌شود، استفاده از function می‌تواند به‌عنوان یک استاندارد پذیرفته شود.
    • روش بدون function کوتاه‌تر و ساده‌تر است و در اکثر اسکریپت‌های شل به‌کار می‌رود.
  2. پشتیبانی از شل‌ها:
    • استفاده از function در بیشتر شل‌های جدید (مثل Bash) پشتیبانی می‌شود، اما در بعضی شل‌ها (مثل sh) این روش پشتیبانی نمی‌شود.
    • بدون function می‌توان از شل‌های قدیمی‌تری هم استفاده کرد و معمولا همه شل‌ها این روش را پشتیبانی می‌کنند.
  3. ویژگی‌های اضافی:
    • استفاده از function به شل اجازه می‌دهد تا برخی ویژگی‌های اضافی را برای مدیریت توابع فراهم کند، مثل اعمال محدودیت‌ها یا استفاده از ویژگی‌های خاص شل.

جمع‌بندی

در نهایت، هر دو روش برای تعریف توابع در شل اسکریپت‌ها به‌طور مؤثر عمل می‌کنند. انتخاب روش به نیازهای پروژه و شخصی‌سازی کدنویسی بستگی دارد. استفاده از function ممکن است در شل‌هایی که ویژگی‌های اضافی دارند مفید باشد، اما روش بدون function ساده‌تر و بیشتر استفاده می‌شود. با این حال، در بیشتر اسکریپت‌های شل، روش بدون function رایج‌تر است و خواناتر است، به‌ویژه برای اسکریپت‌های ساده و کوتاه.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”قواعد نام‌گذاری توابع در شل” subtitle=”توضیحات کامل”]در هنگام نوشتن اسکریپت‌های شل، یکی از مهم‌ترین نکات در طراحی توابع، رعایت قواعد نام‌گذاری است. نام‌های توابع باید قابل درک و معنادار باشند تا کد شما قابل نگهداری، خوانا و قابل فهم برای دیگران باشد. علاوه بر این، شل و سیستم‌عامل‌ها معمولاً برخی از قواعد و محدودیت‌ها را در نام‌گذاری توابع اعمال می‌کنند.

در اینجا به برخی از قواعد و نکات مهم در نام‌گذاری توابع شل پرداخته می‌شود:


1. استفاده از حروف الفبا و اعداد

  • توابع باید با یک حرف الفبا (حروف کوچک یا بزرگ) شروع شوند.
  • پس از حرف اول، می‌توانید از حروف الفبا (کوچک یا بزرگ)، اعداد (0-9) و آندرلاین (_) برای ساخت نام‌های توابع استفاده کنید.

مثال‌های صحیح:

my_function
process_data
calculate_2d_area

مثال‌های غلط:

2d_area       # شروع از عدد غیرمجاز
my-function   # استفاده از خط تیره، که غیرمجاز است

2. عدم استفاده از کاراکترهای خاص

در نام‌گذاری توابع در شل، نمی‌توان از کاراکترهای خاص مانند:

  • !, @, $, &, *, #, -, +
    و … استفاده کرد. این کاراکترها معمولاً برای انجام عملیات خاص در شل تعریف شده‌اند و نباید در نام توابع به کار روند.

مثال:

invalid@name   # نام غیرمجاز

3. توجه به حروف کوچک و بزرگ (Case Sensitivity)

شل‌ها به‌طور پیش‌فرض حساس به حروف بزرگ و کوچک هستند، به این معنی که my_function و My_function توابع متفاوتی محسوب می‌شوند. در اکثر اسکریپت‌های شل، معمولاً از حروف کوچک برای نام توابع استفاده می‌شود.

مثال:

my_function()   # مجاز
My_function()   # مجاز اما متفاوت از مورد قبلی

4. استفاده از آندرلاین برای جدا کردن کلمات

در نام‌گذاری توابع می‌توان از آندرلاین (_) برای جدا کردن کلمات استفاده کرد. این کار باعث می‌شود نام تابع خواناتر باشد. به این صورت که هر کلمه به‌صورت مجزا و واضح در نام تابع دیده شود.

مثال:

calculate_total_amount()
process_user_data()

5. عدم استفاده از نام‌های خاص سیستم

توابعی که در سیستم‌عامل شل به‌طور پیش‌فرض تعریف شده‌اند یا دستورات داخلی سیستم هستند، نباید با آن‌ها هم‌نام شوند. این کار می‌تواند باعث اختلال در عملکرد اسکریپت‌ها یا حتی موجب ایجاد خطاهایی در اجرا شود.

برای مثال:

  • دستورات خاص شل مانند echo, ls, cat, exit نباید به‌عنوان نام تابع استفاده شوند.

مثال:

exit()   # تعریف تابع با نام exit که یک دستور داخلی شل است

6. حداقل و حداکثر طول نام توابع

در بیشتر شل‌ها، هیچ محدودیت خاصی برای طول نام توابع وجود ندارد. با این حال، رعایت طول مناسب و خوانا بودن نام تابع از اهمیت بالایی برخوردار است. استفاده از نام‌های خیلی طولانی می‌تواند باعث پیچیدگی کد شود و خوانایی آن را کاهش دهد.

مثال:

calculate_area_of_rectangles_and_triangles()  # خیلی طولانی
calculate_area()   # مناسب‌تر

7. پرهیز از استفاده از واژه‌های رزرو شده

در شل، برخی از واژه‌ها و عبارات رزرو شده وجود دارند که در زبان شل به‌طور خاص تعریف شده‌اند و استفاده از آن‌ها به‌عنوان نام تابع ممکن است باعث بروز خطا در اسکریپت‌ها شود. از جمله این کلمات می‌توان به if, else, fi, then, do, done, for, while و غیره اشاره کرد.

مثال:

if()   # استفاده از نام‌های رزرو شده
done()  # نام تابع مشابه دستورات شل

8. استفاده از نام‌های معنادار و توصیفی

نام توابع باید به گونه‌ای باشد که عملکرد آن‌ها را به‌خوبی توضیح دهد. این کار موجب افزایش خوانایی و نگهداری کد می‌شود. از استفاده از نام‌های بی‌معنی و کوتاه پرهیز کنید.

مثال:

process_data()   # معنادار
p()              # نام نامشخص و کوتاه

جمع‌بندی

در نهایت، نام‌گذاری توابع در شل باید بر اساس قواعد و استانداردهایی انجام شود که باعث بهبود خوانایی، مدیریت و نگهداری کد می‌شود. استفاده از حروف الفبا، آندرلاین برای جدا کردن کلمات، اجتناب از کاراکترهای خاص و نام‌های رزرو شده و همچنین انتخاب نام‌های معنادار برای توابع از جمله نکات مهم در نام‌گذاری توابع هستند. رعایت این اصول در هنگام نوشتن اسکریپت‌های شل، نه تنها موجب کاهش خطاها می‌شود، بلکه باعث می‌شود کد شما برای دیگران نیز قابل درک‌تر و قابل نگهداری‌تر باشد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تفاوت بین تعریف تابع با پرانتز و بدون پرانتز” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، توابع می‌توانند به دو روش مختلف تعریف شوند: با استفاده از پرانتز یا بدون استفاده از پرانتز. این دو روش از نظر نحو (syntax) تفاوت‌هایی دارند که در ادامه به‌طور کامل به آن‌ها پرداخته می‌شود.


1. تعریف تابع با پرانتز

در این روش، نام تابع پس از کلمه کلیدی function آمده و سپس پرانتز قرار می‌گیرد. به‌طور کلی، پرانتز در این روش به‌طور اختیاری استفاده می‌شود و فقط در هنگام تعریف تابع نشان‌دهنده این است که این یک تابع است. از پرانتز برای نمایش پارامترهای ورودی تابع استفاده می‌شود، ولی در بیشتر مواقع برای توابع ساده می‌توان از آن‌ها صرف‌نظر کرد.

نحوه تعریف:

function my_function() {
  echo "Hello from function with parentheses!"
}
  • در اینجا، کلمه function اختیاری است، ولی پرانتز (همچنین پارامترهای داخل پرانتز) معمولاً برای نمایش و مشخص کردن پارامترهای ورودی به کار می‌روند.
  • پس از پرانتز، بلوک دستوراتی که تابع انجام می‌دهد درون {} قرار می‌گیرد.

2. تعریف تابع بدون پرانتز

در این روش، برای تعریف تابع از کلمه کلیدی function استفاده نمی‌شود و تابع فقط با نام تابع و دستوراتی که باید اجرا شوند، تعریف می‌شود. این روش رایج‌تر است و در شل‌های قدیمی‌تر نیز استفاده می‌شده است. همچنین در این حالت، نیازی به استفاده از پرانتز برای ورودی‌ها یا خروجی‌ها ندارید.

نحوه تعریف:

my_function() {
  echo "Hello from function without parentheses!"
}
  • در این روش از تعریف تابع، نام تابع بلافاصله با () همراه نیست و بدون function تعریف می‌شود.
  • پرانتز به‌طور پیش‌فرض برای تعریف ورودی‌ها استفاده نمی‌شود.

تفاوت‌های اصلی

1. استفاده از function

  • در روش تعریف تابع با پرانتز، استفاده از کلمه کلیدی function اختیاری است، اما در روش بدون پرانتز نیازی به استفاده از کلمه function نیست.
  • اگر از function استفاده کنید، توابع معمولاً برای زبان‌های شل مانند bash به‌وضوح تعریف می‌شوند.

2. پرانتز

  • در روش با پرانتز، تعریف تابع معمولاً همراه با پرانتزهایی است که برای آرگومان‌ها (پارامترهای ورودی) در نظر گرفته می‌شود، هرچند که در اغلب اسکریپت‌ها نیازی به استفاده از پارامترهای ورودی نخواهید داشت.
  • در روش بدون پرانتز، نام تابع به‌طور مستقیم بدون نیاز به پرانتز بیان می‌شود و معمولا کد ساده‌تر به نظر می‌آید.

3. قابلیت‌های استفاده از پرانتز

  • پرانتز در تعریف تابع (با function یا بدون آن) به‌طور ضمنی برای تفکیک دستورات و تغییرات ورودی‌ها استفاده می‌شود، ولی در حالت بیشتر درون اسکریپت‌ها فقط برای مشخص‌کردن پارامترها یا ورودی‌ها استفاده می‌شود.

4. سازگاری و استاندارد

  • روش بدون پرانتز به‌عنوان روش استاندارد و پرکاربردتر در بسیاری از شل‌ها به‌ویژه bash شناخته می‌شود.
  • روش با پرانتز در بعضی از نسخه‌های خاص شل و به‌ویژه در زبان‌های دیگر مانند zsh و ksh رایج‌تر است.

جمع‌بندی

در نهایت، می‌توان گفت که تفاوت اصلی در نحوه نگارش تابع است. تعریف تابع با پرانتز معمولاً با کلمه کلیدی function همراه است و بیشتر در مواقعی که می‌خواهید پارامترهای ورودی به تابع را مشخص کنید، به‌کار می‌رود. در حالی که تعریف تابع بدون پرانتز ساده‌تر است و در شل‌های بیشتر، از جمله bash، رایج‌تر است. انتخاب بین این دو روش بستگی به نیاز و سبک کد شما دارد. با این حال، در بیشتر مواقع، تعریف توابع بدون پرانتز معمول و رایج‌تر است.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. فراخوانی توابع”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”فراخوانی توابع در اسکریپت شل” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، پس از تعریف یک تابع، می‌توان آن را فراخوانی کرد تا دستورات درون آن اجرا شوند. روش‌های مختلفی برای فراخوانی توابع وجود دارد که هرکدام کاربرد خاص خود را دارند. در اینجا، روش‌های مختلف فراخوانی توابع را به همراه مثال‌های عملی توضیح می‌دهیم.


1. فراخوانی تابع با استفاده از نام تابع

ساده‌ترین و رایج‌ترین روش برای فراخوانی تابع، استفاده از نام تابع است. در این روش، کافی است نام تابع را بنویسید تا تابع فراخوانی شود و دستورات درون آن اجرا شوند. این روش به‌ویژه در توابع بدون آرگومان کاربرد دارد.

نحوه فراخوانی:
my_function() {
  echo "Hello, World!"
}

# فراخوانی تابع
my_function
  • در اینجا، تابع my_function بدون هیچ‌گونه آرگومان فراخوانی می‌شود و متن “Hello, World!” در خروجی چاپ خواهد شد.

2. فراخوانی تابع با استفاده از آرگومان‌ها

اگر تابع دارای ورودی‌ها یا آرگومان‌هایی باشد، می‌توان آن‌ها را در هنگام فراخوانی تابع به آن ارسال کرد. آرگومان‌ها در شل با استفاده از متغیرهای $1, $2, …، در داخل تابع قابل دسترسی هستند.

نحوه فراخوانی:
my_function() {
  echo "Hello, $1!"
}

# فراخوانی تابع با یک آرگومان
my_function "Alice"
  • در این مثال، تابع my_function یک آرگومان به نام Alice می‌گیرد و پیغام “Hello, Alice!” را چاپ می‌کند.

3. استفاده از دستور return برای بازگشت از تابع

در هنگام فراخوانی تابع، ممکن است بخواهید نتیجه‌ای را از تابع بازگردانید. برای این کار، می‌توان از دستور return در داخل تابع استفاده کرد. مقدار بازگشتی با استفاده از کد وضعیت خروجی در شل (که معمولاً 0 برای موفقیت و غیر صفر برای خطا است) به فراخوانی‌کننده منتقل می‌شود.

نحوه فراخوانی با return:
my_function() {
  if [ $1 -gt 10 ]; then
    return 0
  else
    return 1
  fi
}

# فراخوانی تابع و بررسی کد وضعیت بازگشتی
my_function 15
if [ $? -eq 0 ]; then
  echo "Number is greater than 10"
else
  echo "Number is less than or equal to 10"
fi
  • در اینجا، تابع my_function بررسی می‌کند که آیا آرگومان ورودی بزرگتر از 10 است یا خیر و کد وضعیت مناسب را باز می‌گرداند. سپس از متغیر خاص $? برای بررسی نتیجه استفاده می‌شود.

4. فراخوانی توابع به‌صورت درون‌خطی (Inline)

در برخی مواقع، می‌توان توابع را به‌صورت درون‌خطی در شل اسکریپت فراخوانی کرد. به این معنا که تابع درون یک خط از اسکریپت فراخوانی می‌شود. این روش معمولاً زمانی کاربرد دارد که تابع نیاز به ورودی یا پیغام خاصی نداشته باشد و فقط برای انجام یک عملیات سریع فراخوانی شود.

نحوه فراخوانی درون‌خطی:
my_function() { echo "This is an inline function"; }

# فراخوانی تابع به صورت درون خطی
my_function && echo "Function executed successfully"
  • در اینجا، تابع my_function بلافاصله پس از تعریف در یک خط اجرا می‌شود و سپس پیغام “Function executed successfully” به‌طور موفقیت‌آمیز چاپ می‌شود.

5. فراخوانی تابع از درون یک حلقه

یکی از رایج‌ترین روش‌های استفاده از توابع، فراخوانی آن‌ها از داخل حلقه‌ها است. این کار معمولاً زمانی انجام می‌شود که نیاز به انجام یک عمل خاص روی هر عنصر از یک لیست یا آرایه داشته باشیم.

نحوه فراخوانی در حلقه:
my_function() {
  echo "Processing $1"
}

# فراخوانی تابع درون یک حلقه
for item in "apple" "banana" "cherry"; do
  my_function $item
done
  • در این مثال، تابع my_function برای هر یک از آیتم‌های موجود در لیست فراخوانی می‌شود و پیامی مشابه “Processing apple” یا “Processing banana” چاپ می‌شود.

6. فراخوانی تابع به‌صورت غیرهمزمان با &

گاهی اوقات ممکن است بخواهید تابع را به‌صورت غیرهمزمان اجرا کنید تا اسکریپت شما در حال اجرای تابع، به کارهای دیگر ادامه دهد. برای این کار می‌توانید از علامت & در انتهای فراخوانی تابع استفاده کنید.

نحوه فراخوانی غیرهمزمان:
my_function() {
  sleep 5
  echo "Function executed after 5 seconds"
}

# فراخوانی تابع به صورت غیرهمزمان
my_function &
echo "This message is printed while the function is still running"
  • در اینجا، تابع my_function به‌صورت غیرهمزمان اجرا می‌شود و در حالی که این تابع در حال خوابیدن است، پیام “This message is printed while the function is still running” چاپ می‌شود.

جمع‌بندی

در این قسمت، روش‌های مختلف فراخوانی توابع در اسکریپت‌های شل را بررسی کردیم. روش‌ها شامل فراخوانی ساده با استفاده از نام تابع، فراخوانی با آرگومان‌ها، استفاده از دستور return برای بازگشت نتیجه از تابع، فراخوانی درون‌خطی، فراخوانی غیرهمزمان با & و همچنین فراخوانی توابع از داخل حلقه‌ها بودند. انتخاب روش فراخوانی مناسب بستگی به نیاز خاص اسکریپت و ساختار آن دارد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”اجرای توابع با آرگومان‌های مختلف” subtitle=”توضیحات کامل”]در شل اسکریپت‌نویسی، توابع می‌توانند آرگومان‌هایی را از فراخوانی دریافت کنند که این آرگومان‌ها می‌توانند برای پردازش داده‌ها در داخل تابع استفاده شوند. به همین دلیل، فراخوانی توابع با آرگومان‌های مختلف یکی از مهم‌ترین بخش‌های توسعه اسکریپت‌ها است، چرا که به انعطاف‌پذیری و استفاده مجدد از کد کمک می‌کند. در این بخش، نحوه اجرای توابع با آرگومان‌های مختلف، انواع مختلف آرگومان‌ها و نحوه استفاده از آن‌ها را بررسی می‌کنیم.


1. تعریف تابع با آرگومان‌ها

برای اینکه یک تابع بتواند آرگومان دریافت کند، کافی است هنگام فراخوانی آن، مقادیری را به تابع ارسال کنید. این مقادیر در داخل تابع با استفاده از متغیرهای خاصی مانند $1, $2, $3, … (بسته به تعداد آرگومان‌ها) قابل دسترسی خواهند بود.

نحوه تعریف و اجرای تابع با آرگومان‌ها:
# تعریف تابع با آرگومان‌ها
greet_user() {
  echo "Hello, $1! Welcome to $2."
}

# فراخوانی تابع با آرگومان‌ها
greet_user "Alice" "Shell Scripting"
  • در اینجا، تابع greet_user دو آرگومان دریافت می‌کند: اولین آرگومان به‌عنوان نام کاربر و دومین آرگومان به‌عنوان نام پروژه یا محیطی که در آن قرار دارد. نتیجه‌ای که در خروجی خواهیم دید به شکل زیر خواهد بود:
    Hello, Alice! Welcome to Shell Scripting.
    

2. استفاده از تعداد متغیرهای متغیر برای دریافت آرگومان‌های متعدد

گاهی اوقات نیاز داریم که تابع تعداد نامشخصی از آرگومان‌ها را دریافت کند. در این مواقع، می‌توانیم از متغیر ویژه "$@" یا "$*" برای دسترسی به تمامی آرگومان‌ها استفاده کنیم.

نحوه استفاده از "$@":
# تابعی که تمامی آرگومان‌ها را چاپ می‌کند
print_args() {
  for arg in "$@"; do
    echo "Argument: $arg"
  done
}

# فراخوانی تابع با چند آرگومان
print_args "Apple" "Banana" "Cherry"
  • در این مثال، تابع print_args تمامی آرگومان‌هایی که به آن داده می‌شود را یکی‌یکی چاپ می‌کند. خروجی به شکل زیر خواهد بود:
    Argument: Apple
    Argument: Banana
    Argument: Cherry
    

3. استفاده از آرگومان‌های پیش‌فرض

در بعضی مواقع ممکن است که آرگومان‌هایی به تابع ارسال نشود. برای این مواقع، می‌توانیم مقادیر پیش‌فرض برای آرگومان‌ها تعیین کنیم تا در صورت نبود ورودی از جانب کاربر، مقدار پیش‌فرض به‌طور خودکار استفاده شود.

نحوه استفاده از مقادیر پیش‌فرض:
# تعریف تابع با مقدار پیش‌فرض
greet_user() {
  local name=${1:-"Guest"}
  local language=${2:-"Shell Scripting"}
  echo "Hello, $name! Welcome to $language."
}

# فراخوانی تابع بدون آرگومان‌ها
greet_user
  • در اینجا، اگر هیچ آرگومانی ارسال نشود، مقدار “Guest” برای نام و “Shell Scripting” برای زبان به‌عنوان پیش‌فرض در نظر گرفته می‌شود. خروجی تابع به شکل زیر خواهد بود:
    Hello, Guest! Welcome to Shell Scripting.
    

4. دریافت تعداد آرگومان‌ها با استفاده از $#

در بعضی مواقع، نیاز داریم که بدانیم تعداد آرگومان‌های دریافتی چقدر است. برای این منظور، از متغیر $# استفاده می‌کنیم که تعداد آرگومان‌های ورودی را نشان می‌دهد.

نحوه استفاده از $#:
# تابعی که تعداد آرگومان‌ها را نمایش می‌دهد
count_args() {
  echo "Number of arguments: $#"
}

# فراخوانی تابع با تعداد مختلف آرگومان‌ها
count_args "Apple" "Banana" "Cherry"
count_args "Only one"
  • خروجی این مثال به شکل زیر خواهد بود:
    Number of arguments: 3
    Number of arguments: 1
    

5. فراخوانی توابع با آرگومان‌های متغیر

گاهی اوقات ممکن است بخواهید تابعی را به‌طور دینامیک با تعداد و نوع مختلفی از آرگومان‌ها فراخوانی کنید. برای این کار می‌توانید از آرایه‌ها یا متغیرهای پویا استفاده کنید تا آرگومان‌ها را به تابع ارسال کنید.

نحوه ارسال آرگومان‌های متغیر به تابع:
# تعریف تابع
dynamic_args() {
  echo "Arguments received: $@"
}

# آرایه از آرگومان‌ها
args=("Apple" "Banana" "Cherry")

# ارسال آرگومان‌ها به تابع
dynamic_args "${args[@]}"
  • در این مثال، آرایه‌ای از آرگومان‌ها به تابع dynamic_args ارسال می‌شود و خروجی مشابه به این خواهد بود:
    Arguments received: Apple Banana Cherry
    

جمع‌بندی

در این بخش، روش‌های مختلف اجرای توابع با آرگومان‌های مختلف را بررسی کردیم. از جمله این روش‌ها می‌توان به ارسال آرگومان‌ها به توابع، استفاده از متغیرهای خاص برای دریافت تمامی آرگومان‌ها، تعیین مقادیر پیش‌فرض برای آرگومان‌ها، بررسی تعداد آرگومان‌ها و ارسال آرگومان‌های متغیر به توابع اشاره کرد. این روش‌ها به توسعه‌دهندگان امکان می‌دهند که توابع را به‌صورت انعطاف‌پذیر و عمومی‌تری بنویسند و آن‌ها را در سناریوهای مختلف استفاده کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه دسترسی به مقدار بازگشتی توابع” subtitle=”توضیحات کامل”]در شل اسکریپت‌نویسی، توابع می‌توانند مقادیری را بازگشت دهند که معمولاً برای استفاده در بخش‌های دیگر اسکریپت یا انجام محاسبات بعدی استفاده می‌شود. این مقادیر می‌توانند به‌صورت مقادیر عددی، متنی، یا حتی کدهای خطا باشند. در این بخش، نحوه دسترسی به مقدار بازگشتی توابع را با جزئیات بیشتر توضیح خواهیم داد و مثال‌های عملی ارائه خواهیم کرد.


1. مقدار بازگشتی از طریق دستور return

در شل، توابع می‌توانند از دستور return برای بازگشت مقادیر استفاده کنند. معمولاً مقادیر بازگشتی از نوع عددی هستند (عدد صحیح از ۰ تا ۲۵۵) که در صورت موفقیت‌آمیز بودن اجرا، مقدار ۰ برگشت داده می‌شود و در صورت وجود خطا، مقادیر دیگر.

نحوه استفاده از دستور return:
# تعریف تابعی با return
add_numbers() {
  local sum=$(( $1 + $2 ))
  return $sum
}

# فراخوانی تابع
add_numbers 5 10

# دسترسی به مقدار بازگشتی با استفاده از $?
echo "The sum is: $?"
  • در این مثال، تابع add_numbers دو عدد را جمع می‌کند و نتیجه را با دستور return به‌صورت کد خروجی باز می‌گرداند. متغیر $? برای دسترسی به کد خروجی آخرین دستور یا تابع استفاده می‌شود.
  • خروجی این کد به این صورت خواهد بود:
    The sum is: 15
    
  • نکته: مقدار بازگشتی از return معمولاً برای نشان دادن وضعیت انجام عملیات (مثلاً موفقیت یا شکست) استفاده می‌شود و تنها از اعداد صحیح (۰ تا ۲۵۵) پشتیبانی می‌کند.

2. دستگاه خروجی استاندارد (stdout) برای بازگشت داده‌های پیچیده‌تر

اگر نیاز دارید که مقداری پیچیده‌تر از یک عدد (مثل رشته‌ها یا داده‌های بزرگ) را از تابع بازگردانید، می‌توانید از خروجی استاندارد (stdout) استفاده کنید. برای این کار از دستور echo داخل تابع استفاده می‌کنیم و خروجی آن را در جایی دیگر ذخیره می‌کنیم.

نحوه بازگشت مقدار با استفاده از echo:
# تعریف تابعی که رشته‌ای را باز می‌گرداند
greet_user() {
  echo "Hello, $1!"
}

# فراخوانی تابع و ذخیره نتیجه در یک متغیر
result=$(greet_user "Alice")

# نمایش نتیجه
echo "Greeting message: $result"
  • در این مثال، تابع greet_user رشته‌ای را با استفاده از دستور echo تولید کرده و به‌عنوان خروجی باز می‌گرداند. مقدار این خروجی در متغیر result ذخیره می‌شود.
  • خروجی این کد به این صورت خواهد بود:
    Greeting message: Hello, Alice!
    
  • نکته: استفاده از دستور echo برای بازگشت داده‌ها به متغیرها یکی از روش‌های متداول در شل اسکریپت‌نویسی است که به شما امکان می‌دهد داده‌های پیچیده‌تری از جمله رشته‌ها را به راحتی به بخش‌های دیگر اسکریپت منتقل کنید.

3. دسترسی به مقدار بازگشتی در شرایط پیچیده‌تر

ممکن است بخواهید مقادیر بازگشتی از توابع را در شرایط پیچیده‌تری مورد استفاده قرار دهید. برای این کار می‌توانید از ترکیب دستورات مختلف برای پردازش مقادیر بازگشتی استفاده کنید.

مثال با استفاده از دستور read برای دریافت ورودی:
# تابعی که یک مقدار را باز می‌گرداند
calculate_area() {
  local radius=$1
  local area=$(echo "scale=2; 3.14 * $radius * $radius" | bc)
  echo $area
}

# فراخوانی تابع و ذخیره نتیجه در یک متغیر
area=$(calculate_area 5)

# استفاده از نتیجه
echo "The area of the circle is: $area"
  • در این مثال، تابع calculate_area مساحت دایره را محاسبه کرده و نتیجه را با استفاده از دستور echo به‌عنوان مقدار بازگشتی ارسال می‌کند. سپس این مقدار در متغیر area ذخیره می‌شود.
  • خروجی به این صورت خواهد بود:
    The area of the circle is: 78.50
    

4. چندین مقدار بازگشتی از طریق آرایه‌ها

در شل، نمی‌توانید بیش از یک مقدار را مستقیماً با دستور return یا echo بازگردانید. با این حال، می‌توانید برای ارسال چندین مقدار از آرایه‌ها استفاده کنید.

مثال استفاده از آرایه‌ها برای بازگشت چندین مقدار:
# تابعی که چندین مقدار را در آرایه باز می‌گرداند
calculate_values() {
  local a=10
  local b=20
  local sum=$((a + b))
  local diff=$((a - b))
  local result=($sum $diff)
  echo "${result[@]}"
}

# فراخوانی تابع و ذخیره نتیجه در متغیر
values=$(calculate_values)

# نمایش مقادیر بازگشتی
echo "Sum and Difference: $values"
  • در این مثال، تابع calculate_values دو مقدار (جمع و تفاضل دو عدد) را محاسبه کرده و در یک آرایه ذخیره می‌کند. سپس مقادیر آرایه را با استفاده از دستور echo باز می‌گرداند.
  • خروجی این کد به شکل زیر خواهد بود:
    Sum and Difference: 30 -10
    

جمع‌بندی

در این بخش، به روش‌های مختلف دسترسی به مقدار بازگشتی توابع در شل اسکریپت‌نویسی پرداختیم. توابع می‌توانند مقادیر را از طریق دستور return (برای بازگشت مقادیر عددی) یا خروجی استاندارد (echo) بازگردانند. همچنین برای ارسال مقادیر پیچیده‌تر یا چندین مقدار از آرایه‌ها استفاده می‌شود. درک نحوه بازگشت و استفاده از مقادیر در توابع برای نوشتن اسکریپت‌های قدرتمند و منعطف بسیار مهم است.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. پارامترها و آرگومان‌ها در توابع”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از $1, $2, … برای دسترسی به آرگومان‌های ورودی” subtitle=”توضیحات کامل”]در شل اسکریپت‌نویسی، می‌توانید مقادیر ورودی که به اسکریپت یا تابع ارسال می‌شود را با استفاده از متغیرهای خاص مانند $1, $2, $3 و غیره دسترسی پیدا کنید. این مقادیر به‌طور معمول به‌عنوان آرگومان‌های ورودی شناخته می‌شوند و به شما این امکان را می‌دهند که اسکریپت‌ها یا توابع خود را انعطاف‌پذیرتر و پویا تر بنویسید.


1. آرگومان‌های ورودی به اسکریپت

زمانی که اسکریپت شل خود را فراخوانی می‌کنید، می‌توانید آرگومان‌هایی را به آن ارسال کنید. این آرگومان‌ها به‌صورت متغیرهایی با نام‌های $1, $2, $3 و غیره در دسترس خواهند بود.

مثال 1: استفاده از $1, $2, $3 برای دسترسی به آرگومان‌ها
#!/bin/bash

# چاپ آرگومان‌های ورودی
echo "Argument 1: $1"
echo "Argument 2: $2"
echo "Argument 3: $3"
  • اگر این اسکریپت را با دستور زیر اجرا کنید:
    ./script.sh hello world 123
    
  • خروجی به‌صورت زیر خواهد بود:
    Argument 1: hello
    Argument 2: world
    Argument 3: 123
    
  • در این مثال، $1 مقدار hello, $2 مقدار world و $3 مقدار 123 را به ترتیب ذخیره می‌کنند.

2. دستگاه $# برای تعداد آرگومان‌ها

دستگاه $# تعداد کل آرگومان‌هایی که به اسکریپت ارسال شده‌اند را نشان می‌دهد. این مقدار برای بررسی تعداد آرگومان‌ها و انجام پردازش‌های خاص بر اساس تعداد ورودی‌ها مفید است.

مثال 2: استفاده از $# برای شمارش تعداد آرگومان‌ها
#!/bin/bash

# شمارش تعداد آرگومان‌ها
echo "Number of arguments: $#"
  • اگر این اسکریپت را با دستور زیر اجرا کنید:
    ./script.sh apple banana cherry
    
  • خروجی به‌صورت زیر خواهد بود:
    Number of arguments: 3
    

3. دستگاه $@ و $* برای دسترسی به تمام آرگومان‌ها

  • $@ و $* هر دو به شما این امکان را می‌دهند که به تمام آرگومان‌ها دسترسی داشته باشید. تفاوت اصلی آن‌ها در نحوه رفتار در زمانی است که آرگومان‌ها شامل فاصله (space) هستند.
    • $@: وقتی از نقل قول استفاده می‌شود، هر آرگومان به‌صورت جداگانه در دسترس قرار می‌گیرد.
    • $*: تمام آرگومان‌ها به‌صورت یک رشته واحد در دسترس قرار می‌گیرند.
مثال 3: استفاده از $@ و $*
#!/bin/bash

echo "Using \$@:"
for arg in "$@"; do
  echo "$arg"
done

echo "Using \$*:"
for arg in $*; do
  echo "$arg"
done
  • اگر این اسکریپت را با دستور زیر اجرا کنید:
    ./script.sh "first argument" "second argument" "third argument"
    
  • خروجی به‌صورت زیر خواهد بود:
    Using $@:
    first argument
    second argument
    third argument
    Using $*:
    first argument second argument third argument
    

4. دستگاه $0 برای نام اسکریپت

دستگاه $0 همیشه نام اسکریپت جاری را نمایش می‌دهد. این دستگاه می‌تواند برای گزارش‌گیری یا چاپ نام اسکریپت در هنگام اجرا استفاده شود.

مثال 4: استفاده از $0 برای چاپ نام اسکریپت
#!/bin/bash

# چاپ نام اسکریپت
echo "The name of the script is: $0"
  • اگر این اسکریپت را با دستور زیر اجرا کنید:
    ./script.sh
    
  • خروجی به‌صورت زیر خواهد بود:
    The name of the script is: ./script.sh
    

5. استفاده از آرگومان‌ها در توابع

در داخل توابع نیز می‌توانید از $1, $2, … برای دسترسی به آرگومان‌هایی که به تابع ارسال می‌شود، استفاده کنید.

مثال 5: استفاده از آرگومان‌ها در توابع
#!/bin/bash

# تابعی برای چاپ نام
greet_user() {
  echo "Hello, $1!"
}

# فراخوانی تابع با ارسال آرگومان
greet_user "Alice"
greet_user "Bob"
  • خروجی به‌صورت زیر خواهد بود:
    Hello, Alice!
    Hello, Bob!
    

جمع‌بندی

در این بخش، به روش‌های مختلف دسترسی به آرگومان‌های ورودی در اسکریپت‌های شل پرداخته شد. متغیرهایی مانند $1, $2, $3 برای دسترسی به آرگومان‌های مختلف ورودی استفاده می‌شوند. همچنین از دستگاه‌هایی چون $@, $* و $# می‌توان برای دسترسی به تمام آرگومان‌ها و شمارش آن‌ها بهره برد. دستگاه $0 نیز نام اسکریپت را نشان می‌دهد. این قابلیت‌ها به شما این امکان را می‌دهند که اسکریپت‌ها و توابع خود را با ورودی‌های پویا و انعطاف‌پذیر بنویسید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعداد آرگومان‌ها با استفاده از $#” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، دستگاه $# به شما این امکان را می‌دهد که تعداد آرگومان‌هایی را که به اسکریپت ارسال شده است، بدست آورید. این ابزار می‌تواند برای بررسی تعداد آرگومان‌ها و انجام اقداماتی بسته به تعداد ورودی‌ها، مورد استفاده قرار گیرد.


نحوه استفاده از $#

زمانی که یک اسکریپت را اجرا می‌کنید و آرگومان‌هایی به آن ارسال می‌شود، مقدار $# تعداد کل آرگومان‌هایی که ارسال شده است را نمایش می‌دهد. این می‌تواند در شرایط مختلف مفید باشد، به‌ویژه وقتی که نیاز دارید رفتار اسکریپت را بر اساس تعداد آرگومان‌ها تنظیم کنید.

مثال 1: شمارش تعداد آرگومان‌ها و چاپ آن
#!/bin/bash

# چاپ تعداد آرگومان‌های ورودی
echo "Number of arguments passed: $#"

اگر این اسکریپت را با دستور زیر اجرا کنید:

./script.sh apple banana cherry
  • خروجی به‌صورت زیر خواهد بود:
    Number of arguments passed: 3
    

در این مثال، چون سه آرگومان به اسکریپت ارسال شده است، مقدار $# برابر با 3 است.


استفاده از $# برای تصمیم‌گیری

شما می‌توانید از $# برای انجام عملیات شرطی مختلف بر اساس تعداد آرگومان‌های ورودی استفاده کنید. این امکان به شما می‌دهد که اسکریپت خود را از نظر انعطاف‌پذیری و تطبیق‌پذیری با ورودی‌های مختلف بهینه کنید.

مثال 2: استفاده از $# برای بررسی تعداد آرگومان‌ها
#!/bin/bash

if [ $# -lt 2 ]; then
  echo "Error: You must provide at least two arguments."
  exit 1
fi

echo "You provided $# arguments."

اگر این اسکریپت را با دستور زیر اجرا کنید:

./script.sh apple
  • خروجی به‌صورت زیر خواهد بود:
    Error: You must provide at least two arguments.
    

اگر اسکریپت را با آرگومان‌های بیشتر از دو اجرا کنید:

./script.sh apple banana cherry
  • خروجی به‌صورت زیر خواهد بود:
    You provided 3 arguments.
    

در این مثال، شرط [ $# -lt 2 ] بررسی می‌کند که تعداد آرگومان‌ها کمتر از 2 نباشد. اگر این شرط برقرار باشد، پیغام خطا چاپ شده و اسکریپت با کد خروجی 1 خاتمه می‌یابد.


جمع‌بندی

دستگاه $# یکی از ابزارهای بسیار مفید در اسکریپت‌نویسی شل است که برای شمارش تعداد آرگومان‌هایی که به اسکریپت ارسال شده است، استفاده می‌شود. با استفاده از این دستگاه، شما می‌توانید اسکریپت خود را طوری تنظیم کنید که بر اساس تعداد آرگومان‌های ورودی واکنش‌های مختلفی نشان دهد. این ابزار به شما کمک می‌کند که ورودی‌های غیرمنتظره را شناسایی کرده و فرآیند اجرا را کنترل کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”لیست کامل آرگومان‌ها با استفاده از $@ و $*” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، زمانی که شما آرگومان‌هایی به اسکریپت می‌دهید، می‌توانید از $@ و $* برای دسترسی به تمامی آرگومان‌ها استفاده کنید. این دو دستگاه مشابه هستند، اما تفاوت‌های جزئی در نحوه استفاده و کاربرد دارند. در این بخش، با استفاده از این دو دستگاه و تفاوت‌هایشان بیشتر آشنا خواهیم شد.


تفاوت‌های کلیدی بین $@ و $*

  • $@: این دستگاه تمامی آرگومان‌های ورودی را به‌صورت یک لیست از جمله‌ها بازمی‌گرداند. به این معنا که اگر آرگومان‌ها شامل فاصله‌ها یا اسپیس‌ها باشند، هر آرگومان به‌طور جداگانه دیده خواهد شد.
  • $*: این دستگاه تمامی آرگومان‌ها را به‌صورت یک رشته واحد جدا شده توسط فاصله‌ها (space) نمایش می‌دهد. در واقع، در اینجا تمامی آرگومان‌ها در یک متغیر واحد به هم متصل می‌شوند.

نحوه استفاده از $@ و $*

استفاده از $@ برای لیست کردن تمامی آرگومان‌ها

وقتی شما از $@ استفاده می‌کنید، شل تمام آرگومان‌ها را به‌صورت یک آرایه از رشته‌ها نگه می‌دارد. این به شما این امکان را می‌دهد که به راحتی هر آرگومان را به‌صورت جداگانه در حلقه‌ها یا سایر ساختارهای کنترلی پردازش کنید.

مثال 1: استفاده از $@
#!/bin/bash

# استفاده از $@
echo "All arguments using \$@: $@"

اگر اسکریپت را به‌صورت زیر اجرا کنید:

./script.sh apple banana "fruit salad" orange
  • خروجی به‌صورت زیر خواهد بود:
    All arguments using $@: apple banana fruit salad orange
    

همانطور که مشاهده می‌کنید، هر آرگومان به‌صورت جداگانه در نظر گرفته می‌شود، حتی اگر آرگومان شامل فاصله باشد.


استفاده از $* برای نمایش تمامی آرگومان‌ها

دستگاه $* تمامی آرگومان‌ها را به‌صورت یک رشته واحد با فاصله‌های بین آرگومان‌ها نمایش می‌دهد.

مثال 2: استفاده از $*
#!/bin/bash

# استفاده از $*
echo "All arguments using \$*: $*"

اگر اسکریپت را به‌صورت زیر اجرا کنید:

./script.sh apple banana "fruit salad" orange
  • خروجی به‌صورت زیر خواهد بود:
    All arguments using $*: apple banana fruit salad orange
    

اگرچه در اینجا هم آرگومان‌ها به‌صورت یک رشته با فاصله‌های معمولی چاپ می‌شوند، اما اگر آرگومان‌ها شامل فضای اضافی بودند، تفاوت اصلی بین $@ و $* به‌خوبی مشهود می‌شود.


استفاده از $@ و $* در حلقه‌ها

با استفاده از $@ یا $* می‌توانید در اسکریپت‌های شل، حلقه‌هایی برای پردازش تک‌تک آرگومان‌ها ایجاد کنید. در اینجا مثالی از نحوه استفاده از این دستگاه‌ها در یک حلقه آورده شده است.

مثال 3: استفاده از $@ در حلقه برای چاپ آرگومان‌ها
#!/bin/bash

# حلقه‌ای برای چاپ تمامی آرگومان‌ها با استفاده از $@
for arg in "$@"
do
  echo "Argument: $arg"
done

اگر اسکریپت را به‌صورت زیر اجرا کنید:

./script.sh apple banana "fruit salad" orange
  • خروجی به‌صورت زیر خواهد بود:
    Argument: apple
    Argument: banana
    Argument: fruit salad
    Argument: orange
    

در اینجا با استفاده از "$@" آرگومان‌ها به‌صورت جداگانه پردازش می‌شوند، حتی آرگومان‌هایی که فضای اضافی دارند.

مثال 4: استفاده از $* در حلقه برای چاپ آرگومان‌ها
#!/bin/bash

# حلقه‌ای برای چاپ تمامی آرگومان‌ها با استفاده از $*
for arg in $*
do
  echo "Argument: $arg"
done

اگر اسکریپت را به‌صورت زیر اجرا کنید:

./script.sh apple banana "fruit salad" orange
  • خروجی به‌صورت زیر خواهد بود:
    Argument: apple
    Argument: banana
    Argument: fruit
    Argument: salad
    Argument: orange
    

در این مثال، به دلیل استفاده از $* که تمامی آرگومان‌ها را به یک رشته تبدیل می‌کند، آرگومان "fruit salad" به دو قسمت تقسیم شده است.


جمع‌بندی

  • $@: هر آرگومان را به‌صورت جداگانه در نظر می‌گیرد، حتی اگر شامل فاصله باشد.
  • $*: تمامی آرگومان‌ها را به‌صورت یک رشته واحد با فاصله‌ها نمایش می‌دهد.

در اسکریپت‌های شل، انتخاب بین $@ و $* بستگی به نیاز شما دارد. اگر نیاز دارید که آرگومان‌ها به‌صورت مستقل و جداگانه پردازش شوند، از $@ استفاده کنید. اما اگر می‌خواهید تمامی آرگومان‌ها را به‌صورت یک رشته واحد نمایش دهید، از $* بهره ببرید.

هر دوی این دستگاه‌ها در اسکریپت‌های شل برای پردازش آرگومان‌ها مفید هستند و کاربردهای مختلفی دارند که در هنگام نوشتن اسکریپت‌ها می‌توانند به شما کمک کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تفاوت بین $@ و $*” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، زمانی که شما آرگومان‌هایی به اسکریپت می‌دهید، می‌توانید از دو دستگاه خاص یعنی $@ و $* برای دسترسی به تمامی آرگومان‌ها استفاده کنید. در ابتدا ممکن است به نظر برسد که این دو دستگاه یکسان هستند، اما در واقع تفاوت‌های اساسی در نحوه پردازش آرگومان‌ها توسط آن‌ها وجود دارد. در ادامه تفاوت‌های دقیق بین $@ و $* را بررسی می‌کنیم.


$@ چیست؟

  • $@ تمام آرگومان‌های ورودی را به‌صورت یک آرایه از رشته‌ها ذخیره می‌کند. به عبارت دیگر، $@ آرگومان‌ها را به‌صورت جداگانه می‌شناسد و آن‌ها را به‌صورت جداگانه در نظر می‌گیرد.
  • اگر آرگومان‌ها شامل فاصله باشند، $@ آن‌ها را به‌عنوان یک آرگومان مجزا و با در نظر گرفتن فاصله‌ها می‌بیند.
  • در نتیجه، زمانی که از $@ استفاده می‌کنید، به‌ویژه هنگام استفاده از آن در حلقه‌ها یا پردازش‌ها، آرگومان‌ها به‌طور مستقل از یکدیگر پردازش می‌شوند.
مثال استفاده از $@:
#!/bin/bash

# چاپ آرگومان‌ها با استفاده از $@
for arg in "$@"
do
  echo "Argument: $arg"
done

اگر اسکریپت را به‌صورت زیر اجرا کنید:

./script.sh apple "fruit salad" banana
  • خروجی به‌صورت زیر خواهد بود:
    Argument: apple
    Argument: fruit salad
    Argument: banana
    

در اینجا، حتی اگر آرگومان “fruit salad” دارای فاصله باشد، $@ آن را به‌عنوان یک آرگومان جداگانه در نظر می‌گیرد.


$* چیست؟

  • $* تمامی آرگومان‌ها را به‌صورت یک رشته واحد با فاصله‌های بین آن‌ها بازمی‌گرداند.
  • هنگامی که از $* استفاده می‌کنید، تمامی آرگومان‌ها به‌طور یکپارچه در یک رشته نمایش داده می‌شوند، حتی اگر شامل فاصله‌ها باشند.
  • اگر از $* در حلقه‌ها استفاده کنید، آرگومان‌ها به‌طور مستقیم جدا نمی‌شوند و همه‌ی آن‌ها به‌صورت یک جمله واحد به هم متصل می‌شوند.
مثال استفاده از $*:
#!/bin/bash

# چاپ آرگومان‌ها با استفاده از $*
for arg in $*
do
  echo "Argument: $arg"
done

اگر اسکریپت را به‌صورت زیر اجرا کنید:

./script.sh apple "fruit salad" banana
  • خروجی به‌صورت زیر خواهد بود:
    Argument: apple
    Argument: fruit
    Argument: salad
    Argument: banana
    

در اینجا، همان‌طور که مشاهده می‌کنید، آرگومان “fruit salad” به دو بخش تقسیم می‌شود و به‌صورت “fruit” و “salad” چاپ می‌شود، چراکه $* تمام آرگومان‌ها را به یک رشته واحد تبدیل می‌کند و فاصله‌ها را به‌عنوان جداکننده در نظر می‌گیرد.


جمع‌بندی تفاوت‌ها

  1. $@:
    • آرگومان‌ها را به‌صورت یک آرایه از رشته‌ها در نظر می‌گیرد.
    • از آن برای پردازش آرگومان‌ها به‌طور جداگانه در حلقه‌ها و پردازش‌های پیچیده‌تر استفاده می‌شود.
    • اگر آرگومان‌ها شامل فاصله‌ها باشند، به‌عنوان یک آرگومان مستقل در نظر گرفته می‌شود.
  2. $*:
    • تمامی آرگومان‌ها را به‌صورت یک رشته واحد با فاصله‌های بین آن‌ها نمایش می‌دهد.
    • مناسب برای نمایش آرگومان‌ها به‌صورت یک رشته است، اما ممکن است برای پردازش‌های پیچیده‌تر مناسب نباشد.
    • اگر آرگومان‌ها شامل فاصله باشند، به‌طور خودکار به چند بخش تقسیم می‌شوند.

نکته مهم

اگر از $@ یا $* در یک حلقه استفاده می‌کنید، حتماً توجه داشته باشید که اگر آرگومان‌ها شامل فاصله‌ها باشند، از "$@" به‌جای $@ یا "$*" به‌جای $* استفاده کنید تا آرگومان‌ها به‌صورت صحیح و جداگانه پردازش شوند. این کار با قرار دادن نقل‌قول‌ها (") اطراف این متغیرها از جدا شدن نادرست آرگومان‌ها جلوگیری می‌کند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. مقدار بازگشتی توابع”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از return برای بازگرداندن مقادیر عددی” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، برای بازگشت به مقدار از توابع، می‌توان از دستور return استفاده کرد. این دستور معمولاً برای بازگشت مقادیر عددی به تابع فراخوانی استفاده می‌شود.

مقدار بازگشتی که توسط دستور return ارائه می‌شود، معمولاً برای نشان دادن وضعیت اجرای یک تابع یا دستورات مختلف استفاده می‌شود. این مقدار، به‌ویژه در اسکریپت‌های شل، به‌طور پیش‌فرض در بازه 0 تا 255 قرار دارد، چراکه مقدارهای بالاتر از 255 در سیستم‌های یونیکس معتبر نیستند.


ساختار دستور return

دستور return به‌طور کلی در توابع شل استفاده می‌شود تا یک مقدار عددی (معمولاً یک کد وضعیت یا کد خطا) را بازگشت دهد. این مقدار معمولاً از نوع عدد صحیح است و در اسکریپت‌های شل برای نشان دادن موفقیت یا شکست یک عملیات به‌کار می‌رود.

ساختار آن به این صورت است:

return <عدد>
  • عددی که با return بازگردانده می‌شود، معمولاً نمایانگر وضعیت است:
    • 0: نشان‌دهنده موفقیت است.
    • مقادیر غیر صفر: نشان‌دهنده خطا یا وضعیت ناموفق است.

مثال کاربردی از استفاده از return

در این مثال، یک تابع ایجاد می‌کنیم که بررسی می‌کند آیا یک عدد مثبت است یا خیر. اگر عدد منفی باشد، تابع با استفاده از دستور return یک مقدار غیر صفر (در اینجا 1) بازمی‌گرداند تا نشان دهد که ورودی نامعتبر است.

#!/bin/bash

# تعریف تابع برای بررسی مثبت بودن عدد
check_positive() {
    if [ $1 -lt 0 ]; then
        echo "Error: Negative number."
        return 1  # بازگرداندن کد خطا
    else
        echo "The number is positive."
        return 0  # موفقیت
    fi
}

# فراخوانی تابع با آرگومان
check_positive $1

# استفاده از مقدار بازگشتی برای بررسی موفقیت یا شکست
if [ $? -eq 0 ]; then
    echo "Function executed successfully."
else
    echo "Function encountered an error."
fi

در این اسکریپت:

  1. تابع check_positive یک عدد ورودی را بررسی می‌کند.
  2. اگر عدد منفی باشد، دستور return 1 برای نشان دادن خطا استفاده می‌شود.
  3. اگر عدد مثبت باشد، دستور return 0 برای نشان دادن موفقیت استفاده می‌شود.
  4. در انتهای اسکریپت، مقدار بازگشتی تابع (با استفاده از $?) برای بررسی نتیجه فراخوانی تابع استفاده می‌شود.
ورودی و خروجی اسکریپت:

اگر اسکریپت را با ورودی 5 اجرا کنید:

./script.sh 5

خروجی به‌صورت زیر خواهد بود:

The number is positive.
Function executed successfully.

اگر اسکریپت را با ورودی -5 اجرا کنید:

./script.sh -5

خروجی به‌صورت زیر خواهد بود:

Error: Negative number.
Function encountered an error.

نکات مهم

  • مقدار بازگشتی توسط دستور return باید عددی بین 0 و 255 باشد. مقادیر بزرگتر از 255 نمی‌توانند به‌طور صحیح توسط اسکریپت شل پردازش شوند.
  • دستور return تنها می‌تواند در توابع شل استفاده شود. اگر بخواهید یک مقدار از یک اسکریپت اصلی (نه تابع) برگردانید، باید از متغیرهای محیطی یا فایل‌ها استفاده کنید.
  • برای بررسی وضعیت دستور آخر (مثلاً بررسی موفقیت یا شکست یک دستور)، می‌توان از متغیر $? استفاده کرد. این متغیر مقدار بازگشتی آخرین دستور اجرا شده را در خود ذخیره می‌کند.

جمع‌بندی

استفاده از دستور return برای بازگشت مقادیر عددی یکی از روش‌های ساده و مفید برای مدیریت وضعیت توابع در اسکریپت‌های شل است. این دستور می‌تواند برای نمایش موفقیت یا خطا و همچنین به‌کارگیری وضعیت‌های مختلف در فرآیندهای خودکارسازی مفید باشد. همچنین، مقادیر بازگشتی عددی از توابع به اسکریپت این امکان را می‌دهد که بتواند به‌صورت هوشمند عمل کند و بر اساس وضعیت‌ها تصمیم‌گیری کند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بازگشت مقادیر متنی با استفاده از echo” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، زمانی که بخواهیم مقداری متنی را از یک تابع یا بخشی از اسکریپت به قسمت‌های دیگر انتقال دهیم یا به‌عنوان خروجی نمایش دهیم، معمولاً از دستور echo استفاده می‌کنیم. این دستور متن یا مقدار مشخصی را چاپ می‌کند و می‌تواند به‌طور گسترده‌ای در اسکریپت‌های شل برای بازگشت مقادیر متنی به کار رود.

در حالی که دستور return برای بازگشت مقادیر عددی و وضعیت‌ها به کار می‌رود، از دستور echo برای بازگشت اطلاعات متنی به‌ویژه زمانی که نیاز به چاپ پیغام‌های واضح و دقیق به کاربر داریم، استفاده می‌شود.


ساختار دستور echo

دستور echo به‌طور کلی به این صورت استفاده می‌شود:

echo "متن یا مقدار متنی"

این دستور مقدار متنی را که درون کوتیشن‌ها قرار داده شده است، به خروجی چاپ می‌کند.


استفاده از echo برای بازگشت مقادیر متنی از توابع

فرض کنید در یک تابع می‌خواهیم یک پیام خاص را بر اساس شرایط خاص به‌طور متنی برگردانیم. در این صورت، می‌توانیم از echo برای چاپ پیام‌ها استفاده کنیم.

مثال:

در این مثال، یک تابع ایجاد می‌کنیم که بررسی می‌کند آیا یک کاربر معتبر است یا نه و بر اساس نتیجه پیامی به کاربر برمی‌گرداند.

#!/bin/bash

# تابع بررسی اعتبار کاربر
check_user() {
    if [ "$1" == "admin" ]; then
        echo "Welcome, admin!"  # چاپ پیغام برای کاربر معتبر
    else
        echo "Access denied. Invalid user."  # چاپ پیغام برای کاربر غیرمعتبر
    fi
}

# فراخوانی تابع با پارامتر ورودی
result=$(check_user "$1")

# چاپ نتیجه به‌طور کلی
echo "Result of user check: $result"

توضیح مثال:

  1. تابع check_user دو حالت مختلف دارد:
    • اگر نام کاربری وارد شده admin باشد، پیام خوش‌آمدگویی به چاپ می‌رسد.
    • در غیر این صورت، پیام “Access denied” چاپ می‌شود.
  2. دستور echo در داخل تابع برای بازگشت پیغام‌ها به کار می‌رود.
  3. پس از فراخوانی تابع، از متغیر result برای ذخیره و چاپ نتیجه استفاده می‌شود.

ورودی و خروجی اسکریپت:

  • ورودی:
    ./script.sh admin
    
  • خروجی:
    Welcome, admin!
    Result of user check: Welcome, admin!
    
  • ورودی (در صورت نامعتبر بودن نام کاربری):
    ./script.sh user
    
  • خروجی:
    Access denied. Invalid user.
    Result of user check: Access denied. Invalid user.
    

مزایای استفاده از echo برای بازگشت مقادیر متنی

  • خوانایی بهتر: echo به‌خوبی برای چاپ پیغام‌ها و مقادیر متنی مناسب است و خوانایی اسکریپت را افزایش می‌دهد.
  • انتقال داده‌ها بین توابع: می‌توان از echo برای بازگشت مقادیر متنی از توابع استفاده کرد و این مقادیر را در قسمت‌های مختلف اسکریپت مورد استفاده قرار داد.
  • ساده و موثر: استفاده از echo برای برگرداندن متغیرهای متنی ساده و در عین حال کارآمد است و نیاز به ساختار پیچیده‌ای ندارد.

نکات مهم هنگام استفاده از echo:

  • توجه به فرمت خروجی: می‌توانید از گزینه‌های مختلف echo برای کنترل فرمت خروجی (مانند افزودن خط جدید یا حذف آن) استفاده کنید:
    • echo -n "متن": برای چاپ متن بدون افزودن خط جدید.
    • echo -e "متن\nاضافه‌کردن خط جدید": برای فعال‌سازی قابلیت‌های خاص مانند استفاده از دستور \n برای خط جدید.
  • انتقال به فایل‌ها: می‌توانید از echo برای انتقال مقادیر متنی به فایل‌ها نیز استفاده کنید:
    echo "This is a test message." > output.txt
    

    این دستور متن را به فایل output.txt انتقال می‌دهد.

  • مدیریت خروجی استاندارد: با استفاده از echo می‌توانید مقادیر را در خروجی استاندارد (مانند کنسول) چاپ کرده و یا آن‌ها را به‌صورت فایل ذخیره کنید.

جمع‌بندی

استفاده از دستور echo در شل اسکریپت‌ها برای بازگشت مقادیر متنی روشی ساده، مؤثر و پرکاربرد است. این دستور می‌تواند به‌طور وسیعی برای چاپ پیام‌ها، ارسال اطلاعات به کاربر، و یا انتقال داده‌ها میان توابع به‌کار رود. اگرچه دستور return برای بازگشت مقادیر عددی در توابع مناسب است، اما برای برگرداندن مقادیر متنی، دستور echo ابزاری بسیار مفید است که انعطاف‌پذیری زیادی را در اسکریپت‌نویسی فراهم می‌آورد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی مقدار بازگشتی توابع با $?” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، هر دستوری که اجرا می‌شود، یک کد وضعیت (exit status) به‌عنوان خروجی باز می‌گرداند. این کد نشان‌دهنده‌ی موفقیت یا شکست آن دستور است. دستور exit برای خاتمه دادن به اسکریپت یا تابع و بازگشت کد وضعیت استفاده می‌شود. پس از اجرای هر دستور، مقدار کد وضعیت آن دستور به متغیر خاص $? تخصیص داده می‌شود.

این متغیر خاص $? برای بررسی مقدار بازگشتی دستورات یا توابع بسیار مفید است و به‌طور معمول برای بررسی موفقیت یا شکست یک دستور مورد استفاده قرار می‌گیرد.


ساختار متغیر $?

متغیر $? پس از اجرای هر دستور در شل به مقدار خروجی دستور قبل از خود اشاره می‌کند. اگر دستور با موفقیت اجرا شود، مقدار بازگشتی معمولاً 0 است و اگر دستور با خطا مواجه شود، مقدار بازگشتی عددی غیر از 0 خواهد بود.

دستور
echo $?

در این ساختار، دستور اول اجرا شده و سپس مقدار کد وضعیت آن دستور با استفاده از $? چاپ می‌شود.


استفاده از $? برای بررسی مقدار بازگشتی توابع

در هنگام نوشتن توابع در شل، شما می‌توانید با استفاده از کد وضعیت خروجی (که در $? ذخیره می‌شود) بررسی کنید که آیا تابع با موفقیت اجرا شده است یا خطا رخ داده است. برای مثال، در تابعی که می‌خواهید بررسی کنید که یک فایل موجود است یا نه، می‌توانید از $? برای ارزیابی نتیجه استفاده کنید.

مثال:

#!/bin/bash

# تابع برای بررسی وجود فایل
check_file_exists() {
    if [ -f "$1" ]; then
        echo "File exists."
        return 0   # موفقیت
    else
        echo "File does not exist."
        return 1   # خطا
    fi
}

# فراخوانی تابع
check_file_exists "testfile.txt"

# بررسی نتیجه تابع با استفاده از $?
if [ $? -eq 0 ]; then
    echo "The function ran successfully."
else
    echo "The function failed."
fi

توضیح مثال:

  1. تابع check_file_exists بررسی می‌کند که آیا فایل با نام ورودی (مانند testfile.txt) در سیستم موجود است یا خیر.
  2. اگر فایل وجود داشته باشد، پیامی مبنی بر موجود بودن فایل چاپ می‌کند و سپس return 0 را برای نشان‌دادن موفقیت اجرا می‌کند.
  3. اگر فایل موجود نباشد، پیامی مبنی بر عدم وجود فایل چاپ می‌کند و return 1 را برای نشان‌دادن خطا بازمی‌گرداند.
  4. پس از فراخوانی تابع، مقدار بازگشتی تابع با استفاده از $? بررسی می‌شود.
  5. اگر مقدار $? برابر با 0 باشد، نشان‌دهنده موفقیت تابع است و پیامی مبنی بر موفقیت چاپ می‌شود. در غیر این صورت، نشان‌دهنده‌ی شکست تابع است و پیامی مبنی بر خطا چاپ می‌شود.

مقدار بازگشتی دستورات در شل:

مقدار بازگشتی معمولاً به‌صورت زیر است:

  • 0: نشان‌دهنده موفقیت دستور (بدون خطا).
  • غیر از 0: نشان‌دهنده خطا یا شکست دستور.

این کدها از سوی سیستم‌عامل برای هر دستور یا برنامه‌ای که اجرا می‌شود باز می‌گردند. به‌طور کلی، هر کد وضعیت غیر از 0 به معنای وقوع خطا است.


مثال‌های رایج برای استفاده از $?:

  1. بررسی وضعیت اجرای دستور ls:فرض کنید می‌خواهید ببینید آیا دستور ls (لیست کردن محتویات دایرکتوری) با موفقیت اجرا شده است یا نه:
    ls /some/directory
    if [ $? -eq 0 ]; then
        echo "Directory listing was successful."
    else
        echo "Failed to list directory."
    fi
    
  2. بررسی وضعیت اجرای دستور grep:فرض کنید می‌خواهید بررسی کنید که آیا عبارت خاصی در یک فایل پیدا شده است یا نه:
    grep "pattern" myfile.txt
    if [ $? -eq 0 ]; then
        echo "Pattern found."
    else
        echo "Pattern not found."
    fi
    
  3. بررسی وضعیت دستور cp:فرض کنید می‌خواهید بررسی کنید که آیا کپی فایل با موفقیت انجام شده است یا خیر:
    cp source.txt destination.txt
    if [ $? -eq 0 ]; then
        echo "File copied successfully."
    else
        echo "Failed to copy the file."
    fi
    

نکات مهم در استفاده از $?:

  • $? همیشه به مقدار کد وضعیت آخرین دستور اجرا شده اشاره می‌کند. بنابراین، باید حواستان باشد که هر دستور قبل از استفاده از $? اجرا شده باشد.
  • برای استفاده‌ی بهینه از $?، باید دستوراتی که احتمال خطا دارند (مانند cp, mv, grep, و غیره) را با استفاده از آن بررسی کنید.
  • از دستور $? به‌ویژه در مواردی که تابع یا دستور شما نیاز به بررسی وضعیت عملکرد دارد (مانند ورود به سیستم، کپی کردن فایل‌ها، و غیره)، استفاده کنید تا از اجرای موفقیت‌آمیز یا شکست عملیات اطمینان حاصل کنید.

جمع‌بندی

مقدار بازگشتی توابع و دستورات در شل با استفاده از متغیر $? قابل بررسی است. این متغیر برای شناسایی موفقیت یا شکست یک دستور به کار می‌رود و معمولاً برای کنترل جریان در اسکریپت‌ها و بررسی وضعیت دستورات بسیار مفید است. برای مثال، پس از اجرای یک دستور یا تابع، می‌توان با استفاده از $? بررسی کرد که آیا عملیات موفقیت‌آمیز بوده یا خیر. این ویژگی در اسکریپت‌های شل کمک می‌کند تا از وقوع خطاها جلوگیری و روند اجرایی اسکریپت به درستی کنترل شود.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. محدوده متغیرها در توابع”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”متغیرهای محلی (Local) و متغیرهای سراسری (Global)” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، متغیرها به دو دسته اصلی تقسیم می‌شوند: متغیرهای محلی و متغیرهای سراسری. این دسته‌بندی به نحوه تعریف و دسترسی به متغیرها و محدوده تاثیر آن‌ها بستگی دارد. در این بخش، به بررسی این دو نوع متغیر و تفاوت‌های آن‌ها خواهیم پرداخت.


1. متغیرهای سراسری (Global Variables)

متغیرهای سراسری یا جهانی، متغیرهایی هستند که در تمام بخش‌های اسکریپت قابل دسترسی و تغییر هستند. این متغیرها معمولاً خارج از توابع تعریف می‌شوند و مقدار آن‌ها می‌تواند در هر نقطه‌ای از اسکریپت تغییر کند.

ویژگی‌ها و رفتار متغیرهای سراسری:

  • این متغیرها به‌طور پیش‌فرض در تمامی توابع، دستورات و قسمت‌های دیگر اسکریپت قابل دسترسی هستند.
  • برای دسترسی به یک متغیر سراسری در هر نقطه از اسکریپت کافی است نام آن را فراخوانی کنید.
  • این متغیرها در صورت تغییر در یک تابع، تغییرات خود را در کل اسکریپت اعمال می‌کنند.

مثال:

#!/bin/bash

# تعریف یک متغیر سراسری
global_var="This is a global variable"

# تابعی که به متغیر سراسری دسترسی دارد
print_global_var() {
    echo "Global Variable: $global_var"
}

# چاپ مقدار متغیر سراسری
print_global_var

توضیح مثال:

  • در این مثال، متغیر global_var به‌عنوان یک متغیر سراسری در اسکریپت تعریف شده است.
  • تابع print_global_var می‌تواند به این متغیر دسترسی پیدا کرده و مقدار آن را چاپ کند.
  • حتی اگر از تابع خارج شویم، همچنان می‌توانیم به این متغیر دسترسی داشته باشیم.

2. متغیرهای محلی (Local Variables)

متغیرهای محلی فقط در داخل توابع خاص خود قابل دسترسی هستند و پس از پایان اجرای تابع از بین می‌روند. این نوع متغیرها معمولاً برای جلوگیری از تداخل با متغیرهای سراسری و مدیریت متغیرها در داخل توابع استفاده می‌شوند.

ویژگی‌ها و رفتار متغیرهای محلی:

  • متغیرهای محلی فقط در همان تابعی که در آن تعریف می‌شوند قابل دسترسی هستند.
  • پس از پایان اجرای تابع، این متغیرها از بین می‌روند.
  • این متغیرها به هیچ عنوان با متغیرهای سراسری تداخل ندارند، زیرا دامنه عملکرد آن‌ها محدود به همان تابع است.
  • برای تعریف یک متغیر به‌عنوان محلی در داخل تابع، باید از کلمه کلیدی local استفاده کنید.

مثال:

#!/bin/bash

# تعریف یک متغیر سراسری
global_var="I am a global variable"

# تابعی که از متغیر محلی استفاده می‌کند
my_function() {
    local local_var="I am a local variable"
    echo "Inside the function: $local_var"
    echo "Inside the function: $global_var"
}

# فراخوانی تابع
my_function

# تلاش برای دسترسی به متغیر محلی خارج از تابع
echo "Outside the function: $local_var"  # خطا می‌دهد زیرا local_var فقط داخل تابع است

توضیح مثال:

  • در این مثال، متغیر local_var داخل تابع my_function تعریف شده است.
  • متغیر محلی فقط داخل تابع my_function قابل دسترسی است.
  • پس از فراخوانی تابع، متغیر محلی دیگر قابل دسترسی نیست و اگر بخواهیم به آن از خارج تابع دسترسی پیدا کنیم، خطا دریافت خواهیم کرد.

تفاوت‌های اصلی بین متغیرهای محلی و سراسری:

ویژگی متغیر سراسری متغیر محلی
محدوده دسترسی در تمام اسکریپت قابل دسترسی فقط در داخل همان تابع قابل دسترسی
حذف و از بین رفتن باقی می‌ماند تا پایان اسکریپت پس از پایان تابع از بین می‌رود
تداخل با توابع دیگر در تمام اسکریپت قابل تغییر است فقط در داخل تابع قابل تغییر است
استفاده از local نیازی به استفاده از local ندارد باید با local تعریف شود

3. مزایای استفاده از متغیرهای محلی:

  • مدیریت بهتر حافظه: استفاده از متغیرهای محلی باعث می‌شود که حافظه به‌طور کارآمدتری استفاده شود، زیرا این متغیرها فقط در زمان اجرای تابع وجود دارند.
  • جلوگیری از تداخل: از آنجایی که متغیرهای محلی فقط در داخل همان تابع قابل دسترسی هستند، از تداخل آن‌ها با متغیرهای سراسری جلوگیری می‌شود.
  • خوانایی بیشتر: استفاده از متغیرهای محلی باعث می‌شود که اسکریپت‌ها واضح‌تر و خواناتر شوند، زیرا دامنه عملکرد متغیر محدود و مشخص است.

4. مزایای استفاده از متغیرهای سراسری:

  • دسترس‌پذیری گسترده‌تر: از آنجایی که متغیرهای سراسری در تمامی بخش‌های اسکریپت قابل دسترسی هستند، می‌توانند برای ذخیره و اشتراک‌گذاری مقادیر در بین توابع مختلف استفاده شوند.
  • سادگی در استفاده: متغیرهای سراسری بدون نیاز به تعریف دوباره در توابع مختلف قابل دسترسی و تغییر هستند.

جمع‌بندی

در اسکریپت‌های شل، استفاده از متغیرهای محلی و سراسری به‌طور صحیح می‌تواند به بهینه‌سازی عملکرد و افزایش خوانایی کد کمک کند. متغیرهای سراسری برای داده‌هایی که باید در تمامی بخش‌های اسکریپت قابل دسترسی باشند، مناسب هستند، در حالی که متغیرهای محلی برای داده‌هایی که فقط در داخل توابع نیاز به استفاده دارند، به کار می‌روند. استفاده از کلمه‌کلیدی local برای تعریف متغیرهای محلی و جلوگیری از تداخل و بهینه‌سازی منابع پیشنهاد می‌شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه تعریف متغیرهای محلی در توابع” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، متغیرها می‌توانند به‌صورت سراسری یا محلی تعریف شوند. متغیرهای محلی به‌طور خاص در داخل توابع تعریف می‌شوند و تنها در محدوده آن تابع قابل دسترسی هستند. این ویژگی به جلوگیری از تداخل میان متغیرهای مختلف و بهینه‌سازی کد کمک می‌کند.

برای تعریف یک متغیر محلی در یک تابع، باید از کلمه‌کلیدی local استفاده کنید. این کلمه‌کلیدی باعث می‌شود که متغیر فقط در همان تابع موجود باشد و پس از پایان اجرای تابع از بین برود. این ویژگی باعث می‌شود که متغیرهای محلی هیچ تأثیری روی متغیرهای سراسری یا دیگر توابع نداشته باشند.


تعریف متغیر محلی با استفاده از local

برای ایجاد یک متغیر محلی، ابتدا باید داخل تابع متغیر را با استفاده از کلمه‌کلیدی local تعریف کنید. این کلمه‌کلیدی به شل می‌گوید که متغیر فقط در همان تابع معتبر است و خارج از آن قابل دسترسی نیست.

ساختار کلی:
local variable_name="value"
  • local کلمه‌کلیدی است که مشخص می‌کند متغیر محلی باشد.
  • variable_name نام متغیر است.
  • "value" مقدار متغیر است که به آن اختصاص داده می‌شود.

مثال 1: تعریف یک متغیر محلی ساده

#!/bin/bash

# تابعی که یک متغیر محلی تعریف می‌کند
my_function() {
    local my_var="Hello, World!"
    echo "Inside the function: $my_var"
}

# فراخوانی تابع
my_function

# تلاش برای دسترسی به متغیر محلی از خارج تابع
echo "Outside the function: $my_var"  # این خط مقدار my_var را نخواهد داشت
توضیح مثال:
  • در این مثال، داخل تابع my_function یک متغیر محلی به نام my_var تعریف شده است.
  • مقدار این متغیر درون تابع چاپ می‌شود، اما زمانی که از خارج تابع بخواهیم به این متغیر دسترسی پیدا کنیم، هیچ مقداری نشان داده نخواهد شد زیرا my_var فقط در داخل همان تابع معتبر است.
  • خط echo "Outside the function: $my_var" هیچ مقداری را چاپ نمی‌کند زیرا my_var محلی است و خارج از تابع قابل دسترسی نیست.

مثال 2: استفاده از متغیر محلی برای جلوگیری از تداخل

#!/bin/bash

# تعریف متغیر سراسری
global_var="I am a global variable"

# تابعی که متغیر محلی با نام مشابه تعریف می‌کند
my_function() {
    local global_var="I am a local variable"
    echo "Inside the function: $global_var"
}

# فراخوانی تابع
my_function

# دسترسی به متغیر سراسری
echo "Outside the function: $global_var"
توضیح مثال:
  • در این مثال، متغیر global_var هم به‌صورت سراسری و هم به‌صورت محلی در داخل تابع my_function تعریف شده است.
  • وقتی که تابع اجرا می‌شود، مقدار متغیر محلی global_var چاپ می‌شود.
  • اما پس از خروج از تابع، مقدار متغیر سراسری global_var بدون تغییر باقی می‌ماند.
  • این نشان می‌دهد که متغیر محلی با نام مشابه به متغیر سراسری تنها در داخل همان تابع اثرگذار است و در خارج از تابع هیچ تاثیری ندارد.

مزایای استفاده از متغیرهای محلی

  • جلوگیری از تداخل: زمانی که شما از متغیرهای محلی استفاده می‌کنید، این متغیرها تنها در محدوده تابع موجود هستند و از این رو هیچ تداخلی با متغیرهای سراسری یا دیگر توابع نخواهند داشت.
  • حافظه بهینه‌تر: متغیرهای محلی تنها در هنگام اجرای تابع وجود دارند و پس از پایان اجرای تابع از بین می‌روند، بنابراین حافظه بهینه‌تر استفاده می‌شود.
  • خوانایی کد: با استفاده از متغیرهای محلی، می‌توانید کد خود را خواناتر و سازمان‌دهی‌شده‌تر کنید، زیرا دامنه عملکرد هر متغیر محدود به جایی است که به آن نیاز دارید.

جمع‌بندی

در شل اسکریپت‌ها، برای جلوگیری از تداخل میان متغیرها و بهینه‌سازی کد، بهتر است از متغیرهای محلی استفاده کنید. با استفاده از کلمه‌کلیدی local می‌توانید متغیرهایی تعریف کنید که فقط در داخل همان تابع قابل دسترسی باشند و پس از پایان اجرای تابع از بین می‌روند. این ویژگی باعث می‌شود که کد شما بهتر سازمان‌دهی شده و از استفاده بیش از حد منابع جلوگیری شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”دسترسی به متغیرهای سراسری در توابع” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، متغیرها می‌توانند به‌صورت سراسری یا محلی تعریف شوند. در حالی که متغیرهای محلی تنها در داخل تابع موجود هستند، متغیرهای سراسری در سراسر اسکریپت قابل دسترسی‌اند. یکی از ویژگی‌های مهم شل این است که توابع به‌طور پیش‌فرض می‌توانند به متغیرهای سراسری دسترسی داشته باشند، اما نمی‌توانند مستقیماً به متغیرهای محلی تابع‌های دیگر دسترسی داشته باشند.

در این بخش، به بررسی نحوه دسترسی به متغیرهای سراسری داخل توابع و استفاده از آن‌ها می‌پردازیم.


دسترسی به متغیرهای سراسری در توابع

برای دسترسی به متغیرهای سراسری در توابع، نیازی به استفاده از کلمه‌کلیدی خاصی مانند local نیست. به‌طور پیش‌فرض، توابع می‌توانند به متغیرهایی که خارج از آن‌ها تعریف شده‌اند، دسترسی پیدا کنند.

ساختار کلی دسترسی:
#!/bin/bash

# متغیر سراسری
global_var="This is a global variable"

# تابعی که به متغیر سراسری دسترسی دارد
my_function() {
    echo "Inside the function: $global_var"
}

# فراخوانی تابع
my_function

# دسترسی به متغیر سراسری از خارج تابع
echo "Outside the function: $global_var"
توضیح مثال:
  • در این مثال، متغیر global_var به‌صورت سراسری در خارج از تابع تعریف شده است.
  • تابع my_function بدون نیاز به هیچ کلمه‌کلیدی خاصی می‌تواند به این متغیر سراسری دسترسی پیدا کند و آن را چاپ کند.
  • پس از فراخوانی تابع، می‌توانیم مقدار متغیر سراسری را از خارج تابع نیز مشاهده کنیم.
  • همانطور که مشاهده می‌کنید، شل به‌طور خودکار متغیرهای سراسری را در داخل توابع در دسترس قرار می‌دهد.

تغییر مقادیر متغیرهای سراسری در داخل توابع

در صورتی که بخواهید مقدار یک متغیر سراسری را از داخل یک تابع تغییر دهید، به‌طور مستقیم این امکان فراهم است. اما باید دقت کنید که اگر در داخل تابع متغیر جدیدی با همان نام متغیر سراسری تعریف کنید (بدون استفاده از local)، متغیر جدید تنها در داخل تابع معتبر خواهد بود و تغییرات آن اثرات بیرونی نخواهد داشت.

مثال تغییر مقدار متغیر سراسری در داخل تابع:
#!/bin/bash

# متغیر سراسری
global_var="Initial value"

# تابعی که مقدار متغیر سراسری را تغییر می‌دهد
my_function() {
    global_var="Modified value"  # تغییر مقدار متغیر سراسری
    echo "Inside the function: $global_var"
}

# فراخوانی تابع
my_function

# دسترسی به متغیر سراسری از خارج تابع
echo "Outside the function: $global_var"
توضیح مثال:
  • در این مثال، ابتدا مقدار متغیر سراسری global_var به "Initial value" تنظیم شده است.
  • سپس داخل تابع my_function، مقدار این متغیر تغییر داده شده است.
  • پس از فراخوانی تابع، مقدار تغییر یافته‌ی global_var در خارج از تابع نیز قابل مشاهده است.
  • این نشان می‌دهد که تغییرات در متغیر سراسری از داخل تابع نیز تأثیرگذار هستند.

دسترسی به متغیرهای سراسری در توابع با استفاده از export

در صورتی که بخواهید متغیر سراسری‌ای که در یک تابع تغییر داده‌اید، برای تمامی فرآیندهای زیرمجموعه اسکریپت نیز قابل دسترسی باشد (یعنی به محیط سیستم منتقل شود)، می‌توانید از دستور export استفاده کنید. این دستور باعث می‌شود که متغیر به‌عنوان یک متغیر محیطی برای تمامی زیرمجموعه‌ها و اسکریپت‌های دیگر قابل دسترسی باشد.

مثال استفاده از export:
#!/bin/bash

# متغیر سراسری
global_var="Initial value"

# تابعی که مقدار متغیر سراسری را تغییر داده و export می‌کند
my_function() {
    global_var="Modified value"  # تغییر مقدار متغیر سراسری
    export global_var  # صادر کردن به محیط سیستم
    echo "Inside the function: $global_var"
}

# فراخوانی تابع
my_function

# دسترسی به متغیر سراسری از خارج تابع
echo "Outside the function: $global_var"
توضیح مثال:
  • در این مثال، متغیر global_var از داخل تابع تغییر می‌کند و با استفاده از دستور export به محیط سیستم منتقل می‌شود.
  • این کار باعث می‌شود که پس از تغییر مقدار متغیر در داخل تابع، مقدار جدید آن در سراسر اسکریپت و حتی در زیرمجموعه‌های سیستم قابل دسترسی باشد.

جمع‌بندی

در شل اسکریپت‌ها، توابع به‌طور پیش‌فرض می‌توانند به متغیرهای سراسری دسترسی داشته باشند. این متغیرها در تمامی بخش‌های اسکریپت قابل دسترسی هستند و تغییرات در آن‌ها می‌تواند از داخل توابع نیز اعمال شود. اگر نیاز دارید که تغییرات متغیر سراسری تأثیر بیشتری بگذارد، می‌توانید از دستور export برای صادر کردن آن به محیط سیستم استفاده کنید. این ویژگی به شما این امکان را می‌دهد که داده‌ها و تنظیمات مشترک میان توابع مختلف را به‌سادگی مدیریت کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. استفاده از توابع کتابخانه‌ای”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف و ذخیره توابع در فایل‌های جداگانه” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، تعریف توابع در فایل‌های جداگانه یک روش موثر برای مدیریت و سازماندهی کد است. این کار نه تنها باعث کاهش پیچیدگی و افزایش خوانایی اسکریپت می‌شود، بلکه امکان استفاده مجدد از توابع در پروژه‌های مختلف را نیز فراهم می‌آورد. در این بخش، به چگونگی تعریف توابع و ذخیره آن‌ها در فایل‌های جداگانه پرداخته خواهد شد.


چرا باید توابع را در فایل‌های جداگانه ذخیره کنیم؟

  1. مدیریت بهتر کد: با ذخیره توابع در فایل‌های جداگانه، کدهای مربوط به توابع از کدهای اصلی اسکریپت جدا می‌شوند و این امر به بهبود خوانایی و نگهداری کد کمک می‌کند.
  2. استفاده مجدد: توابعی که در فایل‌های جداگانه ذخیره می‌شوند، می‌توانند در پروژه‌های مختلف یا اسکریپت‌های دیگر استفاده شوند.
  3. تست آسان‌تر: اگر توابع را در فایل‌های جداگانه قرار دهید، می‌توانید آن‌ها را به‌طور مستقل تست کنید.
  4. کاهش پیچیدگی اسکریپت‌های اصلی: اسکریپت‌های اصلی می‌توانند ساده‌تر و واضح‌تر باشند، زیرا کدهای توابع در فایل‌های جداگانه مدیریت می‌شوند.

نحوه ذخیره توابع در فایل‌های جداگانه

برای ذخیره توابع در فایل‌های جداگانه، ابتدا تابع یا توابع موردنظر خود را تعریف کنید و سپس آن‌ها را در یک فایل جدید ذخیره کنید. پس از آن، با استفاده از دستور source یا . (dot) می‌توانید آن فایل را در اسکریپت اصلی خود بارگذاری کنید.

گام اول: تعریف توابع در فایل جداگانه

فرض کنید یک تابع به نام greet داریم که یک پیام خوشامدگویی چاپ می‌کند. این تابع را در فایلی به نام functions.sh ذخیره می‌کنیم.

ایجاد فایل functions.sh و ذخیره تابع در آن:

#!/bin/bash

# تابع greet که یک پیام خوشامدگویی چاپ می‌کند
greet() {
    echo "Hello, $1!"
}

در اینجا، تابع greet یک ورودی (نام شخص) دریافت می‌کند و پیام خوشامدگویی را چاپ می‌کند. این تابع در فایل functions.sh ذخیره شده است.

گام دوم: استفاده از فایل حاوی توابع در اسکریپت اصلی

حالا که توابع خود را در یک فایل جداگانه ذخیره کرده‌ایم، می‌توانیم این فایل را در اسکریپت اصلی خود بارگذاری کنیم.

ایجاد اسکریپت اصلی main.sh و بارگذاری فایل توابع:

#!/bin/bash

# بارگذاری فایل توابع
source ./functions.sh  # یا می‌توانید از . برای بارگذاری استفاده کنید: . ./functions.sh

# فراخوانی تابع greet
greet "Alice"  # خروجی: Hello, Alice!
greet "Bob"    # خروجی: Hello, Bob!

در اینجا، از دستور source برای بارگذاری فایل functions.sh که حاوی تابع greet است، استفاده کرده‌ایم. بعد از بارگذاری این فایل، تابع greet در اسکریپت اصلی در دسترس قرار می‌گیرد و می‌توانیم آن را فراخوانی کنیم.

استفاده از دستور . به‌جای source

دستور source می‌تواند با استفاده از نقطه (.) نیز فراخوانی شود. این دو دستور عملکرد یکسانی دارند و معمولاً source برای وضوح بیشتر استفاده می‌شود، اما می‌توانید از نقطه (.) نیز به‌عنوان جایگزین آن استفاده کنید.

. ./functions.sh  # همانند دستور source عمل می‌کند
گام سوم: تغییرات در توابع

اگر بخواهید توابع موجود در فایل‌های جداگانه را تغییر دهید، فقط کافی است فایل مربوطه (مثل functions.sh) را ویرایش کنید و تغییرات موردنظر را در آنجا اعمال کنید. اسکریپت اصلی به‌طور خودکار از آخرین نسخه فایل توابع استفاده خواهد کرد، زیرا فایل هر بار که با دستور source یا . بارگذاری می‌شود، به‌روز می‌شود.


مزایای ذخیره توابع در فایل‌های جداگانه

  1. خوانایی بهتر: کدهای تابع در فایل‌های جداگانه باعث می‌شوند که اسکریپت اصلی ساده‌تر و خواناتر باشد.
  2. مدیریت ساده‌تر: می‌توان توابع را به‌راحتی به‌روز کرد و از آن‌ها در اسکریپت‌های مختلف استفاده کرد.
  3. کاهش تکرار کد: توابعی که در فایل‌های جداگانه ذخیره می‌شوند می‌توانند در چندین اسکریپت استفاده شوند، که منجر به کاهش تکرار کد می‌شود.
  4. امکان استفاده در پروژه‌های مختلف: می‌توانید توابع را در پروژه‌های مختلف یا اسکریپت‌های مختلف وارد کنید و از آن‌ها استفاده کنید.

جمع‌بندی

تعریف و ذخیره توابع در فایل‌های جداگانه یک روش مؤثر برای مدیریت و سازماندهی اسکریپت‌های شل است. این روش به شما کمک می‌کند که توابع را در پروژه‌های مختلف استفاده کنید، کدهای اسکریپت اصلی خود را ساده‌تر کنید و در عین حال کدها را به‌راحتی مدیریت و به‌روز کنید. با استفاده از دستور source یا . می‌توانید توابع ذخیره‌شده در فایل‌های جداگانه را به‌راحتی در اسکریپت‌های اصلی بارگذاری کنید و از آن‌ها استفاده کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه import فایل توابع با استفاده از source یا . (dot)” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، گاهی اوقات لازم است که توابعی را که در فایل‌های جداگانه ذخیره شده‌اند، در اسکریپت اصلی خود وارد (import) کنید تا بتوانید از آن‌ها استفاده کنید. برای این کار از دو روش اصلی استفاده می‌شود: استفاده از دستور source یا استفاده از نقطه (.) که عملکرد مشابهی دارند.


چرا باید توابع را import کنیم؟

  1. مدیریت بهتر کد: کدهای مربوط به توابع می‌توانند در فایل‌های جداگانه قرار بگیرند، که این باعث می‌شود اسکریپت اصلی شما تمیزتر و خواناتر باشد.
  2. استفاده مجدد از توابع: شما می‌توانید توابع ذخیره شده در فایل‌های جداگانه را در اسکریپت‌های مختلف یا پروژه‌های مختلف استفاده کنید.
  3. به روز رسانی آسان‌تر: وقتی که توابع در یک فایل جداگانه قرار دارند، می‌توانید تغییرات را تنها در آن فایل اعمال کنید و نیازی به ویرایش اسکریپت‌های مختلف نیست.

نحوه استفاده از دستور source

دستور source به شما این امکان را می‌دهد که محتوای یک فایل را در اسکریپت فعلی بارگذاری کنید، بدون این که به اجرای مجدد اسکریپت نیاز باشد. وقتی فایل مورد نظر با دستور source وارد می‌شود، تمام توابع و متغیرهایی که در آن فایل تعریف شده‌اند در دسترس اسکریپت اصلی قرار می‌گیرند.

نمونه‌ای از استفاده از دستور source:

فرض کنید یک فایل به نام functions.sh دارید که حاوی توابع مختلف است. شما می‌توانید این فایل را به اسکریپت اصلی خود وارد کنید.

فایل functions.sh:

#!/bin/bash

# تابع greet که یک پیام خوشامدگویی چاپ می‌کند
greet() {
    echo "Hello, $1!"
}

حالا در اسکریپت اصلی خود می‌توانید این فایل را با استفاده از دستور source وارد کنید.

فایل اصلی main.sh:

#!/bin/bash

# بارگذاری توابع از فایل functions.sh
source ./functions.sh

# فراخوانی تابع greet
greet "Alice"  # خروجی: Hello, Alice!
greet "Bob"    # خروجی: Hello, Bob!

در اینجا، با استفاده از دستور source ./functions.sh فایل functions.sh را وارد کرده‌ایم و توابع موجود در آن فایل در اسکریپت اصلی قابل استفاده شدند.


استفاده از نقطه (.) برای وارد کردن فایل

دستور . (dot) عملکردی مشابه با دستور source دارد و می‌توان از آن برای وارد کردن فایل‌ها به اسکریپت استفاده کرد. این دستور بیشتر برای کوتاه‌تر نوشتن کد به کار می‌رود، اما کاربرد و عملکرد آن کاملاً مشابه با دستور source است.

نمونه‌ای از استفاده از دستور . (dot):

#!/bin/bash

# بارگذاری توابع از فایل functions.sh با استفاده از نقطه (.)
. ./functions.sh

# فراخوانی تابع greet
greet "Charlie"  # خروجی: Hello, Charlie!

در اینجا نیز از دستور . برای وارد کردن فایل functions.sh استفاده کرده‌ایم و همانطور که مشاهده می‌کنید، تابع greet قابل استفاده در اسکریپت اصلی است.


مقایسه source و . (dot)

  • عملکرد مشابه: هر دو دستور source و . عملکرد مشابهی دارند و به شما اجازه می‌دهند تا محتویات یک فایل را در اسکریپت فعلی بارگذاری کنید.
  • تفاوت ظاهری: دستور source به صورت کامل‌تر و واضح‌تری نوشته می‌شود، در حالی که نقطه (.) به صورت کوتاه‌تر نوشته می‌شود.
  • استفاده رایج: دستور source معمولاً در اسکریپت‌های طولانی‌تر و زمانی که نیاز به وضوح بیشتر دارید استفاده می‌شود. نقطه (.) بیشتر برای کوتاه نگه داشتن کد در اسکریپت‌های ساده یا زمانی که می‌خواهید کدتان را سریع‌تر بنویسید به کار می‌رود.

نکات مهم

  • مسیر فایل: هنگام استفاده از دستور source یا نقطه (.) برای وارد کردن فایل، باید مسیر دقیق فایل را مشخص کنید. اگر فایل در دایرکتوری جاری باشد، می‌توانید از ./ برای اشاره به آن استفاده کنید.
  • اجرای فایل: برخلاف دستور bash که فایل را به‌طور مستقل اجرا می‌کند، با استفاده از source یا .، فایل درون اسکریپت فعلی اجرا می‌شود و هیچ فرآیند جدیدی برای اجرای آن ایجاد نمی‌شود. بنابراین، تغییرات در متغیرها و توابع در اسکریپت فعلی اعمال خواهند شد.
  • تأثیرات در دسترسی: هر چیزی که در فایل واردشده با دستور source یا . تعریف شده باشد (توابع، متغیرها، یا هر نوع تغییر دیگری)، در اسکریپت اصلی در دسترس خواهد بود.

جمع‌بندی

برای وارد کردن توابع یا متغیرهای ذخیره‌شده در فایل‌های جداگانه در شل اسکریپت‌ها، می‌توان از دستور source یا نقطه (.) استفاده کرد. هر دو دستور به شما امکان می‌دهند که محتوای یک فایل را در اسکریپت جاری وارد کنید و از توابع و متغیرهای موجود در آن استفاده کنید. دستور source واضح‌تر است و در اسکریپت‌های پیچیده‌تر کاربرد دارد، در حالی که دستور نقطه (.) کوتاه‌تر و سریع‌تر است و برای اسکریپت‌های ساده‌تر مناسب است. این روش‌ها باعث بهبود خوانایی، مدیریت بهتر کد و استفاده مجدد از توابع در پروژه‌های مختلف می‌شوند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده مجدد از توابع در پروژه‌های مختلف” subtitle=”توضیحات کامل”]در برنامه‌نویسی و به‌ویژه در اسکریپت‌نویسی شل، یکی از اصولی که به بهبود ساختار و نگهداری کد کمک می‌کند، استفاده مجدد از توابع است. این امکان به شما اجازه می‌دهد که توابع نوشته‌شده در پروژه‌های مختلف را بدون نیاز به نوشتن دوباره، در پروژه‌های جدید یا اسکریپت‌های مختلف استفاده کنید. این کار باعث افزایش بهره‌وری، کاهش خطاها و تسهیل در نگهداری کد می‌شود.


چرا استفاده مجدد از توابع مهم است؟

  1. کاهش پیچیدگی کد: به جای نوشتن مجدد توابع برای هر پروژه جدید، می‌توانید از توابع موجود در پروژه‌های قبلی استفاده کنید و تنها آن‌ها را در پروژه‌های جدید وارد کنید.
  2. مدیریت بهتر: زمانی که توابع در فایل‌های جداگانه ذخیره شوند، می‌توانند در چندین اسکریپت به راحتی استفاده شوند و نگهداری و به‌روزرسانی آن‌ها ساده‌تر خواهد بود.
  3. کاهش خطاهای تکراری: استفاده از توابعی که قبلاً نوشته‌اید به این معناست که احتمال ایجاد خطاهای مشابه یا تکراری کمتر می‌شود.
  4. افزایش مقیاس‌پذیری: پروژه‌های شما می‌توانند مقیاس‌پذیرتر شوند زیرا برای افزودن قابلیت‌های جدید، کافی است توابع جدیدی را فقط در یک فایل اضافه کرده و از آن در سایر پروژه‌ها استفاده کنید.

روش‌های استفاده مجدد از توابع در پروژه‌های مختلف

برای استفاده مجدد از توابع در پروژه‌های مختلف، معمولاً این توابع را در فایل‌های جداگانه ذخیره کرده و سپس در اسکریپت‌های دیگر از آن‌ها استفاده می‌کنید. این روش به شما این امکان را می‌دهد که توابع را به صورت متمرکز نگهداری کنید و تنها زمانی که نیاز به تغییر دارید، آن‌ها را ویرایش کنید. در اینجا روش‌های مختلف استفاده مجدد از توابع را بررسی می‌کنیم.


1. ذخیره توابع در فایل‌های جداگانه

برای استفاده مجدد از توابع، اولین قدم این است که آن‌ها را در فایل‌های جداگانه ذخیره کنید. فرض کنید شما چندین تابع دارید که برای کارهای مختلف از جمله پردازش داده‌ها، چاپ پیام‌ها یا مدیریت خطاها استفاده می‌شوند. می‌توانید این توابع را در یک فایل به نام functions.sh ذخیره کنید.

مثال از فایل functions.sh:

#!/bin/bash

# تابع چاپ پیغام خوشامدگویی
greet() {
    echo "Hello, $1!"
}

# تابع محاسبه جمع دو عدد
add_numbers() {
    echo $(($1 + $2))
}

# تابع نمایش تاریخ فعلی
current_date() {
    echo "Today's date is: $(date)"
}

2. وارد کردن توابع در اسکریپت‌های دیگر

بعد از اینکه توابع خود را در فایل functions.sh ذخیره کردید، می‌توانید این فایل را در هر اسکریپت دیگری که نیاز به این توابع دارید، وارد کنید. برای این کار می‌توانید از دستور source یا نقطه (.) استفاده کنید.

مثال از فایل main.sh:

#!/bin/bash

# وارد کردن توابع از فایل functions.sh
source ./functions.sh

# استفاده از توابع
greet "Alice"        # خروجی: Hello, Alice!
sum=$(add_numbers 5 10)  # خروجی: 15
echo $sum
current_date         # خروجی: Today's date is: ...

در اینجا، با وارد کردن فایل functions.sh با استفاده از دستور source ./functions.sh یا نقطه (.)، توابع greet، add_numbers و current_date در دسترس اسکریپت main.sh قرار می‌گیرند و می‌توانیم از آن‌ها استفاده کنیم.


3. استفاده از توابع در پروژه‌های مختلف

برای استفاده مجدد از توابع در پروژه‌های مختلف، تنها کافی است که فایل functions.sh را در پروژه جدید خود وارد کنید. این کار به شما این امکان را می‌دهد که توابع موجود را بدون نوشتن مجدد در هر پروژه‌ای که به آن نیاز دارید، مورد استفاده قرار دهید.

مثال از پروژه جدید (مثلاً project2.sh):

#!/bin/bash

# وارد کردن توابع از فایل functions.sh
source /path/to/functions.sh

# استفاده از توابع در پروژه جدید
greet "Bob"            # خروجی: Hello, Bob!
result=$(add_numbers 20 30)  # خروجی: 50
echo $result

در اینجا، ما فایل functions.sh را در پروژه جدید خود وارد کرده‌ایم و توابع موجود در آن را دوباره استفاده کرده‌ایم. همانطور که می‌بینید، نیازی به نوشتن مجدد توابع نیست و می‌توان از همان توابع در پروژه‌های مختلف استفاده کرد.


4. نگهداری و به‌روزرسانی توابع

یکی از مزایای اصلی ذخیره توابع در فایل‌های جداگانه، این است که شما تنها باید در یک مکان تغییرات را اعمال کنید. اگر نیاز به به‌روزرسانی یا اصلاح یک تابع دارید، می‌توانید تنها در فایل functions.sh تغییرات را اعمال کنید و تمام پروژه‌هایی که این فایل را وارد کرده‌اند، به‌طور خودکار به‌روزرسانی خواهند شد.

مثال از اصلاح تابع greet:

#!/bin/bash

# اصلاح تابع greet
greet() {
    echo "Welcome, $1. Have a great day!"
}

با این تغییر، همه پروژه‌هایی که از این تابع استفاده می‌کنند، به‌طور خودکار به نسخه جدید تابع دسترسی خواهند داشت و نیازی به تغییر در آن پروژه‌ها نیست.


جمع‌بندی

استفاده مجدد از توابع در پروژه‌های مختلف باعث افزایش بهره‌وری، کاهش خطاها و تسهیل در نگهداری کد می‌شود. برای این کار، ابتدا توابع خود را در فایل‌های جداگانه ذخیره کرده و سپس در اسکریپت‌های دیگر با استفاده از دستور source یا نقطه (.) وارد کنید. این روش‌ها به شما این امکان را می‌دهند که توابع را به‌راحتی در پروژه‌های مختلف استفاده کنید و در صورت نیاز به‌روزرسانی، تنها یک فایل را ویرایش کرده و تغییرات را در تمام پروژه‌ها اعمال کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 7. توابع بازگشتی (Recursive Functions)”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف و استفاده از توابع بازگشتی” subtitle=”توضیحات کامل”]توابع بازگشتی یکی از ویژگی‌های قدرتمند در برنامه‌نویسی هستند که در آن‌ها یک تابع خود را برای حل مسئله‌ای مشابه فراخوانی می‌کند. در واقع، تابعی که خود را فراخوانی می‌کند، قادر است تا به طور مکرر عمل پردازش را انجام دهد و در نهایت نتیجه نهایی را بازگرداند.

در شل اسکریپت‌نویسی، توابع بازگشتی نیز قابل استفاده هستند، اما باید دقت داشت که برای جلوگیری از بروز مشکلاتی مانند ایجاد حلقه‌های بی‌پایان یا مصرف بیش از حد حافظه، از آن‌ها به درستی استفاده کرد.

توابع بازگشتی برای حل مسائلی مفید هستند که ساختار درختی یا سلسله‌مراتبی دارند. برخی از این مسائل می‌توانند شامل جستجو در دایرکتوری‌ها، پردازش فایل‌های درختی، محاسبه دنباله‌های بازگشتی مانند دنباله فیبوناچی یا حتی انجام محاسبات ریاضی پیچیده باشند.


نحوه تعریف و استفاده از توابع بازگشتی

برای تعریف یک تابع بازگشتی در شل، کافی است که تابعی را تعریف کنید که در درون بدنه خود خود را فراخوانی کند. در اینجا یک مثال ساده از نحوه تعریف و استفاده از توابع بازگشتی در شل آورده شده است.

مثال: محاسبه فاکتوریل یک عدد با استفاده از تابع بازگشتی

فاکتوریل یک عدد، به این صورت تعریف می‌شود:

  • فاکتوریل صفر (۰!) برابر با 1 است.
  • فاکتوریل هر عدد N، برابر با N ضرب در فاکتوریل (N-1) است.

بنابراین، برای محاسبه فاکتوریل با استفاده از تابع بازگشتی، باید تابعی بنویسیم که خود را برای کاهش مقدار N فراخوانی کند.

#!/bin/bash

# تابع بازگشتی برای محاسبه فاکتوریل
factorial() {
    if [ $1 -eq 0 ]; then
        # شرط پایه: اگر عدد صفر بود فاکتوریل برابر با 1 است
        echo 1
    else
        # فراخوانی بازگشتی تابع برای محاسبه فاکتوریل
        local temp=$(( $1 - 1 ))  # کاهش مقدار ورودی
        local result=$(factorial $temp)  # فراخوانی بازگشتی
        echo $(( $1 * $result ))  # ضرب نتیجه با مقدار فعلی
    fi
}

# درخواست ورودی از کاربر
echo "Enter a number: "
read number

# محاسبه و نمایش فاکتوریل
result=$(factorial $number)
echo "The factorial of $number is: $result"

توضیح کد:

  1. تابع factorial برای محاسبه فاکتوریل یک عدد تعریف شده است.
  2. در این تابع، ابتدا بررسی می‌کنیم که آیا ورودی صفر است یا خیر. اگر صفر بود، تابع 1 را برمی‌گرداند.
  3. در غیر این صورت، تابع خود را برای ورودی N-1 فراخوانی می‌کند و نتیجه را با N ضرب می‌کند.
  4. تابع بازگشتی تا زمانی که ورودی به صفر برسد، ادامه می‌یابد و سپس خروجی نهایی بازگشت داده می‌شود.

خطرات و نکات استفاده از توابع بازگشتی

استفاده از توابع بازگشتی در شل اسکریپت‌نویسی مزایای زیادی دارد، اما باید با دقت به کار گرفته شود زیرا در صورتی که به درستی پیاده‌سازی نشوند، می‌توانند مشکلاتی مانند خرابی حافظه و خرابی عملکرد ایجاد کنند. در اینجا برخی از خطرات و نکات را بررسی می‌کنیم:

  1. خطر وقوع حلقه بی‌پایان: یکی از مهم‌ترین مشکلات استفاده از توابع بازگشتی در شل، عدم تعریف درست شرط پایه است. اگر شرط پایه به درستی تنظیم نشود، تابع به صورت بی‌پایان خود را فراخوانی می‌کند و منجر به خرابی برنامه می‌شود. به همین دلیل باید به دقت بررسی شود که آیا تابع در نهایت به شرط پایه می‌رسد یا خیر.
  2. محدودیت‌های حافظه: در شل، به دلیل اینکه توابع بازگشتی به صورت سطحی در حافظه اجرا می‌شوند، در مقایسه با زبان‌های دیگر که از پشته برای ذخیره‌سازی فراخوانی‌های توابع استفاده می‌کنند، محدودیت حافظه ممکن است مشکل‌ساز شود. بنابراین، برای استفاده از توابع بازگشتی در شل، باید از مقادیر ورودی کوچک‌تری استفاده کرد.
  3. سختی در دیباگ کردن: اگر توابع بازگشتی به درستی پیاده‌سازی نشوند، دیباگ کردن آن‌ها می‌تواند دشوار باشد. با افزایش عمق بازگشت‌ها، پیدا کردن علت مشکلات پیچیده‌تر می‌شود.
  4. استفاده از توابع بازگشتی برای مسائل درختی و سلسله‌مراتبی: توابع بازگشتی بیشتر برای حل مسائل با ساختارهای درختی یا سلسله‌مراتبی مانند جستجو در دایرکتوری‌ها و فایل‌ها، محاسبات دنباله‌های بازگشتی، مرتب‌سازی و غیره مناسب هستند.

مثال‌های دیگر از توابع بازگشتی

  1. حساب کردن دنباله فیبوناچی:دنباله فیبوناچی، دنباله‌ای است که هر عدد در آن برابر با مجموع دو عدد قبلی است. به این صورت که فیبوناچی برای N برابر با:
    • فیبوناچی 0 = 0
    • فیبوناچی 1 = 1
    • فیبوناچی N = فیبوناچی (N-1) + فیبوناچی (N-2)

    کد محاسبه فیبوناچی با توابع بازگشتی:

    #!/bin/bash
    
    fibonacci() {
        if [ $1 -eq 0 ]; then
            echo 0
        elif [ $1 -eq 1 ]; then
            echo 1
        else
            local n1=$(fibonacci $(( $1 - 1 )))
            local n2=$(fibonacci $(( $1 - 2 )))
            echo $(( n1 + n2 ))
        fi
    }
    
    # درخواست ورودی از کاربر
    echo "Enter a number: "
    read number
    
    # محاسبه و نمایش دنباله فیبوناچی
    result=$(fibonacci $number)
    echo "The Fibonacci number at position $number is: $result"
    

    این کد به شما اجازه می‌دهد که با استفاده از توابع بازگشتی، هر عدد ن-th از دنباله فیبوناچی را محاسبه کنید.


جمع‌بندی

توابع بازگشتی در شل اسکریپت‌نویسی ابزاری قدرتمند برای حل مسائل پیچیده و حل مشکلات با ساختار درختی یا سلسله‌مراتبی هستند. با استفاده از این توابع، می‌توانید مسائلی مانند محاسبه فاکتوریل، دنباله‌های فیبوناچی یا جستجو در دایرکتوری‌ها را به راحتی پیاده‌سازی کنید. با این حال، استفاده از توابع بازگشتی در شل باید با دقت انجام شود تا از بروز مشکلاتی مانند حلقه‌های بی‌پایان، مصرف زیاد حافظه یا مشکلات دیباگ جلوگیری شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”کاربردهای توابع بازگشتی در شل” subtitle=”توضیحات کامل”]توابع بازگشتی در شل اسکریپت‌نویسی برای حل مسائل خاص با استفاده از اصول بازگشتی، می‌توانند بسیار مفید باشند. این نوع توابع به ویژه زمانی مفیدند که مسأله‌ای نیاز به حل به صورت تکراری داشته باشد یا ساختاری سلسله‌مراتبی داشته باشد. در این بخش، به بررسی برخی از کاربردهای رایج توابع بازگشتی در شل خواهیم پرداخت.


۱. جستجو در دایرکتوری‌ها و فایل‌ها

یکی از کاربردهای رایج توابع بازگشتی در شل، جستجو در دایرکتوری‌ها و فایل‌ها است. در اینجا، توابع بازگشتی می‌توانند برای جستجو در دایرکتوری‌ها و زیرشاخه‌های آن‌ها استفاده شوند.

مثال: جستجو در دایرکتوری‌ها به صورت بازگشتی

فرض کنید می‌خواهید تمام فایل‌هایی را که در زیرشاخه‌های یک دایرکتوری مشخص قرار دارند جستجو کنید. برای این کار می‌توان از یک تابع بازگشتی استفاده کرد که دایرکتوری‌ها را بررسی کرده و اگر دایرکتوری‌ای پیدا کرد، آن را به صورت بازگشتی بررسی کند.

#!/bin/bash

# تابع بازگشتی برای جستجو در دایرکتوری‌ها
search_files() {
    local directory="$1"
    local search_term="$2"

    # برای هر فایل در دایرکتوری جاری
    for file in "$directory"/*; do
        if [ -d "$file" ]; then
            # اگر فایل یک دایرکتوری است، تابع را به صورت بازگشتی فراخوانی می‌کنیم
            search_files "$file" "$search_term"
        elif [ -f "$file" ]; then
            # اگر فایل معمولی باشد، نام آن را نمایش می‌دهیم
            if grep -q "$search_term" "$file"; then
                echo "Found in: $file"
            fi
        fi
    done
}

# ورودی از کاربر
echo "Enter the directory path: "
read directory
echo "Enter the search term: "
read term

# فراخوانی تابع جستجو
search_files "$directory" "$term"

توضیح کد:

  • این کد برای هر دایرکتوری بررسی می‌کند که آیا در داخل آن زیرشاخه‌ها وجود دارند یا خیر. اگر دایرکتوری‌ای پیدا کند، خود را به صورت بازگشتی برای آن دایرکتوری فراخوانی می‌کند و جستجو را ادامه می‌دهد.
  • در نهایت، اگر متنی در فایل پیدا شود، نام فایل نمایش داده می‌شود.

۲. محاسبه دنباله‌های بازگشتی

توابع بازگشتی معمولاً برای محاسبه دنباله‌های عددی استفاده می‌شوند. یکی از معروف‌ترین این دنباله‌ها، دنباله فیبوناچی است. در این دنباله، هر عدد برابر با مجموع دو عدد قبلی است.

مثال: محاسبه دنباله فیبوناچی با استفاده از تابع بازگشتی

#!/bin/bash

# تابع بازگشتی برای محاسبه فیبوناچی
fibonacci() {
    if [ $1 -eq 0 ]; then
        echo 0
    elif [ $1 -eq 1 ]; then
        echo 1
    else
        local n1=$(fibonacci $(( $1 - 1 )))
        local n2=$(fibonacci $(( $1 - 2 )))
        echo $(( n1 + n2 ))
    fi
}

# ورودی از کاربر
echo "Enter a number: "
read number

# محاسبه و نمایش دنباله فیبوناچی
result=$(fibonacci $number)
echo "The Fibonacci number at position $number is: $result"

توضیح کد:

  • در این کد، تابع fibonacci به صورت بازگشتی نوشته شده است. برای هر عدد N، تابع خود را برای مقادیر (N-1) و (N-2) فراخوانی کرده و سپس حاصل جمع آن‌ها را باز می‌گرداند.
  • این کد به شما اجازه می‌دهد تا هر عدد از دنباله فیبوناچی را محاسبه کنید.

۳. تجزیه و تحلیل داده‌های سلسله‌مراتبی

در بسیاری از پروژه‌های شل اسکریپت‌نویسی، داده‌ها به صورت سلسله‌مراتبی ذخیره می‌شوند (مثل فایل‌های XML یا JSON که درختی هستند). در این مواقع، توابع بازگشتی می‌توانند برای تجزیه و تحلیل داده‌های این ساختارها بسیار مفید باشند.

مثال: پردازش فایل‌های XML به صورت بازگشتی

در صورتی که بخواهید داده‌های داخل یک فایل XML که به صورت درختی است را پردازش کنید، می‌توانید از توابع بازگشتی استفاده کنید.

#!/bin/bash

# تابع بازگشتی برای پردازش درختی XML
parse_xml() {
    local file="$1"
    # فرض کنید که فایل XML حاوی تگ‌هایی به نام <item> باشد
    while read line; do
        if [[ $line =~ "<item>" ]]; then
            echo "Found item: $line"
        fi
    done < "$file"
}

# ورودی از کاربر
echo "Enter the XML file path: "
read file

# فراخوانی تابع برای پردازش XML
parse_xml "$file"

توضیح کد:

  • این کد فرض می‌کند که شما یک فایل XML دارید که حاوی تگ‌های <item> است. تابع parse_xml به طور بازگشتی این تگ‌ها را پردازش کرده و آن‌ها را به نمایش می‌گذارد.
  • این کار می‌تواند برای تحلیل فایل‌های بزرگ و درختی مفید باشد.

۴. پیاده‌سازی الگوریتم‌های جستجو و مرتب‌سازی به صورت بازگشتی

برخی از الگوریتم‌های پیچیده مرتب‌سازی و جستجو می‌توانند به صورت بازگشتی پیاده‌سازی شوند. به عنوان مثال، الگوریتم‌های مرتب‌سازی مانند “مرتب‌سازی سریع” (Quick Sort) و “مرتب‌سازی ادغامی” (Merge Sort) معمولاً به صورت بازگشتی پیاده‌سازی می‌شوند.

مثال: مرتب‌سازی سریع (Quick Sort) با استفاده از توابع بازگشتی

#!/bin/bash

# تابع بازگشتی برای مرتب‌سازی سریع (Quick Sort)
quick_sort() {
    if [ ${#1} -le 1 ]; then
        echo "$1"
    else
        local pivot="${1:0:1}"
        local left=()
        local right=()
        
        # تقسیم آرایه به چپ و راست نسبت به pivot
        for i in ${1}; do
            if [ "$i" -lt "$pivot" ]; then
                left+=("$i")
            else
                right+=("$i")
            fi
        done
        
        # فراخوانی بازگشتی برای چپ و راست
        local sorted_left=$(quick_sort "${left[@]}")
        local sorted_right=$(quick_sort "${right[@]}")
        
        # بازگشت نتیجه مرتب‌شده
        echo "${sorted_left[@]} $pivot ${sorted_right[@]}"
    fi
}

# ورودی از کاربر
echo "Enter numbers to sort (space separated): "
read -a numbers

# مرتب‌سازی با استفاده از Quick Sort
result=$(quick_sort "${numbers[@]}")
echo "Sorted numbers: $result"

توضیح کد:

  • این کد پیاده‌سازی الگوریتم مرتب‌سازی سریع (Quick Sort) با استفاده از توابع بازگشتی است. در اینجا، تابع quick_sort ابتدا یک عدد را به عنوان pivot (محور) انتخاب کرده، سپس لیست را به دو بخش تقسیم می‌کند و برای هر بخش به طور بازگشتی خود را فراخوانی می‌کند.

جمع‌بندی

توابع بازگشتی در شل اسکریپت‌نویسی کاربردهای گسترده‌ای دارند، به ویژه در حل مسائلی که به صورت درختی یا سلسله‌مراتبی سازمان‌دهی شده‌اند. این توابع برای جستجو در دایرکتوری‌ها، پردازش داده‌های سلسله‌مراتبی، محاسبه دنباله‌های ریاضی، پیاده‌سازی الگوریتم‌های جستجو و مرتب‌سازی و بسیاری از مسائل دیگر مفید هستند. به هر حال، استفاده از توابع بازگشتی باید با دقت و رعایت اصول بهینه‌سازی انجام شود تا از بروز مشکلاتی مانند خرابی حافظه یا حلقه‌های بی‌پایان جلوگیری شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”محدودیت‌ها و مشکلات احتمالی در توابع بازگشتی” subtitle=”توضیحات کامل”]توابع بازگشتی یکی از ابزارهای قدرتمند در شل اسکریپت‌نویسی هستند، اما استفاده از آن‌ها می‌تواند با مشکلات و محدودیت‌هایی همراه باشد. این مشکلات معمولاً به دلیل نحوه عملکرد حافظه و نحوه اجرای توابع در محیط شل به وجود می‌آیند. در این بخش، به بررسی مشکلات و محدودیت‌های احتمالی در استفاده از توابع بازگشتی خواهیم پرداخت.


۱. مصرف بیش از حد حافظه و Stack Overflow

یکی از بزرگ‌ترین مشکلات استفاده از توابع بازگشتی در شل اسکریپت‌نویسی، مصرف بیش از حد حافظه است. هر بار که یک تابع بازگشتی فراخوانی می‌شود، داده‌های آن در stack ذخیره می‌شوند و پس از اتمام تابع، باید از حافظه آزاد شوند. اگر تعداد فراخوانی‌های بازگشتی زیاد باشد، ممکن است باعث بروز خطای Stack Overflow شود.

مثال: مصرف بیش از حد حافظه با توابع بازگشتی

#!/bin/bash

# تابع بازگشتی بی‌پایان که می‌تواند باعث Stack Overflow شود
infinite_recursion() {
    echo "In infinite recursion"
    infinite_recursion
}

# فراخوانی تابع
infinite_recursion

توضیح کد:

  • این کد یک تابع بازگشتی بی‌پایان تعریف کرده است که هیچ‌گاه متوقف نمی‌شود. به طور غیرمستقیم، باعث مصرف بیش از حد حافظه و بروز خطای Stack Overflow می‌شود.

راه حل:

  • برای جلوگیری از این مشکل، باید اطمینان حاصل کرد که هر تابع بازگشتی به یک نقطه پایانی دست پیدا کند و شرایط پایه (base case) به درستی تعریف شده باشد.

۲. پیچیدگی و فهم کد

توابع بازگشتی می‌توانند باعث پیچیدگی در فهم کد شوند. در مواردی که چندین فراخوانی توابع بازگشتی با یکدیگر ترکیب می‌شوند، پیگیری جریان برنامه و نتیجه بازگشتی می‌تواند چالش‌برانگیز شود.

مثال: پیچیدگی در کد بازگشتی

#!/bin/bash

# تابع بازگشتی پیچیده
complex_recursion() {
    if [ "$1" -le 1 ]; then
        echo "$1"
    else
        local temp=$(complex_recursion $(( $1 - 1 )))
        echo "$temp $1"
    fi
}

# فراخوانی تابع
complex_recursion 5

توضیح کد:

  • در این کد، تابع complex_recursion به صورت بازگشتی عمل می‌کند. هر فراخوانی آن یک مقدار را به تابع قبلی ارسال می‌کند که ممکن است درک روند اجرای آن برای برخی از افراد دشوار باشد.

راه حل:

  • برای کاهش پیچیدگی کد، می‌توان از توابع کمکی، متغیرهای توضیحی، و مستندسازی کد استفاده کرد.

۳. محدودیت‌های زبان شل در مدیریت بازگشت مقادیر

در زبان شل، توانایی بازگشت مقادیر از توابع محدود است. شل به صورت پیش‌فرض فقط می‌تواند مقادیر عددی (کدهای وضعیت) را از توابع بازگشتی برگرداند. اگر بخواهید یک مقدار متنی یا مجموعه‌ای از داده‌ها را بازگشت دهید، باید از روش‌های مختلفی مانند استفاده از متغیرهای سراسری یا دستورات خروجی (مانند echo) استفاده کنید.

مثال: بازگشت مقدار متنی از تابع

#!/bin/bash

# تابع بازگشتی برای بازگشت مقدار متنی
string_recursion() {
    if [ "$1" -le 0 ]; then
        echo "Done"
    else
        string_recursion $(( $1 - 1 ))
    fi
}

# فراخوانی تابع
result=$(string_recursion 5)
echo "$result"

توضیح کد:

  • در این کد، تابع بازگشتی متنی را با استفاده از دستور echo باز می‌گرداند. این روش به این دلیل محدود است که شل به طور پیش‌فرض تنها می‌تواند مقادیر عددی را به عنوان وضعیت بازگشتی تابع پذیرفته و مقادیر متنی باید از طریق روش‌هایی مانند echo مدیریت شوند.

راه حل:

  • برای مدیریت مقادیر متنی و داده‌های پیچیده‌تر، بهتر است از فایل‌ها یا متغیرهای سراسری برای ذخیره‌سازی مقادیر استفاده کنید.

۴. عدم پشتیبانی از حافظه داخلی (Memoization)

در شل، برخلاف برخی زبان‌های برنامه‌نویسی دیگر مانند Python یا JavaScript، حافظه داخلی (Memoization) برای ذخیره‌سازی نتایج توابع بازگشتی پشتیبانی نمی‌شود. بنابراین، اگر از توابع بازگشتی برای حل مسائلی استفاده کنید که نتایج مشابهی در مراحل مختلف نیاز دارند (مانند دنباله فیبوناچی)، تابع بازگشتی مجدداً محاسبات مشابه را انجام خواهد داد و این امر باعث کاهش کارایی می‌شود.

مثال: محاسبه دنباله فیبوناچی بدون بهینه‌سازی

#!/bin/bash

# تابع بازگشتی برای محاسبه فیبوناچی بدون بهینه‌سازی
fibonacci() {
    if [ $1 -eq 0 ]; then
        echo 0
    elif [ $1 -eq 1 ]; then
        echo 1
    else
        local n1=$(fibonacci $(( $1 - 1 )))
        local n2=$(fibonacci $(( $1 - 2 )))
        echo $(( n1 + n2 ))
    fi
}

# ورودی از کاربر
echo "Enter a number: "
read number

# محاسبه دنباله فیبوناچی
result=$(fibonacci $number)
echo "The Fibonacci number at position $number is: $result"

توضیح کد:

  • این کد بدون بهینه‌سازی است و برای محاسبه دنباله فیبوناچی از توابع بازگشتی استفاده می‌کند. اگر عدد ورودی بزرگ باشد، این تابع زمان زیادی برای محاسبه صرف خواهد کرد زیرا محاسبات تکراری انجام می‌دهد.

راه حل:

  • برای بهینه‌سازی این الگوریتم‌ها می‌توان از روش‌هایی مانند حافظه‌سازی دستی نتایج (Memoization) استفاده کرد، اما این ویژگی در شل به طور پیش‌فرض وجود ندارد.

۵. مدیریت خطا در توابع بازگشتی

مدیریت خطاها در توابع بازگشتی در شل می‌تواند چالش‌برانگیز باشد. به دلیل اینکه توابع به صورت بازگشتی فراخوانی می‌شوند، شناسایی مشکلات و خطاها در هر سطح از بازگشت می‌تواند پیچیده باشد.

مثال: مدیریت خطا در توابع بازگشتی

#!/bin/bash

# تابع بازگشتی که خطا را مدیریت می‌کند
recursive_with_error_handling() {
    if [ "$1" -le 0 ]; then
        echo "Reached base case"
    else
        if ! recursive_with_error_handling $(( $1 - 1 )); then
            echo "Error in recursion"
            return 1
        fi
    fi
}

# ورودی از کاربر
echo "Enter a number: "
read number

# فراخوانی تابع با مدیریت خطا
if ! recursive_with_error_handling $number; then
    echo "An error occurred."
    exit 1
else
    echo "Recursion completed successfully."
fi

توضیح کد:

  • در این کد، تابع recursive_with_error_handling به صورت بازگشتی فراخوانی می‌شود و در صورتی که خطایی رخ دهد، پیام خطا نمایش داده می‌شود.
  • برای مدیریت خطا در توابع بازگشتی باید از دستور return و بررسی وضعیت خروجی با $? استفاده کرد.

راه حل:

  • برای مدیریت بهتر خطاها، می‌توان از متغیرهای وضعیت و بازگشت مقادیر مناسب در هنگام بروز خطاها استفاده کرد.

جمع‌بندی

در حالی که توابع بازگشتی ابزارهای بسیار مفیدی در شل اسکریپت‌نویسی هستند، استفاده از آن‌ها ممکن است با محدودیت‌ها و مشکلاتی همراه باشد. این مشکلات شامل مصرف زیاد حافظه و بروز خطای Stack Overflow، پیچیدگی فهم کد، محدودیت‌های بازگشتی مقادیر، و مشکلات مرتبط با مدیریت خطاها است. برای رفع این مشکلات، باید از استراتژی‌های بهینه‌سازی، مدیریت صحیح حافظه و مستندسازی مناسب استفاده کرد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 8. مدیریت آرگومان‌های خط فرمان”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه پردازش آرگومان‌های ورودی اسکریپت” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، شما می‌توانید آرگومان‌هایی را هنگام اجرای اسکریپت به آن پاس دهید. این آرگومان‌ها می‌توانند به عنوان ورودی برای انجام عملیات‌های مختلف در اسکریپت استفاده شوند. پردازش این آرگومان‌ها در شل اسکریپت‌ها به شما این امکان را می‌دهد که رفتار اسکریپت را بسته به ورودی‌های مختلف تغییر دهید.


۱. دسترسی به آرگومان‌ها

در شل، آرگومان‌های ورودی به اسکریپت به طور خودکار در متغیرهای خاص ذخیره می‌شوند. در اینجا، نحوه دسترسی به این آرگومان‌ها را توضیح می‌دهیم:

  • $0: نام اسکریپت
  • $1, $2, $3, …: آرگومان‌های ورودی. به عنوان مثال، $1 به اولین آرگومان، $2 به دومین آرگومان و به همین ترتیب اشاره می‌کند.
  • $#: تعداد آرگومان‌های ورودی که به اسکریپت داده شده است.
  • $@ و $*: همه آرگومان‌ها به صورت یک لیست.

۲. نمونه ساده از استفاده از آرگومان‌ها

برای درک بهتر نحوه پردازش آرگومان‌های ورودی، بیایید یک اسکریپت ساده بنویسیم که از آرگومان‌های ورودی استفاده می‌کند.

#!/bin/bash

# بررسی تعداد آرگومان‌ها
if [ $# -lt 2 ]; then
    echo "Usage: $0 <arg1> <arg2>"
    exit 1
fi

# دسترسی به آرگومان‌ها
echo "First argument: $1"
echo "Second argument: $2"
echo "Total arguments: $#"

توضیحات کد:

  • در این اسکریپت، ابتدا بررسی می‌کنیم که تعداد آرگومان‌ها کم‌تر از ۲ نباشد. اگر تعداد آرگومان‌ها کمتر از ۲ باشد، پیامی به کاربر نشان می‌دهیم و اسکریپت را متوقف می‌کنیم.
  • سپس از $1 و $2 برای دسترسی به آرگومان‌های اول و دوم استفاده می‌کنیم و همچنین از $# برای نمایش تعداد کل آرگومان‌ها استفاده می‌کنیم.

مثال اجرا:

$ ./script.sh hello world
First argument: hello
Second argument: world
Total arguments: 2

۳. استفاده از $@ و $*

  • $@ و $* هر دو شامل تمام آرگومان‌های ورودی اسکریپت هستند، اما تفاوت‌هایی در نحوه استفاده دارند:
    • $@: اگر این مقدار در داخل کوتیشن‌مارک‌ها قرار گیرد، هر آرگومان به صورت یک عنصر جداگانه در نظر گرفته می‌شود.
    • $*: زمانی که داخل کوتیشن‌مارک‌ها قرار گیرد، همه آرگومان‌ها به عنوان یک رشته واحد در نظر گرفته می‌شوند.

مثال:

#!/bin/bash

# استفاده از $@ و $*
echo "Using \$@:"
for arg in "$@"; do
    echo $arg
done

echo "Using \$*:"
for arg in "$*"; do
    echo $arg
done

توضیح کد:

  • در این اسکریپت، ابتدا از $@ برای پیمایش آرگومان‌ها به صورت جداگانه استفاده کرده‌ایم. سپس از $* برای پیمایش آن‌ها به عنوان یک رشته واحد استفاده کرده‌ایم.

مثال اجرا:

$ ./script.sh hello world "my name"
Using $@:
hello
world
my name
Using $*:
hello world my name

۴. استفاده از شرط‌ها برای پردازش آرگومان‌ها

می‌توانیم از دستورات شرطی (مانند if و case) برای پردازش آرگومان‌ها و انجام عملیات‌های مختلف بسته به مقدار آن‌ها استفاده کنیم.

مثال:

#!/bin/bash

# بررسی نوع آرگومان‌ها با دستور if
if [ "$1" == "start" ]; then
    echo "Starting the process..."
elif [ "$1" == "stop" ]; then
    echo "Stopping the process..."
else
    echo "Invalid argument. Please use 'start' or 'stop'."
fi

توضیح کد:

  • این اسکریپت با استفاده از دستور if بررسی می‌کند که آیا اولین آرگومان (که $1 است) برابر با start یا stop است. اگر هیچ‌کدام از این‌ها نباشد، پیام خطا نمایش داده می‌شود.

مثال اجرا:

$ ./script.sh start
Starting the process...

$ ./script.sh stop
Stopping the process...

$ ./script.sh pause
Invalid argument. Please use 'start' or 'stop'.

۵. استفاده از حلقه برای پردازش چندین آرگومان

اگر نیاز به پردازش تعداد زیادی آرگومان دارید، می‌توانید از حلقه‌ها برای پیمایش و پردازش آرگومان‌ها استفاده کنید.

مثال:

#!/bin/bash

# پردازش تمام آرگومان‌ها با استفاده از حلقه
for arg in "$@"; do
    echo "Processing argument: $arg"
done

توضیح کد:

  • در این اسکریپت، از حلقه for برای پیمایش تمام آرگومان‌های ورودی استفاده کرده‌ایم. برای هر آرگومان، یک پیام نمایش داده می‌شود.

مثال اجرا:

$ ./script.sh apple banana cherry
Processing argument: apple
Processing argument: banana
Processing argument: cherry

۶. استفاده از دستور getopts برای پردازش آرگومان‌ها

در شل، برای پردازش آرگومان‌های ورودی به صورت پیچیده‌تر (مانند آرگومان‌های گزینه‌ای) می‌توان از دستور getopts استفاده کرد. این دستور به شما اجازه می‌دهد که آرگومان‌ها را با گزینه‌های مختلفی مانند -f یا -v پردازش کنید.

مثال:

#!/bin/bash

# پردازش آرگومان‌های گزینه‌ای با استفاده از getopts
while getopts "f:v" opt; do
    case $opt in
        f)
            echo "Option -f was triggered with value: $OPTARG"
            ;;
        v)
            echo "Option -v was triggered"
            ;;
        *)
            echo "Invalid option"
            ;;
    esac
done

توضیح کد:

  • این اسکریپت از دستور getopts برای پردازش آرگومان‌های ورودی استفاده می‌کند. در این مثال، -f یک آرگومان با مقدار است و -v یک گزینه بدون مقدار است.
  • OPTARG متغیر ویژه‌ای است که مقدار آرگومان پس از گزینه را ذخیره می‌کند.

مثال اجرا:

$ ./script.sh -f file.txt -v
Option -f was triggered with value: file.txt
Option -v was triggered

جمع‌بندی

در این بخش، نحوه پردازش آرگومان‌های ورودی اسکریپت شل را بررسی کردیم. شما می‌توانید با استفاده از متغیرهایی مانند $1, $2, $#, $@, و $* به آرگومان‌ها دسترسی پیدا کرده و آن‌ها را پردازش کنید. همچنین با استفاده از دستورات شرطی، حلقه‌ها و دستور getopts می‌توانید رفتار اسکریپت را بسته به آرگومان‌های ورودی کنترل کنید. این ویژگی‌ها به شما امکان می‌دهند که اسکریپت‌های قدرتمند و انعطاف‌پذیر ایجاد کنید که قادر به پردازش ورودی‌های مختلف باشند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از getopts برای مدیریت آرگومان‌ها” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، گاهی نیاز دارید که آرگومان‌های ورودی را به شکل‌های مختلفی پردازش کنید، به ویژه زمانی که آرگومان‌ها شامل گزینه‌های خاص (مانند -f یا -v) باشند. دستور getopts یکی از ابزارهای قدرتمند برای پردازش آرگومان‌ها در این شرایط است.

getopts به شما این امکان را می‌دهد که آرگومان‌ها را به صورت گزینه‌های کوتاه (مثل -f) یا با مقادیر مربوطه (مثل -f filename) پردازش کنید. این دستور به طور خودکار ورودی‌های نادرست یا گزینه‌های غیراستاندارد را مدیریت می‌کند و امکان ارائه دستورالعمل‌های واضح برای کاربر فراهم می‌آورد.


۱. ساختار دستور getopts

ساختار اصلی دستور getopts به این صورت است:

getopts option_string variable
  • option_string: رشته‌ای از کاراکترها که مشخص‌کننده گزینه‌های موردنظر است.
    • اگر گزینه نیاز به مقدار داشته باشد، بلافاصله بعد از آن باید دو نقطه : قرار داده شود. به عنوان مثال، f: به این معناست که گزینه -f باید یک مقدار (مانند یک نام فایل) داشته باشد.
    • اگر گزینه نیازی به مقدار نداشته باشد، تنها یک کاراکتر کافی است.
  • variable: نام متغیری که مقدار گزینه‌های دریافت شده در آن ذخیره می‌شود.

۲. مثال‌های عملی از استفاده getopts

۲.۱. اسکریپت ساده با استفاده از getopts

در این مثال، یک اسکریپت ساده ایجاد می‌کنیم که از دستور getopts برای پردازش گزینه‌های ورودی استفاده می‌کند. این اسکریپت گزینه‌های -f (برای دریافت فایل) و -v (برای فعال‌سازی حالت نمایش جزئیات) را مدیریت می‌کند.

#!/bin/bash

# پردازش گزینه‌های ورودی با استفاده از getopts
while getopts "f:v" opt; do
    case $opt in
        f)
            echo "Option -f triggered with value: $OPTARG"
            ;;
        v)
            echo "Option -v triggered"
            ;;
        *)
            echo "Invalid option"
            ;;
    esac
done

توضیح کد:

  • دستور getopts "f:v" به این معنی است که گزینه -f یک آرگومان می‌گیرد و گزینه -v یک گزینه بدون آرگومان است.
  • درون while، هر بار که getopts یک گزینه را پردازش می‌کند، آن را به متغیر opt می‌دهد.
  • case برای تشخیص گزینه‌ها و انجام عملیات مناسب استفاده می‌شود.
  • OPTARG برای ذخیره‌سازی مقدار مربوط به آرگومان‌های دارای مقدار (مثل -f) استفاده می‌شود.

مثال اجرا:

$ ./script.sh -f file.txt -v
Option -f triggered with value: file.txt
Option -v triggered

۲.۲. اسکریپت با چند گزینه و مقادیر مختلف

در این اسکریپت، ما می‌خواهیم دو گزینه -f و -v را مدیریت کنیم، که -f نیاز به یک فایل به عنوان ورودی دارد و -v یک گزینه اختیاری است که حالت verbose را فعال می‌کند.

#!/bin/bash

# متغیر برای ذخیره‌سازی ورودی‌های کاربر
file=""
verbose=false

# پردازش گزینه‌ها
while getopts "f:v" opt; do
    case $opt in
        f)
            file=$OPTARG  # ذخیره نام فایل
            ;;
        v)
            verbose=true  # فعال‌سازی حالت verbose
            ;;
        *)
            echo "Invalid option"
            exit 1
            ;;
    esac
done

# نمایش خروجی بسته به مقادیر گزینه‌ها
if [ "$verbose" = true ]; then
    echo "Verbose mode enabled"
fi

if [ -n "$file" ]; then
    echo "Processing file: $file"
else
    echo "No file specified"
fi

توضیح کد:

  • این اسکریپت دو گزینه را پردازش می‌کند:
    • -f که باید یک نام فایل به عنوان آرگومان داشته باشد.
    • -v که به صورت یک سوئیچ ساده است.
  • اگر -f وارد شود، نام فایل در متغیر file ذخیره می‌شود.
  • اگر -v وارد شود، متغیر verbose به true تغییر می‌کند و پیامی در مورد فعال بودن حالت verbose چاپ می‌شود.
  • سپس اسکریپت بررسی می‌کند که آیا متغیر file مقدار دارد یا نه، و پیغام مناسب را چاپ می‌کند.

مثال اجرا:

$ ./script.sh -f myfile.txt -v
Verbose mode enabled
Processing file: myfile.txt

$ ./script.sh -f myfile.txt
No file specified

۳. مدیریت آرگومان‌های ورودی نامعتبر

یکی از ویژگی‌های مفید getopts این است که به طور خودکار آرگومان‌های نامعتبر را شناسایی کرده و پیغام خطا صادر می‌کند. همچنین می‌توانیم با استفاده از case پیغام‌های خطای دلخواه را برای گزینه‌های نامعتبر ارائه دهیم.

#!/bin/bash

# پردازش گزینه‌ها
while getopts "a:b:" opt; do
    case $opt in
        a)
            echo "Option -a triggered with value: $OPTARG"
            ;;
        b)
            echo "Option -b triggered with value: $OPTARG"
            ;;
        *)
            echo "Invalid option or missing argument for $OPTARG"
            exit 1
            ;;
    esac
done

توضیح کد:

  • در این اسکریپت، -a و -b دو گزینه با آرگومان هستند.
  • اگر گزینه‌ای به صورت اشتباه یا بدون آرگومان وارد شود، دستور * درون case پیغام خطا چاپ می‌کند و اسکریپت با کد 1 پایان می‌یابد.

مثال اجرا:

$ ./script.sh -a hello -b world
Option -a triggered with value: hello
Option -b triggered with value: world

$ ./script.sh -a hello -c world
Invalid option or missing argument for c

جمع‌بندی

در این بخش، با استفاده از دستور getopts برای مدیریت آرگومان‌های ورودی آشنا شدیم. این دستور امکان پردازش گزینه‌های مختلف با و بدون آرگومان را فراهم می‌کند و می‌تواند ورودی‌های نامعتبر را شناسایی کرده و پیغام‌های مناسب را به کاربر نمایش دهد. با استفاده از getopts می‌توان اسکریپت‌هایی نوشت که رفتارشان بسته به گزینه‌های ورودی تغییر کند و به راحتی از ورودی‌های مختلف پشتیبانی کنند.

از getopts می‌توان در اسکریپت‌های پیچیده برای پردازش گزینه‌ها و آرگومان‌ها استفاده کرد و در نهایت به اسکریپت‌های انعطاف‌پذیرتر و کاربرپسندتری دست یافت.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف فلگ‌ها (Flags) مختلف برای اسکریپت‌ها” subtitle=”توضیحات کامل”]فلگ‌ها (Flags) یکی از اجزای رایج در اسکریپت‌ها هستند که به طور معمول برای فعال یا غیرفعال کردن ویژگی‌های خاصی در هنگام اجرای اسکریپت‌ها به کار می‌روند. این فلگ‌ها به عنوان آرگومان‌هایی که همراه با گزینه‌های مختلف وارد می‌شوند، می‌توانند رفتار اسکریپت‌ها را در شرایط مختلف تغییر دهند. به طور کلی، فلگ‌ها معمولاً به صورت یک حرف یا یک کلمه مخفف نشان داده می‌شوند که به یک ویژگی یا گزینه خاص اشاره دارند.

۱. ساختار فلگ‌ها در اسکریپت‌ها

فلگ‌ها معمولاً به دو صورت در اسکریپت‌ها مورد استفاده قرار می‌گیرند:

  1. فلگ‌های بدون نیاز به آرگومان: در این نوع فلگ‌ها نیازی به دریافت مقداری (آرگومان) اضافی وجود ندارد. تنها به صورت یک سوئیچ برای فعال یا غیرفعال کردن یک ویژگی مورد استفاده قرار می‌گیرند.
    • مثال: -v (نمایش جزئیات بیشتر)، -h (نمایش راهنما).
  2. فلگ‌های با آرگومان: این فلگ‌ها نیاز به دریافت مقداری به عنوان آرگومان دارند.
    • مثال: -f filename (جایی که -f به معنای دریافت یک نام فایل است).

۲. ایجاد فلگ‌های مختلف در اسکریپت‌ها با استفاده از getopts

دستور getopts ابزاری برای مدیریت فلگ‌ها و آرگومان‌های ورودی در شل اسکریپت‌ها است. این دستور به شما کمک می‌کند تا فلگ‌های مختلف را در اسکریپت‌ها مدیریت کنید و به طور خودکار از ورودی‌های نامعتبر جلوگیری کنید.

مثال ۱: استفاده از فلگ‌ها بدون آرگومان

در این مثال، از فلگ‌های -v و -h استفاده خواهیم کرد. فلگ -v برای فعال کردن حالت verbose و فلگ -h برای نمایش راهنما است.

#!/bin/bash

# پردازش گزینه‌ها
while getopts "vh" opt; do
    case $opt in
        v)
            echo "Verbose mode enabled"
            ;;
        h)
            echo "Usage: $0 [-v] [-h]"
            exit 0
            ;;
        *)
            echo "Invalid option"
            exit 1
            ;;
    esac
done

توضیحات کد:

  • -v یک فلگ بدون آرگومان است که اگر کاربر آن را وارد کند، حالت verbose فعال می‌شود و پیامی نمایش داده می‌شود.
  • -h یک فلگ بدون آرگومان است که زمانی که وارد شود، راهنمای ساده‌ای از نحوه استفاده از اسکریپت نمایش داده می‌شود.
  • اگر هیچ‌کدام از این دو فلگ وارد نشوند یا فلگ نادرست وارد شود، پیغام خطای مناسبی چاپ می‌شود.

اجرای مثال:

$ ./script.sh -v
Verbose mode enabled

$ ./script.sh -h
Usage: ./script.sh [-v] [-h]

مثال ۲: استفاده از فلگ‌ها با آرگومان

در این مثال، فلگ -f برای دریافت نام فایل و فلگ -v برای فعال‌سازی حالت verbose استفاده می‌شود.

#!/bin/bash

# پردازش گزینه‌ها
while getopts "f:v" opt; do
    case $opt in
        f)
            file=$OPTARG
            echo "File selected: $file"
            ;;
        v)
            verbose=true
            echo "Verbose mode enabled"
            ;;
        *)
            echo "Usage: $0 [-f filename] [-v]"
            exit 1
            ;;
    esac
done

توضیحات کد:

  • فلگ -f نیاز به دریافت یک نام فایل دارد که در متغیر file ذخیره می‌شود.
  • فلگ -v یک سوئیچ ساده است که اگر وارد شود، حالت verbose فعال می‌شود.
  • اگر هیچ‌کدام از گزینه‌های معتبر وارد نشوند یا گزینه‌های نامعتبر وارد شوند، راهنمای استفاده از اسکریپت چاپ می‌شود.

اجرای مثال:

$ ./script.sh -f myfile.txt -v
File selected: myfile.txt
Verbose mode enabled

$ ./script.sh -f myfile.txt
File selected: myfile.txt

۳. مدیریت چندین فلگ به طور همزمان

شما می‌توانید چندین فلگ را به طور همزمان در یک خط دستور وارد کنید. برای این کار باید مطمئن شوید که گزینه‌ها به درستی پردازش می‌شوند و هر یک از آنها به درستی در اسکریپت شما مورد استفاده قرار می‌گیرند.

#!/bin/bash

# پردازش گزینه‌ها
while getopts "f:v:h" opt; do
    case $opt in
        f)
            file=$OPTARG
            echo "File selected: $file"
            ;;
        v)
            verbose=true
            echo "Verbose mode enabled"
            ;;
        h)
            echo "Usage: $0 [-f filename] [-v] [-h]"
            exit 0
            ;;
        *)
            echo "Invalid option"
            exit 1
            ;;
    esac
done

اجرای مثال:

$ ./script.sh -f file.txt -v
File selected: file.txt
Verbose mode enabled

$ ./script.sh -h
Usage: ./script.sh [-f filename] [-v] [-h]

جمع‌بندی

در این بخش، با استفاده از فلگ‌ها (flags) در شل اسکریپت‌ها آشنا شدیم. فلگ‌ها معمولاً برای فعال یا غیرفعال کردن ویژگی‌ها و پارامترهای خاص در اسکریپت‌ها استفاده می‌شوند. شما می‌توانید فلگ‌ها را با و بدون آرگومان‌ها تعریف کنید و با استفاده از دستور getopts آنها را پردازش کنید.

  • فلگ‌ها می‌توانند باعث افزایش قابلیت انعطاف‌پذیری اسکریپت‌ها شوند.
  • با استفاده از دستور getopts می‌توانید مدیریت بهتری بر روی ورودی‌های نامعتبر داشته باشید و تجربه بهتری برای کاربران فراهم کنید.
  • فلگ‌ها معمولاً برای اسکریپت‌های اتوماسیون و مدیریت سیستم‌ها بسیار مفید هستند.

این روش‌ها به شما این امکان را می‌دهند که اسکریپت‌هایی بنویسید که به راحتی توسط کاربران با نیازهای مختلف قابل پیکربندی باشند و امکانات مختلفی را از طریق آرگومان‌های ورودی فعال یا غیرفعال کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نمایش پیام‌های راهنما (Help) با آرگومان –help” subtitle=”توضیحات کامل”]در بسیاری از اسکریپت‌ها و برنامه‌ها، پیامی به نام “راهنما” یا “help” وجود دارد که برای اطلاع‌رسانی به کاربران در مورد نحوه استفاده از اسکریپت یا برنامه به کار می‌رود. این پیام‌ها معمولاً اطلاعاتی در مورد گزینه‌های قابل استفاده، آرگومان‌ها، و نحوه اجرای صحیح برنامه را نمایش می‌دهند.

در شل اسکریپت‌ها، نمایش پیام‌های راهنما می‌تواند به سادگی از طریق چک کردن آرگومان ورودی --help انجام شود. در این بخش، نحوه نمایش پیام‌های راهنما در اسکریپت‌ها با استفاده از آرگومان --help بررسی خواهد شد.

۱. نحوه شناسایی ورودی –help

برای شناسایی ورودی --help و نمایش پیام راهنما به کاربر، می‌توانید از دستور if برای بررسی این ورودی در هنگام اجرای اسکریپت استفاده کنید. زمانی که --help وارد شود، باید یک پیام راهنما نمایش داده شود که اطلاعاتی درباره نحوه استفاده از اسکریپت و آرگومان‌های آن ارائه دهد.

۲. مثال از اسکریپت با آرگومان –help

در این مثال، اسکریپت به گونه‌ای نوشته شده که اگر آرگومان --help وارد شود، پیام راهنما نمایش داده می‌شود. همچنین، اگر آرگومان‌های دیگری وارد شوند، اسکریپت باید طبق دستورالعمل‌های مشخص شده عمل کند.

#!/bin/bash

# تابع نمایش پیام راهنما
function show_help {
    echo "Usage: $0 [options]"
    echo ""
    echo "Options:"
    echo "  -h, --help     Show this help message"
    echo "  -f FILE        Specify a file"
    echo "  -v             Enable verbose mode"
}

# بررسی آرگومان‌های ورودی
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
    show_help
    exit 0
fi

# پردازش دیگر گزینه‌ها
while getopts "f:v" opt; do
    case $opt in
        f)
            file=$OPTARG
            echo "File specified: $file"
            ;;
        v)
            echo "Verbose mode enabled"
            ;;
        *)
            echo "Invalid option"
            show_help
            exit 1
            ;;
    esac
done

۳. توضیحات کد

  • تابع show_help: این تابع پیامی را که حاوی نحوه استفاده از اسکریپت است، چاپ می‌کند. در این پیام، توضیحات مربوط به گزینه‌های مختلف ورودی (آرگومان‌ها) به نمایش درمی‌آید.
    • -h یا --help: به کاربر امکان نمایش پیام راهنما را می‌دهد.
    • -f FILE: به کاربر امکان تعیین یک فایل خاص را می‌دهد.
    • -v: به کاربر این امکان را می‌دهد که حالت verbose (جزئیات بیشتر) را فعال کند.
  • بررسی ورودی --help یا -h: در ابتدای اسکریپت، با استفاده از دستور if بررسی می‌شود که آیا آرگومان ورودی برابر با --help یا -h است یا خیر. اگر چنین باشد، تابع show_help فراخوانی می‌شود و اسکریپت خاتمه می‌یابد.
  • پردازش دیگر گزینه‌ها: در صورتی که --help وارد نشده باشد، اسکریپت وارد مرحله پردازش آرگومان‌ها می‌شود و با استفاده از دستور getopts گزینه‌های مختلف اسکریپت را پردازش می‌کند.

۴. اجرای اسکریپت

  • برای نمایش راهنما:
$ ./script.sh --help
Usage: ./script.sh [options]

Options:
  -h, --help     Show this help message
  -f FILE        Specify a file
  -v             Enable verbose mode
  • برای استفاده از دیگر گزینه‌ها:
$ ./script.sh -f myfile.txt -v
File specified: myfile.txt
Verbose mode enabled

جمع‌بندی

در این بخش، روش نمایش پیام‌های راهنما در اسکریپت‌ها با استفاده از آرگومان --help بررسی شد. زمانی که کاربر آرگومان --help را وارد می‌کند، اسکریپت به طور خودکار پیام راهنما را نمایش می‌دهد که اطلاعات مربوط به نحوه استفاده از اسکریپت و گزینه‌های مختلف آن را توضیح می‌دهد. استفاده از این روش برای اطلاع‌رسانی به کاربران در اسکریپت‌ها بسیار مفید است و از سردرگمی آنها جلوگیری می‌کند.

این روش به شما امکان می‌دهد تا اسکریپت‌های خود را برای کاربران قابل استفاده‌تر و منعطف‌تر کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 9. کاربردهای عملی توابع و آرگومان‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نوشتن توابع عمومی برای اجرای دستورات متداول” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، یکی از بهترین روش‌ها برای بهبود خوانایی، سازماندهی و استفاده مجدد از کد، نوشتن توابع عمومی برای دستورات متداول است. با این روش می‌توان کدهای تکراری را کاهش داد و امکان استفاده مجدد از آنها را در بخش‌های مختلف اسکریپت فراهم کرد. به طور کلی، توابع عمومی ابزارهای مفیدی برای انجام عملیات متداول مانند دستورات فایل، مدیریت ورودی/خروجی، بررسی وضعیت‌ها، و غیره هستند.

1. تعریف توابع عمومی

توابع عمومی معمولاً شامل دستورات ساده و کاربردی هستند که در بخش‌های مختلف اسکریپت برای انجام وظایف تکراری استفاده می‌شوند. به طور کلی، توابع عمومی در شل به شکل زیر تعریف می‌شوند:

function function_name {
    # دستورات داخل تابع
}

یا بدون استفاده از کلمه کلیدی function:

function_name() {
    # دستورات داخل تابع
}

2. نوشتن توابع عمومی برای دستورات متداول

در این بخش، چندین مثال از توابع عمومی برای انجام دستورات متداول ارائه خواهیم داد که می‌توانند در اسکریپت‌های شل به کار گرفته شوند.

3. مثال 1: تابعی برای بررسی وجود فایل

گاهی نیاز داریم که بررسی کنیم آیا یک فایل خاص وجود دارد یا خیر. این کار را می‌توانیم با استفاده از یک تابع عمومی انجام دهیم:

# تابع بررسی وجود فایل
file_exists() {
    if [ -e "$1" ]; then
        echo "File '$1' exists."
    else
        echo "File '$1' does not exist."
    fi
}

در این مثال، تابع file_exists بررسی می‌کند که آیا فایلی با نام داده‌شده به عنوان ورودی ($1) وجود دارد یا خیر. اگر فایل وجود داشته باشد، پیامی مبنی بر وجود فایل چاپ می‌شود و در غیر این صورت، پیامی مبنی بر عدم وجود فایل نمایش داده می‌شود.

4. مثال 2: تابعی برای چاپ تاریخ و زمان

یک تابع عمومی دیگر می‌تواند برای چاپ تاریخ و زمان جاری استفاده شود. این تابع می‌تواند در هر جایی که نیاز به تاریخ و زمان است فراخوانی شود.

# تابع چاپ تاریخ و زمان
print_datetime() {
    echo "Current date and time: $(date)"
}

تابع print_datetime به سادگی از دستور date برای چاپ تاریخ و زمان جاری استفاده می‌کند. این تابع می‌تواند در هر جایی که نیاز به نمایش تاریخ و زمان داریم، فراخوانی شود.

5. مثال 3: تابعی برای کپی کردن فایل‌ها

توابع عمومی می‌توانند کارهای پیچیده‌تری را نیز انجام دهند. در این مثال، یک تابع عمومی برای کپی کردن فایل‌ها ایجاد می‌کنیم:

# تابع کپی فایل
copy_file() {
    if [ -e "$1" ]; then
        cp "$1" "$2"
        echo "File '$1' copied to '$2'."
    else
        echo "File '$1' does not exist, cannot copy."
    fi
}

این تابع دو آرگومان دریافت می‌کند: فایل مبدا (که باید کپی شود) و مقصد (که فایل در آنجا کپی خواهد شد). ابتدا بررسی می‌شود که آیا فایل مبدا وجود دارد یا نه. اگر فایل وجود داشته باشد، با استفاده از دستور cp آن را کپی کرده و پیامی نمایش می‌دهد. در غیر این صورت، پیامی مبنی بر عدم وجود فایل نمایش داده می‌شود.

6. مثال 4: تابعی برای بررسی دسترسی به فایل

در برخی اسکریپت‌ها ممکن است بخواهیم بررسی کنیم که آیا دسترسی لازم به یک فایل خاص وجود دارد یا خیر. برای این منظور می‌توانیم از یک تابع عمومی استفاده کنیم:

# تابع بررسی دسترسی فایل
check_file_permission() {
    if [ -r "$1" ]; then
        echo "File '$1' is readable."
    else
        echo "File '$1' is not readable."
    fi

    if [ -w "$1" ]; then
        echo "File '$1' is writable."
    else
        echo "File '$1' is not writable."
    fi

    if [ -x "$1" ]; then
        echo "File '$1' is executable."
    else
        echo "File '$1' is not executable."
    fi
}

در این مثال، تابع check_file_permission بررسی می‌کند که آیا فایل دارای مجوز خواندن (-r)، نوشتن (-w)، و اجرا (-x) است. این تابع می‌تواند برای بررسی دسترسی به فایل‌ها مفید باشد.

7. مثال 5: تابعی برای ایجاد دایرکتوری

گاهی نیاز داریم که دایرکتوری جدیدی ایجاد کنیم، در اینجا یک تابع عمومی برای این کار نوشته‌ایم:

# تابع ایجاد دایرکتوری
create_directory() {
    if [ ! -d "$1" ]; then
        mkdir -p "$1"
        echo "Directory '$1' created."
    else
        echo "Directory '$1' already exists."
    fi
}

تابع create_directory بررسی می‌کند که آیا دایرکتوری مورد نظر وجود دارد یا نه. اگر وجود نداشته باشد، آن را با استفاده از دستور mkdir -p ایجاد می‌کند. در غیر این صورت، پیامی مبنی بر وجود دایرکتوری چاپ می‌شود.

8. استفاده از توابع عمومی در اسکریپت‌ها

پس از نوشتن توابع عمومی، می‌توان آنها را در هر جایی از اسکریپت فراخوانی کرد. به عنوان مثال، یک اسکریپت ساده که از این توابع استفاده می‌کند می‌تواند به شکل زیر باشد:

#!/bin/bash

# فراخوانی توابع
file_exists "example.txt"
print_datetime
copy_file "example.txt" "/tmp/example_copy.txt"
check_file_permission "example.txt"
create_directory "/tmp/new_directory"

جمع‌بندی

در این بخش، توابع عمومی برای انجام دستورات متداول در اسکریپت‌های شل معرفی شدند. توابع عمومی می‌توانند در اسکریپت‌های شل به شما کمک کنند تا کدهای تکراری را کاهش داده، قابلیت استفاده مجدد از کد را فراهم کنید و ساختار اسکریپت‌ها را تمیزتر و قابل خواندن‌تر کنید. این توابع می‌توانند وظایف مختلفی را انجام دهند، از جمله بررسی وجود فایل، کپی کردن فایل‌ها، بررسی دسترسی به فایل‌ها، ایجاد دایرکتوری‌ها و نمایش تاریخ و زمان جاری.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نوشتن توابع برای پردازش فایل‌ها و داده‌ها” subtitle=”توضیحات کامل”]در اسکریپت‌نویسی شل، یکی از مهم‌ترین کارهایی که ممکن است بخواهید انجام دهید پردازش فایل‌ها و داده‌ها است. برای این منظور، نوشتن توابعی که وظایف پردازش فایل را به‌طور خودکار و بدون نیاز به کدنویسی مکرر انجام دهند، مفید است. این توابع می‌توانند برای کارهایی مانند خواندن، نوشتن، و ویرایش داده‌ها در فایل‌ها، تجزیه و تحلیل محتوای فایل‌ها و موارد مشابه استفاده شوند.

در این بخش، نحوه نوشتن توابعی برای پردازش فایل‌ها و داده‌ها در اسکریپت‌های شل با استفاده از دستوراتی مانند cat, grep, awk, sed, و غیره توضیح داده خواهد شد.


1. نوشتن تابع برای خواندن محتویات یک فایل

اولین مرحله در پردازش فایل‌ها، خواندن محتوای آن‌ها است. برای این کار، می‌توانیم از دستور cat یا دستورات دیگری مانند head و tail استفاده کنیم. در اینجا یک تابع عمومی برای خواندن محتوای یک فایل و چاپ آن ایجاد می‌کنیم:

# تابع خواندن محتوای فایل
read_file() {
    if [ -e "$1" ]; then
        cat "$1"
    else
        echo "File '$1' does not exist."
    fi
}

در این مثال، تابع read_file بررسی می‌کند که آیا فایل مورد نظر وجود دارد یا خیر. اگر فایل وجود داشته باشد، از دستور cat برای چاپ محتویات آن استفاده می‌کند. در غیر این صورت، پیامی مبنی بر عدم وجود فایل نمایش داده می‌شود.


2. نوشتن تابع برای جستجوی یک کلمه در فایل

گاهی اوقات ممکن است بخواهید در یک فایل به جستجوی کلمات خاصی بپردازید. برای این کار می‌توانیم از دستور grep استفاده کنیم. در اینجا یک تابع عمومی برای جستجوی کلمه در فایل آورده شده است:

# تابع جستجوی کلمه در فایل
search_in_file() {
    if [ -e "$1" ]; then
        grep -i "$2" "$1"
    else
        echo "File '$1' does not exist."
    fi
}

تابع search_in_file دو آرگومان می‌گیرد: اولین آرگومان مسیر فایل و دومین آرگومان کلمه‌ای است که می‌خواهید در آن فایل جستجو کنید. دستور grep با استفاده از گزینه -i (که جستجو را غیر حساس به حروف بزرگ و کوچک می‌کند) در فایل جستجو کرده و نتایج را چاپ می‌کند.


3. نوشتن تابع برای شمارش خطوط یک فایل

در بسیاری از مواقع، ممکن است بخواهید تعداد خطوط یک فایل را بشمارید. این کار را می‌توان با استفاده از دستور wc -l انجام داد. در اینجا یک تابع برای شمارش خطوط فایل آورده شده است:

# تابع شمارش خطوط فایل
count_lines() {
    if [ -e "$1" ]; then
        wc -l < "$1"
    else
        echo "File '$1' does not exist."
    fi
}

تابع count_lines از دستور wc -l برای شمارش تعداد خطوط در یک فایل استفاده می‌کند. اگر فایل وجود داشته باشد، تعداد خطوط چاپ می‌شود و در غیر این صورت، پیامی مبنی بر عدم وجود فایل نمایش داده می‌شود.


4. نوشتن تابع برای استخراج داده‌ها با استفاده از awk

گاهی نیاز داریم که داده‌ها را از یک فایل به‌طور خاص استخراج کنیم. ابزار awk به ما این امکان را می‌دهد که داده‌ها را براساس الگوهای خاص جدا کنیم و آن‌ها را نمایش دهیم. در اینجا یک تابع عمومی برای استخراج داده‌ها از یک فایل آورده شده است:

# تابع استخراج داده‌ها با استفاده از awk
extract_column() {
    if [ -e "$1" ]; then
        awk "{print \$$2}" "$1"
    else
        echo "File '$1' does not exist."
    fi
}

تابع extract_column دو آرگومان می‌گیرد: اولین آرگومان مسیر فایل و دومین آرگومان شماره ستونی است که می‌خواهید داده‌های آن را استخراج کنید. از دستور awk برای استخراج و نمایش ستون مورد نظر استفاده می‌شود.


5. نوشتن تابع برای جایگزینی داده‌ها با استفاده از sed

در برخی مواقع ممکن است بخواهید داده‌ها را در فایل ویرایش کنید. ابزار sed برای انجام این کار مفید است. در اینجا یک تابع برای جایگزینی یک کلمه در فایل با استفاده از sed آورده شده است:

# تابع جایگزینی داده‌ها با sed
replace_text() {
    if [ -e "$1" ]; then
        sed -i "s/$2/$3/g" "$1"
        echo "Replaced '$2' with '$3' in '$1'."
    else
        echo "File '$1' does not exist."
    fi
}

تابع replace_text سه آرگومان می‌گیرد: مسیر فایل، کلمه‌ای که باید جایگزین شود، و کلمه جدیدی که باید جایگزین آن گردد. از دستور sed -i برای انجام این جایگزینی به صورت درون‌خطی استفاده می‌شود.


6. نوشتن تابع برای ذخیره داده‌ها در یک فایل جدید

اگر بخواهید داده‌ها را در یک فایل جدید ذخیره کنید، می‌توانید از دستور echo یا cat استفاده کنید. در اینجا یک تابع برای ذخیره داده‌ها در یک فایل آورده شده است:

# تابع ذخیره داده‌ها در فایل
save_to_file() {
    echo "$2" > "$1"
    echo "Data saved to '$1'."
}

تابع save_to_file دو آرگومان می‌گیرد: اولین آرگومان مسیر فایل و دومین آرگومان داده‌هایی است که باید در فایل ذخیره شوند. از دستور echo برای ذخیره داده‌ها در فایل استفاده می‌شود.


7. نوشتن تابع برای فشرده‌سازی فایل‌ها

در برخی مواقع ممکن است بخواهید فایل‌ها را فشرده کنید. این کار را می‌توان با استفاده از دستور gzip یا tar انجام داد. در اینجا یک تابع برای فشرده‌سازی فایل‌ها آورده شده است:

# تابع فشرده‌سازی فایل
compress_file() {
    if [ -e "$1" ]; then
        gzip "$1"
        echo "File '$1' compressed."
    else
        echo "File '$1' does not exist."
    fi
}

تابع compress_file بررسی می‌کند که آیا فایل وجود دارد یا خیر. اگر فایل وجود داشته باشد، از دستور gzip برای فشرده‌سازی آن استفاده می‌شود.


جمع‌بندی

در این بخش توابع مختلفی برای پردازش فایل‌ها و داده‌ها در اسکریپت‌های شل معرفی شد. این توابع شامل خواندن فایل، جستجوی کلمات در فایل‌ها، شمارش خطوط، استخراج داده‌ها از فایل‌ها، ویرایش محتویات فایل‌ها، ذخیره داده‌ها در فایل‌ها و فشرده‌سازی فایل‌ها می‌شوند. با استفاده از این توابع می‌توان پردازش فایل‌ها و داده‌ها را به طور خودکار و مؤثر انجام داد و اسکریپت‌ها را کارآمدتر و سازمان‌یافته‌تر کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”طراحی توابع برای مدیریت خطاها و گزارش‌دهی” subtitle=”توضیحات کامل”]در هنگام نوشتن اسکریپت‌ها، یکی از بخش‌های مهم و ضروری، مدیریت خطاها و گزارش‌دهی است. در پروژه‌های واقعی، به ویژه وقتی که با فایل‌ها، ورودی‌های کاربر و سیستم‌های مختلف کار می‌کنیم، احتمال بروز خطاها و مشکلات بسیار زیاد است. بنابراین، داشتن راهکارهایی برای شناسایی، مدیریت و گزارش خطاها به‌طور صحیح، می‌تواند اسکریپت‌ها را پایدارتر و قابل اعتمادتر کند.

در این بخش، نحوه طراحی توابع برای مدیریت خطاها و گزارش‌دهی در اسکریپت‌های شل را بررسی خواهیم کرد. این توابع به شما کمک می‌کنند تا هنگام بروز خطا، اسکریپت را به درستی متوقف کنید یا پیغام‌های مفیدی به کاربر ارسال کنید.


1. بررسی کد خروجی دستورات با $?

اولین قدم برای مدیریت خطاها، بررسی وضعیت اجرای دستورات است. در شل، کد خروجی هر دستور می‌تواند به‌طور مؤثر نشان‌دهنده موفقیت یا شکست آن دستور باشد. کد خروجی 0 به معنای موفقیت و کدهای غیر صفر نشان‌دهنده بروز خطا است. می‌توانیم از $? برای بررسی کد خروجی دستور قبلی استفاده کنیم.

# تابع برای بررسی خطا و گزارش آن
check_command_status() {
    if [ $? -ne 0 ]; then
        echo "Error: Command failed with exit code $?."
        exit 1
    fi
}

در این مثال، تابع check_command_status بررسی می‌کند که آیا دستور قبلی با کد خروجی غیر صفر تمام شده است یا خیر. اگر این‌گونه باشد، پیغامی مبنی بر بروز خطا چاپ کرده و اسکریپت را با کد خروجی 1 متوقف می‌کند.


2. گزارش خطاها به فایل لاگ

گاهی اوقات مفید است که خطاها را به‌جای چاپ در کنسول، در یک فایل لاگ ذخیره کنیم. این کار می‌تواند برای بررسی خطاها در آینده یا برای تحلیل‌های بیشتر مفید باشد. برای این کار، می‌توانیم یک تابع بنویسیم که خطاها را به یک فایل لاگ ارسال کند.

# تابع گزارش خطاها در فایل لاگ
log_error() {
    local error_message="$1"
    local log_file="error.log"
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: $error_message" >> "$log_file"
}

در اینجا، تابع log_error پیغام خطا را همراه با تاریخ و زمان جاری در فایل error.log ذخیره می‌کند. هر بار که این تابع فراخوانی شود، پیغام خطا در فایل لاگ به‌صورت افزایشی ذخیره می‌شود.


3. استفاده از trap برای مدیریت خطاهای سیگنال‌ها

گاهی اوقات ممکن است اسکریپت‌ها به‌طور غیرمنتظره‌ای با سیگنال‌هایی مثل SIGINT (قطع دستور با Ctrl+C) یا SIGTERM (دستور خاتمه) خاتمه یابند. برای مدیریت این‌گونه خطاها و انجام کارهای لازم مانند پاکسازی منابع یا گزارش خطا، می‌توان از دستور trap استفاده کرد.

# تابع مدیریت سیگنال‌ها
trap_error() {
    echo "Script terminated unexpectedly. Cleaning up resources..."
    log_error "Script terminated unexpectedly."
    exit 1
}

# فعال‌سازی trap برای سیگنال‌های مختلف
trap trap_error SIGINT SIGTERM

در اینجا، از دستور trap برای گوش دادن به سیگنال‌های SIGINT و SIGTERM استفاده می‌شود. اگر یکی از این سیگنال‌ها ارسال شود، تابع trap_error اجرا می‌شود که پیغام خطا را چاپ کرده و خطای مربوطه را در فایل لاگ ذخیره می‌کند.


4. بررسی ورودی‌های کاربر با read و مدیریت خطا

در بسیاری از اسکریپت‌ها نیاز است که ورودی‌هایی از کاربر گرفته شود. اگر ورودی اشتباه باشد، اسکریپت باید آن را شناسایی کرده و از انجام عملیات ادامه‌دار جلوگیری کند. در اینجا مثالی برای مدیریت ورودی‌های نامعتبر آورده شده است:

# تابع برای گرفتن ورودی صحیح از کاربر
get_user_input() {
    local prompt="$1"
    local input

    echo "$prompt"
    read input

    # بررسی اینکه ورودی خالی نباشد
    if [ -z "$input" ]; then
        echo "Error: Input cannot be empty."
        log_error "User provided empty input."
        exit 1
    fi

    echo "User input: $input"
}

# استفاده از تابع
get_user_input "Please enter a valid value:"

در اینجا، تابع get_user_input از کاربر یک ورودی می‌گیرد. اگر ورودی خالی باشد، اسکریپت پیغام خطا چاپ کرده و خطا را در فایل لاگ ذخیره کرده و سپس اسکریپت را متوقف می‌کند.


5. استفاده از توابع برای مدیریت خطا در پردازش فایل‌ها

در هنگام پردازش فایل‌ها، بروز خطاهایی مانند عدم وجود فایل، دسترسی محدود به فایل یا دیگر مشکلات رایج ممکن است اتفاق بیفتد. در اینجا، تابعی برای بررسی خطاهای مرتبط با فایل‌ها نوشته شده است:

# تابع بررسی وجود فایل
check_file_exists() {
    if [ ! -e "$1" ]; then
        echo "Error: File '$1' does not exist."
        log_error "File '$1' does not exist."
        exit 1
    fi
}

# استفاده از تابع
check_file_exists "/path/to/file.txt"

تابع check_file_exists بررسی می‌کند که آیا فایل مورد نظر وجود دارد یا خیر. اگر فایل وجود نداشته باشد، پیغام خطا چاپ می‌شود و خطا در فایل لاگ ذخیره می‌شود.


6. پیغام‌های خطا با استفاده از echo و exit

یکی از ساده‌ترین روش‌ها برای مدیریت خطاها، چاپ پیغام خطا با استفاده از دستور echo و استفاده از دستور exit برای متوقف کردن اسکریپت است.

# تابع گزارش خطا و خاتمه اسکریپت
handle_error() {
    local error_message="$1"
    echo "ERROR: $error_message"
    exit 1
}

# استفاده از تابع
handle_error "Something went wrong!"

در اینجا، تابع handle_error پیغام خطا را به کاربر نمایش می‌دهد و سپس اسکریپت را با استفاده از دستور exit متوقف می‌کند.


جمع‌بندی

در این بخش، نحوه طراحی توابع برای مدیریت خطاها و گزارش‌دهی در اسکریپت‌های شل بررسی شد. استفاده از دستورات مختلف مانند $? برای بررسی وضعیت دستورات، trap برای مدیریت سیگنال‌ها، و توابعی برای گزارش خطا به فایل لاگ از جمله مهم‌ترین روش‌ها برای مدیریت خطاها است. همچنین، طراحی توابعی برای بررسی ورودی‌های کاربر و پردازش فایل‌ها به‌صورت ایمن و مدیریت خطاهای مرتبط با آن‌ها نیز به اسکریپت‌ها کمک می‌کند که پایدارتر و قابل اعتمادتر شوند.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش 7. ورودی و خروجی در شل”][cdb_course_lesson title=”فصل 1. خواندن ورودی از کاربر”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از دستور read برای گرفتن ورودی از کاربر” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، گاهی نیاز است که ورودی‌هایی از کاربر دریافت کنیم. برای این کار، دستور read به‌عنوان یکی از ابزارهای اصلی برای دریافت ورودی از کاربران در اسکریپت‌های شل مورد استفاده قرار می‌گیرد. دستور read به شما این امکان را می‌دهد که ورودی کاربر را ذخیره کرده و از آن در اسکریپت خود استفاده کنید.

در این بخش، به‌طور جامع و عملی به نحوه استفاده از دستور read برای دریافت ورودی از کاربر خواهیم پرداخت و با مثال‌هایی نحوه کارکرد آن را توضیح خواهیم داد.


1. نحوه استفاده از دستور read

دستور read به‌صورت ساده به شکل زیر استفاده می‌شود:

read variable_name

در این حالت، دستور read از کاربر ورودی می‌گیرد و آن را در متغیر variable_name ذخیره می‌کند.

مثال ساده:

#!/bin/bash
echo "Enter your name:"
read name
echo "Hello, $name!"

در این اسکریپت، ابتدا از کاربر خواسته می‌شود که نام خود را وارد کند. سپس، ورودی کاربر در متغیر name ذخیره شده و در نهایت، نام کاربر چاپ می‌شود.


2. استفاده از دستور read با پیغام ورودی

گاهی اوقات می‌خواهیم که دستور read همزمان با درخواست از کاربر، پیغامی برای راهنمایی به او نمایش دهد. برای این کار، می‌توانیم از پارامتر -p استفاده کنیم.

مثال:

#!/bin/bash
read -p "Enter your age: " age
echo "You are $age years old."

در این اسکریپت، پیغامی به‌صورت مستقیم قبل از گرفتن ورودی از کاربر نمایش داده می‌شود. به‌عنوان مثال، در صورتی که کاربر وارد 25 کند، خروجی به این صورت خواهد بود:

You are 25 years old.

3. استفاده از دستور read برای گرفتن چندین ورودی

دستور read به شما این امکان را می‌دهد که همزمان چندین ورودی از کاربر دریافت کنید. برای این کار، می‌توانید چندین متغیر را به‌طور همزمان در دستور read وارد کنید.

مثال:

#!/bin/bash
read -p "Enter your first name and last name: " first_name last_name
echo "Hello, $first_name $last_name!"

در اینجا، ورودی‌های کاربر به‌طور همزمان در دو متغیر مختلف ذخیره می‌شود. اگر کاربر وارد John Doe شود، خروجی به این صورت خواهد بود:

Hello, John Doe!

4. استفاده از دستور read برای محدود کردن ورودی‌ها

اگر بخواهید که ورودی کاربر باید از یک نوع خاص باشد (مثلاً یک عدد یا رشته خاص)، می‌توانید از حلقه‌ها و دستورات شرطی برای محدود کردن ورودی استفاده کنید. در این حالت، دستور read ورودی را می‌گیرد، اما اگر ورودی نامعتبر باشد، از کاربر خواسته می‌شود که ورودی دیگری وارد کند.

مثال:

#!/bin/bash
while true; do
    read -p "Enter a number between 1 and 10: " number
    if [[ "$number" -ge 1 && "$number" -le 10 ]]; then
        break
    else
        echo "Invalid input. Please enter a number between 1 and 10."
    fi
done
echo "You entered: $number"

در این اسکریپت، از کاربر خواسته می‌شود که عددی بین 1 و 10 وارد کند. اگر ورودی نامعتبر باشد، از کاربر خواسته می‌شود که ورودی جدیدی وارد کند.


5. ذخیره ورودی در آرایه‌ها با استفاده از read

دستور read می‌تواند ورودی‌ها را در آرایه‌ها ذخیره کند. برای این کار، می‌توانید از ویژگی‌های خاص شل مانند استفاده از read به‌صورت آرایه‌ای استفاده کنید.

مثال:

#!/bin/bash
read -p "Enter a list of items separated by space: " -a items
echo "You entered the following items: ${items[@]}"

در این اسکریپت، ورودی‌های کاربر که با فاصله از هم جدا شده‌اند در آرایه items ذخیره می‌شوند. به‌عنوان مثال، اگر کاربر ورودی apple banana cherry را وارد کند، خروجی به این صورت خواهد بود:

You entered the following items: apple banana cherry

6. جلوگیری از نمایش ورودی (رمز عبور)

اگر بخواهید ورودی‌هایی مانند رمز عبور را از کاربر دریافت کنید و ورودی به‌صورت مخفی (یعنی نمایش داده نشود) باشد، می‌توانید از گزینه -s در دستور read استفاده کنید.

مثال:

#!/bin/bash
read -s -p "Enter your password: " password
echo -e "\nPassword entered."

در اینجا، ورودی کاربر مخفی باقی می‌ماند و نمایش داده نمی‌شود. این قابلیت معمولاً در زمانی که می‌خواهید رمز عبور یا اطلاعات حساس دیگری را از کاربر دریافت کنید مفید است.


7. زمان محدود برای ورودی

در برخی مواقع، ممکن است بخواهید از کاربر ورودی را در مدت زمان محدودی دریافت کنید. برای این کار می‌توان از دستور timeout یا استفاده از اسکریپت‌های خاصی که ورودی را پس از مدت زمان مشخصی قطع می‌کنند استفاده کرد. دستور read به‌طور پیش‌فرض هیچ‌گونه زمان‌محدودیتی ندارد، اما با استفاده از ابزارهایی مانند timeout می‌توانید این کار را انجام دهید.

مثال:

#!/bin/bash
echo "You have 10 seconds to provide your input."
if read -t 10 -p "Enter something: " input; then
    echo "You entered: $input"
else
    echo "Time's up! You did not enter anything."
fi

در این اسکریپت، از دستور read با گزینه -t برای محدود کردن زمان ورودی به 10 ثانیه استفاده می‌شود. اگر کاربر نتواند ظرف 10 ثانیه ورودی دهد، پیغام خطا چاپ می‌شود.


جمع‌بندی

دستور read یکی از دستورات اصلی در شل است که به شما این امکان را می‌دهد که از کاربر ورودی دریافت کنید. این دستور قابلیت‌های زیادی دارد، از جمله دریافت ورودی به‌صورت مخفی، ذخیره ورودی در متغیرها و آرایه‌ها، تعیین محدودیت برای ورودی‌ها، و مدیریت ورودی‌ها با زمان محدود. در این بخش، با استفاده از مثال‌های مختلف یاد گرفتیم که چگونه از دستور read برای دریافت ورودی از کاربر در اسکریپت‌ها استفاده کنیم و آن را با روش‌های مختلف کنترل کنیم تا اسکریپت‌های شل کاربردی‌تری بسازیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تنظیم مقدار پیش‌فرض برای ورودی‌های خالی” subtitle=”توضیحات کامل”]در هنگام نوشتن اسکریپت‌های شل، معمولاً نیاز داریم که از ورودی‌های کاربر استفاده کنیم. اما ممکن است کاربر ورودی را خالی بگذارد یا هیچ مقداری وارد نکند. در اینجا می‌توانیم از روش‌هایی برای تنظیم مقدار پیش‌فرض برای چنین ورودی‌هایی استفاده کنیم. این کار به ما این امکان را می‌دهد که اسکریپت‌های ما انعطاف‌پذیرتر و مقاوم‌تر در برابر خطاهای ورودی شوند.

روش‌های تنظیم مقدار پیش‌فرض

در شل اسکریپت، برای تنظیم مقدار پیش‌فرض برای ورودی‌هایی که ممکن است خالی باشند، می‌توان از ویژگی‌های گسترش متغیرها (Variable Expansion) استفاده کرد. یکی از این ویژگی‌ها، استفاده از ${variable:-default} است که در آن مقدار پیش‌فرض برای متغیر تنظیم می‌شود.

نحوه استفاده از ${variable:-default}

اگر متغیر مورد نظر خالی یا تعریف‌نشده باشد، مقدار پیش‌فرض به آن اختصاص داده می‌شود. این روش معمولاً برای جلوگیری از ایجاد خطا هنگام استفاده از متغیرهایی که ممکن است ورودی نداشته باشند، به‌کار می‌رود.

مثال:

#!/bin/bash

echo "لطفاً نام خود را وارد کنید:"
read name

# تنظیم مقدار پیش‌فرض در صورت خالی بودن ورودی
name=${name:-"کاربر محترم"}

echo "سلام, $name!"

در این مثال، اگر کاربر هیچ مقداری وارد نکند یا ورودی خالی باشد، مقدار "کاربر محترم" به‌طور پیش‌فرض به متغیر name اختصاص داده می‌شود.

توضیح بیشتر

  • ${variable:-default}: اگر متغیر variable خالی باشد یا تعریف نشده باشد، مقدار پیش‌فرض default به آن اختصاص داده می‌شود.
  • این روش باعث می‌شود که حتی اگر کاربر هیچ مقداری وارد نکند، اسکریپت بتواند به‌طور صحیح ادامه یابد.

مثال پیشرفته‌تر

فرض کنید یک اسکریپت دارید که از کاربر دو ورودی می‌گیرد، یکی برای نام و دیگری برای سن. در صورتی که کاربر هیچ یک از این دو ورودی را وارد نکند، شما می‌خواهید از مقادیر پیش‌فرض استفاده کنید.

#!/bin/bash

# دریافت ورودی از کاربر
echo "نام خود را وارد کنید:"
read name

echo "سن خود را وارد کنید:"
read age

# تنظیم مقدار پیش‌فرض
name=${name:-"کاربر محترم"}
age=${age:-30}

echo "سلام $name! سن شما $age سال است."

در این اسکریپت:

  • اگر کاربر نام خود را وارد نکند، مقدار پیش‌فرض "کاربر محترم" به متغیر name اختصاص داده می‌شود.
  • اگر کاربر سن خود را وارد نکند، مقدار پیش‌فرض 30 به متغیر age داده می‌شود.

جمع‌بندی

در این بخش، روش‌های تنظیم مقدار پیش‌فرض برای ورودی‌های خالی در اسکریپت‌های شل را بررسی کردیم. استفاده از ${variable:-default} برای اختصاص دادن مقادیر پیش‌فرض به متغیرهای خالی یا تعریف‌نشده یک روش بسیار کارآمد است که می‌تواند به جلوگیری از بروز خطا در اسکریپت‌ها کمک کند. این تکنیک به شما این امکان را می‌دهد که اسکریپت‌هایی بنویسید که در برابر ورودی‌های غیرمنتظره یا خالی مقاوم باشند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”خواندن چندین متغیر در یک خط” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، یکی از ویژگی‌های مفید این است که می‌توانید چندین ورودی از کاربر را در یک خط دریافت کرده و آن‌ها را به متغیرهای مختلف اختصاص دهید. این کار باعث می‌شود که اسکریپت شما خواناتر و کارآمدتر باشد، مخصوصاً زمانی که نیاز به دریافت چندین ورودی مشابه دارید.

برای این کار، می‌توانید از دستور read با استفاده از جداکننده‌هایی مانند فاصله (space) یا تب (tab) برای خواندن چندین ورودی در یک خط استفاده کنید.

نحوه استفاده از دستور read برای خواندن چندین متغیر در یک خط

اگر بخواهید چندین متغیر را در یک خط بخوانید، می‌توانید از دستور read به این شکل استفاده کنید:

read var1 var2 var3

در اینجا، سه متغیر (var1, var2, var3) به ترتیب با ورودی‌های کاربر پر می‌شوند.

مثال:

در این مثال، اسکریپت از کاربر می‌خواهد که نام، سن، و شغل خود را وارد کند. همه این ورودی‌ها در یک خط گرفته می‌شوند و به متغیرهای مختلف اختصاص داده می‌شوند:

#!/bin/bash

echo "لطفاً نام، سن و شغل خود را وارد کنید (با فاصله از هم جدا کنید):"
read name age job

echo "نام: $name"
echo "سن: $age"
echo "شغل: $job"

توضیح کد:

  1. در ابتدا از کاربر خواسته می‌شود که نام، سن و شغل خود را در یک خط وارد کند.
  2. دستور read این ورودی‌ها را به سه متغیر (name, age, job) اختصاص می‌دهد.
  3. سپس مقادیر این متغیرها با استفاده از دستور echo چاپ می‌شوند.

اگر کاربر ورودی را به‌طور صحیح وارد کند (مثلاً Ali 25 Developer)، خروجی به شکل زیر خواهد بود:

نام: Ali
سن: 25
شغل: Developer

نکات مهم:

  • جداکننده‌ها در اینجا فاصله (space) هستند. بنابراین، اگر ورودی‌های کاربر با فاصله از هم جدا شوند، هر بخش به یک متغیر اختصاص داده می‌شود.
  • اگر تعداد متغیرها بیشتر از تعداد ورودی‌ها باشد، مقادیر باقی‌مانده متغیرها خالی می‌مانند.
  • در صورتی که ورودی‌ها بیش از تعداد متغیرها باشند، فقط به تعداد متغیرها ورودی اختصاص می‌یابد و باقی‌مانده نادیده گرفته می‌شود.

مثال پیشرفته‌تر:

اگر بخواهید ورودی‌ها را از کاربر به‌صورت دقیق‌تر با استفاده از دستور read پردازش کنید، می‌توانید از یک حلقه برای اطمینان از اینکه همه ورودی‌ها به درستی گرفته شده‌اند استفاده کنید. در این مثال، از کاربر خواسته می‌شود که نام، سن و شغل خود را وارد کند، اما این بار ورودی‌ها به‌طور دقیق‌تر بررسی می‌شود:

#!/bin/bash

echo "لطفاً نام، سن و شغل خود را وارد کنید (با فاصله از هم جدا کنید):"
while true; do
  read name age job
  if [[ -z "$name" || -z "$age" || -z "$job" ]]; then
    echo "لطفاً همه مقادیر را وارد کنید."
  else
    break
  fi
done

echo "نام: $name"
echo "سن: $age"
echo "شغل: $job"

در اینجا:

  • از حلقه while برای اطمینان از اینکه کاربر همه سه ورودی را وارد می‌کند، استفاده شده است.
  • اگر کاربر ورودی نادرستی وارد کند (مثلاً یکی از فیلدها خالی باشد)، دوباره از او خواسته می‌شود که ورودی‌های صحیح را وارد کند.

جمع‌بندی

در این بخش، نحوه خواندن چندین متغیر در یک خط در شل اسکریپت را بررسی کردیم. استفاده از دستور read برای دریافت ورودی‌های متعدد به‌صورت هم‌زمان به شما این امکان را می‌دهد که اسکریپت‌های خود را کارآمدتر و مختصرتر بنویسید. این روش در مواردی که نیاز به دریافت چندین پارامتر از کاربر دارید، بسیار مفید است و باعث می‌شود که اسکریپت شما انعطاف‌پذیرتر باشد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. نوشتن خروجی به کنسول یا فایل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از echo برای چاپ متن و متغیرها” subtitle=”توضیحات کامل”]دستور echo یکی از پرکاربردترین و ساده‌ترین دستورات در شل اسکریپت‌ها است که برای چاپ متن، مقادیر متغیرها، و یا ترکیب آن‌ها با هم استفاده می‌شود. این دستور به شما این امکان را می‌دهد که نتایج یا پیام‌ها را در هنگام اجرای اسکریپت به نمایش درآورید.

نحوه استفاده از echo

1. چاپ متن ساده:

برای چاپ متن ثابت در شل، می‌توانید از دستور echo به این صورت استفاده کنید:

echo "سلام، خوش آمدید!"

در این مثال، دستور echo پیام “سلام، خوش آمدید!” را در ترمینال چاپ می‌کند.

2. چاپ متغیرها:

برای چاپ مقادیر متغیرها، شما می‌توانید نام متغیر را پس از علامت $ در دستور echo قرار دهید. در این صورت مقدار متغیر چاپ خواهد شد.

مثال:
#!/bin/bash

name="علی"
echo "نام من $name است."

در این مثال، متغیر name با مقدار "علی" تعریف شده است و هنگام اجرای اسکریپت، دستور echo مقدار این متغیر را چاپ می‌کند:

نام من علی است.

3. چاپ چندین متغیر و متن در یک خط:

شما می‌توانید چندین متغیر را به همراه متن در یک خط چاپ کنید. برای این کار می‌توانید از فضای خالی (space) برای جدا کردن بخش‌های مختلف استفاده کنید.

مثال:
#!/bin/bash

name="علی"
age="25"
echo "نام: $name, سن: $age"

خروجی این اسکریپت به صورت زیر خواهد بود:

نام: علی, سن: 25

4. استفاده از چاپ متغیر در داخل متن با استفاده از “ویرگول” یا “پرانتز”:

در بعضی موارد، ممکن است نیاز داشته باشید که متغیرها را به‌صورت ترکیب‌شده با متن چاپ کنید، بدون اینکه فضای خالی یا پرانتز در چاپ وارد شود. برای این کار، می‌توانید از پرانتزهای ${} برای مشخص کردن متغیرها استفاده کنید.

مثال:
#!/bin/bash

name="علی"
echo "نام من ${name} است."

در این مثال، پرانتزهای {} به شل کمک می‌کنند تا متغیر را به‌درستی شناسایی کرده و تنها مقدار آن را چاپ کند.

5. چاپ متن چندخطی با استفاده از echo:

در صورتی که بخواهید متنی چندخطی چاپ کنید، می‌توانید از گزینه -e استفاده کنید تا امکان استفاده از کدهای خاص مانند \n برای تغییر خط (new line) فراهم شود.

مثال:
#!/bin/bash

echo -e "خط اول\nخط دوم\nخط سوم"

خروجی:

خط اول
خط دوم
خط سوم

در اینجا، دستور echo -e از کدهای خاص پشتیبانی می‌کند و باعث می‌شود که متن چاپ شده در چند خط به نمایش درآید.

6. استفاده از echo برای چاپ خروجی از دستورات:

شما می‌توانید خروجی دستورات را با استفاده از دستور echo به نمایش درآورید. برای این کار می‌توانید خروجی دستورات را در داخل یک دستور $(command) قرار دهید.

مثال:
#!/bin/bash

current_date=$(date)
echo "تاریخ و زمان فعلی: $current_date"

در اینجا، دستور $(date) تاریخ و زمان فعلی را از سیستم دریافت می‌کند و دستور echo این مقدار را چاپ می‌کند.

7. جلوگیری از ایجاد فضای اضافی در انتهای چاپ با -n:

به‌طور پیش‌فرض، دستور echo بعد از چاپ متن یک خط جدید اضافه می‌کند. اگر نخواهید این خط جدید ایجاد شود، می‌توانید از گزینه -n استفاده کنید.

مثال:
#!/bin/bash

echo -n "این متن بدون خط جدید چاپ می‌شود."

در این مثال، خروجی تنها متن خواهد بود و هیچ خط جدیدی بعد از آن ایجاد نمی‌شود.

جمع‌بندی

در این بخش، روش‌های مختلف استفاده از دستور echo برای چاپ متن و متغیرها را بررسی کردیم. دستور echo ابزار بسیار مفیدی است که در هنگام نوشتن شل اسکریپت‌ها برای نمایش پیام‌ها و مقادیر متغیرها به کار می‌رود. با استفاده از گزینه‌های مختلف مانند -e برای پردازش کدهای خاص، -n برای جلوگیری از چاپ خط جدید، و پرانتزهای ${} برای تفکیک متغیرها، می‌توانید انعطاف‌پذیری بیشتری در چاپ مقادیر داشته باشید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”قالب‌بندی خروجی با استفاده از printf” subtitle=”توضیحات کامل”]دستور printf یکی از قدرتمندترین دستورات برای قالب‌بندی خروجی در شل است. برخلاف دستور echo که به طور پیش‌فرض تنها متن را چاپ می‌کند، printf به شما این امکان را می‌دهد که خروجی‌های خود را با دقت بیشتری قالب‌بندی کنید. با استفاده از printf می‌توانید مقادیر را به‌طور دقیق‌تر و با فرمت دلخواه چاپ کنید.

نحوه استفاده از دستور printf

دستور printf به شما این امکان را می‌دهد که خروجی‌ها را به صورت قالب‌بندی‌شده درآورید. فرمت دستور به شکل زیر است:

printf "فرمت" آرگومان‌ها

در اینجا:

  • "فرمت" قالب یا فرمت خروجی است که مشخص می‌کند چگونه مقادیر آرگومان‌ها باید چاپ شوند.
  • آرگومان‌ها مقادیری هستند که باید طبق قالبی که مشخص کرده‌اید، چاپ شوند.

قالب‌های رایج در printf

در دستور printf می‌توانید از انواع قالب‌ها (format specifiers) استفاده کنید تا خروجی دقیقاً به شکل مورد نظر شما باشد. این قالب‌ها شبیه به قالب‌های زبان‌های برنامه‌نویسی مانند C هستند. برخی از قالب‌های رایج عبارتند از:

  • %s برای چاپ رشته‌ها
  • %d برای چاپ اعداد صحیح (integer)
  • %f برای چاپ اعداد اعشاری (float)
  • %x برای چاپ اعداد به صورت هگزادسیمال
  • %c برای چاپ یک کاراکتر واحد
  • %b برای چاپ داده‌ها با استفاده از escape characters (مثل \n)

مثال‌های کاربردی

1. چاپ یک رشته ساده

#!/bin/bash
printf "سلام دنیا!\n"

در این مثال، پیام "سلام دنیا!" با استفاده از printf چاپ می‌شود.

2. چاپ متغیرها

#!/bin/bash
name="علی"
age=25
printf "نام: %s، سن: %d\n" "$name" "$age"

در این مثال:

  • %s برای چاپ رشته (در اینجا نام) استفاده شده است.
  • %d برای چاپ عدد صحیح (سن) استفاده شده است.

خروجی این اسکریپت به صورت زیر خواهد بود:

نام: علی، سن: 25

3. قالب‌بندی اعداد اعشاری

#!/bin/bash
pi=3.14159
printf "مقدار پی: %.2f\n" "$pi"

در اینجا:

  • %.2f برای نمایش عدد اعشاری با دو رقم اعشار استفاده می‌شود.

خروجی این اسکریپت به صورت زیر خواهد بود:

مقدار پی: 3.14

4. استفاده از درصد در خروجی

برای چاپ علامت درصد % در خروجی، باید از دو درصد (%%) استفاده کنید.

#!/bin/bash
score=80
printf "امتیاز شما: %d%%\n" "$score"

خروجی این اسکریپت:

امتیاز شما: 80%

5. چاپ چندین مقدار با استفاده از printf

#!/bin/bash
name="مریم"
age=30
city="تهران"
printf "نام: %-10s سن: %-5d شهر: %s\n" "$name" "$age" "$city"

در این مثال:

  • %10s برای چاپ رشته با حداقل ۱۰ کاراکتر فضای سفید استفاده می‌شود.
  • %-10s باعث می‌شود که رشته به چپ تراز شود.
  • %-5d باعث می‌شود که عدد با حداقل ۵ کاراکتر به سمت چپ تراز شود.

خروجی این اسکریپت:

نام: مریم      سن: 30    شهر: تهران

6. قالب‌بندی برای اعداد بزرگ و کوچک

در صورتی که بخواهید اعداد را با تعداد خاصی از ارقام قبل از و بعد از ممیز چاپ کنید، از دستور printf می‌توانید استفاده کنید.

#!/bin/bash
number=12345.6789
printf "عدد وارد شده: %.2f\n" "$number"

در این مثال، عدد وارد شده به‌صورت اعشاری با دو رقم اعشار چاپ خواهد شد.

ویژگی‌های کلیدی printf

  1. دقت در قالب‌بندی: printf به شما این امکان را می‌دهد که به‌طور دقیق‌تری خروجی‌ها را قالب‌بندی کنید، مخصوصاً برای مقادیر عددی، متنی یا زمان.
  2. فرمت‌های چندگانه: شما می‌توانید از قالب‌های مختلفی برای متغیرهای مختلف استفاده کنید و حتی از پارامترهای متنی یا عددی برای فرمت‌بندی استفاده کنید.
  3. چندین آرگومان: printf می‌تواند چندین آرگومان را در قالب‌های مختلف بپذیرد و آن‌ها را چاپ کند.

جمع‌بندی

در این بخش، استفاده از دستور printf برای قالب‌بندی خروجی‌ها بررسی شد. printf ابزاری بسیار قدرتمند برای قالب‌بندی دقیق و کنترل‌شده خروجی‌ها در شل است. با استفاده از قالب‌های مختلف می‌توان مقادیر را به‌طور صحیح و شکیل نمایش داد. این دستور به‌ویژه در اسکریپت‌های پیچیده که نیاز به قالب‌بندی دقیق دارند، بسیار مفید است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” subtitle=”توضیحات کامل” title=”ذخیره خروجی دستورات در فایل با استفاده از نشانه‌های هدایت خروجی”]در شل اسکریپت‌ها، گاهی اوقات نیاز داریم که خروجی دستورات یا برنامه‌های مختلف را در یک فایل ذخیره کنیم تا در زمان‌های بعدی از آن استفاده کنیم یا نتایج آن را بررسی کنیم. برای این منظور، از عملگرهای > و >> برای هدایت خروجی دستورات به فایل‌ها استفاده می‌کنیم.

1. استفاده از >

عملگر > برای نوشتن یا بازنویسی محتوای یک فایل استفاده می‌شود. اگر فایل مقصد از قبل وجود داشته باشد، محتوای آن پاک خواهد شد و خروجی جدید در آن نوشته می‌شود. اگر فایل وجود نداشته باشد، یک فایل جدید ساخته می‌شود.

نحوه استفاده از >:

دستور > فایل

در اینجا:

  • دستور: هر دستوری است که خروجی آن به فایل هدایت می‌شود.
  • فایل: نام فایلی است که خروجی در آن ذخیره می‌شود.

مثال 1: نوشتن خروجی یک دستور در یک فایل

#!/bin/bash
echo "سلام دنیا" > hello.txt

در این مثال:

  • دستور echo "سلام دنیا" خروجی "سلام دنیا" را تولید می‌کند.
  • این خروجی در فایل hello.txt ذخیره می‌شود.
  • اگر فایل hello.txt از قبل وجود داشته باشد، محتوای آن با "سلام دنیا" جایگزین می‌شود.
  • اگر فایل hello.txt وجود نداشته باشد، یک فایل جدید به نام hello.txt ایجاد می‌شود.

مثال 2: نوشتن خروجی دستوری دیگر در یک فایل

#!/bin/bash
ls -l > directory_listing.txt

در اینجا:

  • دستور ls -l فهرستی از فایل‌ها و دایرکتوری‌ها را به صورت دقیق چاپ می‌کند.
  • این خروجی در فایل directory_listing.txt ذخیره می‌شود.

2. استفاده از >>

عملگر >> برای اضافه کردن خروجی به انتهای یک فایل موجود استفاده می‌شود. برخلاف >, که فایل را بازنویسی می‌کند، >> به فایل موجود خروجی جدید را اضافه می‌کند. اگر فایل وجود نداشته باشد، یک فایل جدید ساخته می‌شود.

نحوه استفاده از >>:

دستور >> فایل

در اینجا:

  • دستور: دستوری است که می‌خواهید خروجی آن را در فایل ذخیره کنید.
  • فایل: نام فایل مقصدی است که خروجی در آن ذخیره خواهد شد.

مثال 3: اضافه کردن به انتهای فایل

#!/bin/bash
echo "این یک خط جدید است" >> hello.txt

در این مثال:

  • اگر فایل hello.txt وجود داشته باشد، متن "این یک خط جدید است" به انتهای این فایل اضافه می‌شود.
  • اگر فایل hello.txt وجود نداشته باشد، یک فایل جدید به نام hello.txt ساخته شده و متن در آن ذخیره می‌شود.

مثال 4: استفاده از >> برای جمع‌آوری خروجی‌های مختلف در یک فایل

#!/bin/bash
echo "شروع جمع‌آوری اطلاعات" > data.txt
echo "اطلاعات جدید 1" >> data.txt
echo "اطلاعات جدید 2" >> data.txt
echo "اطلاعات جدید 3" >> data.txt

در این مثال:

  • ابتدا با استفاده از > محتوای "شروع جمع‌آوری اطلاعات" در فایل data.txt نوشته می‌شود.
  • سپس با استفاده از >> سه خط جدید به انتهای این فایل اضافه می‌شود.
  • فایل نهایی شامل چهار خط خواهد بود:
    شروع جمع‌آوری اطلاعات
    اطلاعات جدید 1
    اطلاعات جدید 2
    اطلاعات جدید 3
    

3. هدایت خروجی خطا به فایل

گاهی اوقات می‌خواهیم علاوه بر خروجی موفقیت‌آمیز یک دستور، خطاها (stderr) را نیز در یک فایل ذخیره کنیم. برای این کار، می‌توانیم از عملگر 2> برای هدایت خروجی خطا به فایل استفاده کنیم.

مثال 5: ذخیره خروجی استاندارد و خطا در فایل‌های جداگانه

#!/bin/bash
ls /nonexistent_directory > output.txt 2> error.txt

در اینجا:

  • دستور ls /nonexistent_directory باعث تولید یک خطای “دایرکتوری پیدا نشد” می‌شود.
  • خروجی معمولی در فایل output.txt ذخیره نمی‌شود زیرا دستوری که اجرا شده هیچ خروجی موفقیت‌آمیزی ندارد.
  • خطای تولید شده (که مربوط به stderr است) در فایل error.txt ذخیره می‌شود.

مثال 6: هدایت همزمان خروجی استاندارد و خطا به یک فایل

#!/bin/bash
ls /nonexistent_directory > all_output.txt 2>&1

در اینجا:

  • دستور 2>&1 باعث می‌شود که هر دو نوع خروجی (stdout و stderr) به فایل all_output.txt هدایت شوند.

جمع‌بندی

در این بخش، نحوه استفاده از عملگرهای > و >> برای نوشتن یا اضافه کردن خروجی دستورات به فایل‌ها بررسی شد. عملگر > برای بازنویسی محتوای فایل و عملگر >> برای اضافه کردن خروجی به انتهای فایل استفاده می‌شود. همچنین، نحوه هدایت خطاها به فایل‌ها با استفاده از عملگر 2> و هدایت همزمان خروجی استاندارد و خطا به یک فایل نیز شرح داده شد. این ابزارها در اسکریپت‌نویسی شل برای مدیریت خروجی‌ها و ذخیره‌سازی داده‌ها بسیار مفید هستند.

 [/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تغییر رفتار نوشتن خروجی با کاراکترهای کنترلی مانند
،” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، برای کنترل بهتر نحوه نمایش خروجی می‌توان از کاراکترهای کنترلی استفاده کرد. این کاراکترها برای تنظیم فرمت خروجی به کار می‌روند و به شما این امکان را می‌دهند که خروجی را به صورت خواناتر و زیباتری نمایش دهید. دو نمونه از مهم‌ترین کاراکترهای کنترلی که برای تغییر نحوه نوشتن خروجی در شل استفاده می‌شوند عبارتند از:

  • \n برای ایجاد خط جدید.
  • \t برای ایجاد فاصله عمودی (tab).

1. استفاده از \n برای خط جدید

کاراکتر \n برای ایجاد یک خط جدید در خروجی استفاده می‌شود. این کاراکتر به شل می‌گوید که پس از نوشتن متن جاری، باید به خط جدیدی برود و از آنجا نوشتن ادامه یابد.

نحوه استفاده از \n:

echo -e "متن اول\nمتن دوم"

در اینجا:

  • گزینه -e برای فعال‌سازی تفسیر کاراکترهای ویژه مانند \n در دستور echo استفاده می‌شود.
  • متن "متن اول" در خط اول چاپ می‌شود، سپس \n باعث می‌شود که متن "متن دوم" در خط جدید نمایش داده شود.

خروجی:

متن اول
متن دوم

2. استفاده از \t برای فاصله عمودی (Tab)

کاراکتر \t برای اضافه کردن یک فضای عمودی (tab) به متن استفاده می‌شود. این کاراکتر معمولا برای فرمت‌دهی و خواناتر کردن خروجی‌های ستون‌دار به کار می‌رود.

نحوه استفاده از \t:

echo -e "ستون اول\tستون دوم\tستون سوم"

در اینجا:

  • گزینه -e برای فعال‌سازی تفسیر کاراکترهای ویژه مثل \t استفاده می‌شود.
  • کاراکتر \t بین هر ستون قرار می‌گیرد و فاصله‌ای مشابه فاصله عمودی (tab) را ایجاد می‌کند.

خروجی:

ستون اول    ستون دوم    ستون سوم

این خروجی به این صورت است که هر ستون با فاصله‌ای شبیه به فاصله عمودی از هم جدا می‌شود.

3. ترکیب \n و \t

می‌توان کاراکترهای کنترلی مختلف را در کنار هم استفاده کرد تا فرمت خروجی به شکلی که می‌خواهید درآید. برای مثال، می‌توانید از هر دو \n و \t برای نمایش داده‌های مرتب و چندخطی استفاده کنید.

مثال ترکیب \n و \t:

echo -e "نام\tآدرس\tشماره تماس\nعلی\tتهران\t123456\nمحمد\tاصفهان\t654321"

در اینجا:

  • \t برای ایجاد فاصله بین ستون‌ها و \n برای ایجاد خط جدید استفاده شده است.
  • داده‌ها به صورت جدول‌وار و مرتب در چند خط نمایش داده می‌شوند.

خروجی:

نام     آدرس     شماره تماس
علی     تهران    123456
محمد    اصفهان   654321

4. استفاده از \c برای جلوگیری از افزودن خط جدید

کاراکتر \c می‌تواند برای جلوگیری از افزودن خط جدید پس از چاپ یک متن استفاده شود. این کاراکتر باعث می‌شود که هیچ خط جدیدی بعد از چاپ متن وارد نشود.

مثال استفاده از \c:

echo -e "این یک متن است بدون خط جدید\c"

در اینجا:

  • \c باعث می‌شود که بعد از نوشتن "این یک متن است بدون خط جدید" هیچ خط جدیدی ایجاد نشود.

خروجی:

این یک متن است بدون خط جدید

5. استفاده از printf برای کنترل دقیق‌تر خروجی

اگر بخواهید کنترل دقیق‌تری بر روی نحوه نمایش داده‌ها داشته باشید، می‌توانید از دستور printf استفاده کنید. دستور printf به شما این امکان را می‌دهد که به راحتی فرمت خروجی را تنظیم کنید.

مثال استفاده از printf:

printf "نام\tآدرس\tشماره تماس\n"
printf "علی\tتهران\t123456\n"
printf "محمد\tاصفهان\t654321\n"

در اینجا:

  • دستور printf از همان کاراکترهای کنترلی \t و \n برای ایجاد جداسازی و خطوط جدید استفاده می‌کند.
  • این روش دقت بیشتری در مقایسه با echo فراهم می‌کند.

خروجی:

نام     آدرس     شماره تماس
علی     تهران    123456
محمد    اصفهان   654321

جمع‌بندی

در این بخش، کاراکترهای کنترلی مانند \n برای ایجاد خطوط جدید و \t برای ایجاد فاصله عمودی (tab) در شل اسکریپت‌ها بررسی شد. همچنین، نحوه استفاده از echo برای چاپ متن با این کاراکترها و دستور printf برای کنترل دقیق‌تر فرمت خروجی توضیح داده شد. این کاراکترها ابزارهای مفیدی برای فرمت‌دهی و نمایش زیباتر و خواناتر داده‌ها در اسکریپت‌های شل هستند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. ریدایرکشن (Redirection)”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”هدایت خروجی استاندارد به فایل” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، برای ذخیره‌سازی خروجی یک دستور یا برنامه در یک فایل، می‌توان از دستور هدایت خروجی استفاده کرد. یکی از پرکاربردترین روش‌ها برای این کار، استفاده از علامت > است. این عملگر خروجی استاندارد (stdout) را به یک فایل هدایت می‌کند و در صورتی که فایل وجود نداشته باشد، آن را ایجاد می‌کند. اگر فایل از قبل وجود داشته باشد، محتوای آن با خروجی جدید جایگزین می‌شود.

1. نحوه استفاده از > برای هدایت خروجی به فایل

command > file

در اینجا:

  • command نمایانگر دستوری است که می‌خواهید خروجی آن را به فایل هدایت کنید.
  • file نام فایلی است که خروجی دستور به آن نوشته می‌شود.

مثال 1: ذخیره‌سازی خروجی دستور echo در فایل

فرض کنید می‌خواهید پیامی را در یک فایل ذخیره کنید. می‌توانید از دستور echo همراه با عملگر > استفاده کنید:

echo "Hello, World!" > output.txt

در اینجا:

  • پیام "Hello, World!" چاپ می‌شود و به جای نمایش در صفحه، در فایل output.txt ذخیره می‌شود.

خروجی:

فایل output.txt به صورت زیر خواهد بود:

Hello, World!

اگر فایل output.txt از قبل وجود داشته باشد، محتوای قبلی آن پاک خواهد شد و با خروجی جدید جایگزین می‌شود.

2. استفاده از >> برای اضافه کردن به فایل

اگر بخواهید به جای جایگزین کردن محتوای فایل، خروجی جدید را به انتهای آن اضافه کنید، باید از عملگر >> استفاده کنید. این عملگر باعث می‌شود که محتوای جدید در انتهای فایل اضافه شود بدون اینکه محتوای قبلی آن پاک شود.

مثال 2: اضافه کردن خروجی به فایل

echo "This is a new line" >> output.txt

در اینجا:

  • پیام "This is a new line" به انتهای فایل output.txt اضافه می‌شود.

خروجی:

فایل output.txt اکنون به شکل زیر خواهد بود:

Hello, World!
This is a new line

3. هدایت خروجی استاندارد و خطاها به یک فایل

اگر می‌خواهید هم خروجی استاندارد (stdout) و هم خروجی خطاها (stderr) را به یک فایل هدایت کنید، می‌توانید از ترکیب &> استفاده کنید.

مثال 3: هدایت خروجی استاندارد و خطا به یک فایل

command &> output.txt

در اینجا:

  • command خروجی استاندارد و خطاهای خود را به فایل output.txt هدایت می‌کند.

برای مثال، اگر دستوری مانند ls با یک پارامتر نادرست اجرا شود، می‌توانید هم خروجی استاندارد و هم پیغام خطا را در یک فایل ذخیره کنید:

ls /nonexistent_directory &> output.txt

در اینجا:

  • خروجی استاندارد (در صورتی که موجود باشد) و خطای مربوط به دایرکتوری غیرموجود در فایل output.txt ذخیره می‌شود.

خروجی:

فایل output.txt به شکل زیر خواهد بود:

ls: cannot access '/nonexistent_directory': No such file or directory

4. هدایت خروجی به فایل‌های مختلف برای stdout و stderr

اگر بخواهید خروجی استاندارد و خطاها را به فایل‌های جداگانه هدایت کنید، می‌توانید از عملگرهای > و 2> استفاده کنید.

  • > برای هدایت خروجی استاندارد.
  • 2> برای هدایت خروجی خطا (stderr).

مثال 4: هدایت خروجی استاندارد و خطا به فایل‌های جداگانه

command > output.txt 2> error.txt

در اینجا:

  • خروجی استاندارد در فایل output.txt ذخیره می‌شود.
  • خروجی خطا در فایل error.txt ذخیره می‌شود.

مثال 5: هدایت خروجی استاندارد و خطا به فایل‌های جداگانه در یک دستور

ls /nonexistent_directory > output.txt 2> error.txt

در اینجا:

  • خروجی استاندارد (در صورتی که وجود داشته باشد) به فایل output.txt هدایت می‌شود.
  • پیغام خطا (در صورتی که به دلیل وجود نداشتن دایرکتوری خطا رخ دهد) به فایل error.txt هدایت می‌شود.

خروجی:

  • فایل output.txt خالی خواهد ماند.
  • فایل error.txt شامل خطای زیر خواهد بود:
ls: cannot access '/nonexistent_directory': No such file or directory

جمع‌بندی

در این بخش، نحوه استفاده از عملگر > برای هدایت خروجی استاندارد یک دستور به فایل توضیح داده شد. همچنین، با عملگر >> برای اضافه کردن داده به فایل و &> برای هدایت همزمان خروجی استاندارد و خطا به یک فایل آشنا شدیم. همچنین، روش‌هایی برای هدایت خروجی استاندارد و خطا به فایل‌های جداگانه با استفاده از > و 2> بیان گردید. این تکنیک‌ها به شما کمک می‌کند تا بتوانید خروجی دستورات را به راحتی ذخیره کرده و مدیریت کنید.

 [/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”افزودن خروجی به انتهای فایل” subtitle=”توضیحات کامل”]در شل اسکریپت‌، اگر بخواهید خروجی یک دستور را به انتهای یک فایل موجود اضافه کنید، از عملگر >> می توانید استفاده کنید. برخلاف عملگر > که فایل را بازنویسی می‌کند و محتویات قبلی را پاک می‌کند، >>` باعث می‌شود که خروجی جدید به انتهای فایل اضافه شود بدون اینکه محتوای قبلی آن از بین برود.

نحوه استفاده:

command >> file

در اینجا:

  • command نمایانگر دستوری است که خروجی آن به فایل اضافه می‌شود.
  • file نام فایلی است که خروجی دستور در آن ذخیره می‌شود.

مثال 1: استفاده از echo برای اضافه کردن به فایل

فرض کنید می‌خواهید متنی را به یک فایل اضافه کنید. از دستور echo همراه با >> می‌توان برای این کار استفاده کرد.

echo "This is a new line" >> output.txt

در اینجا:

  • پیام "This is a new line" به انتهای فایل output.txt اضافه می‌شود.

خروجی:

اگر فایل output.txt از قبل دارای محتوا باشد، این محتوا حفظ می‌شود و خط جدید در انتهای آن اضافه خواهد شد.

محتوای فایل output.txt به شکل زیر خواهد بود:

Hello, World!
This is a new line

مثال 2: اضافه کردن خروجی دستور date به فایل

برای اضافه کردن تاریخ و زمان کنونی به فایل، می‌توانید از دستور date همراه با عملگر >> استفاده کنید.

date >> output.txt

این دستور تاریخ و زمان کنونی را به انتهای فایل output.txt اضافه می‌کند.

خروجی:

محتوای فایل output.txt ممکن است به این شکل باشد:

Hello, World!
This is a new line
Fri Feb 22 10:30:00 UTC 2025

1. هدایت خطاها به انتهای فایل

اگر بخواهید خطاها را نیز به انتهای یک فایل اضافه کنید، می‌توانید از عملگر 2>> برای هدایت خطاها به انتهای فایل استفاده کنید.

مثال 3: هدایت خطاها به انتهای فایل

ls /nonexistent_directory 2>> error.txt

در اینجا:

  • پیغام خطای مربوط به دایرکتوری غیرموجود به انتهای فایل error.txt اضافه می‌شود.

خروجی:

فایل error.txt به شکل زیر خواهد بود:

ls: cannot access '/nonexistent_directory': No such file or directory

جمع‌بندی

در این بخش به استفاده از عملگر >> برای اضافه کردن خروجی به انتهای یک فایل پرداختیم. با این روش می‌توان بدون از دست دادن داده‌های قبلی در فایل، خروجی جدید را به آن افزود. همچنین، مشاهده کردیم که می‌توان خطاها را نیز با استفاده از 2>> به انتهای فایل‌های مختلف هدایت کرد. این ابزار برای جمع‌آوری داده‌ها و گزارش‌ها در فایل‌ها بدون از دست دادن اطلاعات قدیمی بسیار مفید است.

 [/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”هدایت خطاهای استاندارد به فایل” subtitle=”توضیحات کامل”]در سیستم‌عامل‌های مبتنی بر یونیکس و لینوکس، خروجی دستورها به دو دسته اصلی تقسیم می‌شود:

  1. خروجی استاندارد (Standard Output) یا stdout: این خروجی، اطلاعات معمولی و عادی است که توسط دستورها تولید می‌شود.
  2. خروجی خطاهای استاندارد (Standard Error) یا stderr: این خروجی، شامل پیغام‌های خطا و هشدارهایی است که از اجرای دستورها حاصل می‌شود.

برای هدایت خروجی‌های خطای استاندارد به یک فایل خاص، از عملگر 2> استفاده می‌شود. در اینجا، عدد 2 نمایانگر فایل توصیفگر خطای استاندارد است و > برای هدایت خروجی به فایل به کار می‌رود.

نحوه استفاده:

command 2> file

در اینجا:

  • command نمایانگر دستوری است که ممکن است خطا تولید کند.
  • 2> به سیستم می‌گوید که خطاهای استاندارد (stderr) را به فایل هدایت کند.
  • file نام فایلی است که خطاها در آن ذخیره می‌شوند.

مثال 1: هدایت خطاهای دستور ls به فایل

فرض کنید دستور ls را برای فهرست کردن محتویات یک دایرکتوری که وجود ندارد اجرا می‌کنید. در این حالت، یک پیغام خطا دریافت خواهید کرد. با استفاده از عملگر 2>, می‌توان این خطا را به یک فایل هدایت کرد.

ls /nonexistent_directory 2> error.log

در اینجا:

  • دستور ls تلاش می‌کند تا محتویات دایرکتوری /nonexistent_directory را نمایش دهد.
  • چون این دایرکتوری وجود ندارد، یک پیغام خطا به سیستم ارسال می‌شود که توسط 2> به فایل error.log هدایت می‌شود.

خروجی:

فایل error.log حاوی پیغام خطا به شکل زیر خواهد بود:

ls: cannot access '/nonexistent_directory': No such file or directory

مثال 2: هدایت خطاهای یک دستور اشتباه به فایل

اگر از یک دستور اشتباه استفاده کنید، مثلا دستور ech که اشتباه تایپی است، یک خطای مشابه زیر مشاهده خواهید کرد:

ech "Hello" 2> error.log

در اینجا:

  • چون دستور ech اشتباه است و به عنوان یک دستور شناخته نمی‌شود، پیغام خطای مربوطه به error.log ارسال می‌شود.

خروجی:

فایل error.log ممکن است به این شکل باشد:

bash: ech: command not found

هدایت خطا و خروجی استاندارد به یک فایل

در برخی موارد، ممکن است بخواهید هم خروجی استاندارد و هم خطاها را به یک فایل هدایت کنید. برای انجام این کار، می‌توانید از عملگر &> یا 2>&1 استفاده کنید.

مثال 3: هدایت خروجی استاندارد و خطاها به یک فایل

command &> output.log

یا

command > output.log 2>&1

در اینجا:

  • هر دو دستور خروجی استاندارد (stdout) و خروجی خطا (stderr) را به فایل output.log هدایت می‌کنند.

جمع‌بندی

در این بخش به هدایت خروجی خطاهای استاندارد با استفاده از عملگر 2> پرداختیم. این امکان به شما این اجازه را می‌دهد که فقط خطاهای تولید شده توسط دستورها را در یک فایل خاص ذخیره کنید، که برای گزارش‌دهی و تجزیه و تحلیل مشکلات بسیار مفید است. همچنین با استفاده از روش‌های مختلف می‌توان هم خروجی استاندارد و هم خطاها را در یک فایل ذخیره کرد، که این خود کمک شایانی به مدیریت و بررسی دستورات در اسکریپت‌ها و برنامه‌ها می‌کند.

 [/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”هدایت همزمان خروجی و خطا به یک فایل” subtitle=”توضیحات کامل”]در سیستم‌عامل‌های مبتنی بر یونیکس و لینوکس، دستوراتی که اجرا می‌کنید معمولاً دو نوع خروجی تولید می‌کنند:

  1. خروجی استاندارد (stdout): این خروجی شامل داده‌ها، نتایج یا اطلاعاتی است که معمولاً توسط دستورها تولید می‌شود.
  2. خروجی خطاهای استاندارد (stderr): این خروجی شامل پیغام‌های خطا یا هشدارهایی است که هنگام اجرا یا در حین پردازش توسط دستورها ایجاد می‌شود.

گاهی اوقات، ممکن است بخواهید همزمان هم خروجی استاندارد و هم خطاهای استاندارد را در یک فایل ذخیره کنید. برای این کار از عملگرهای خاصی استفاده می‌شود.

در اینجا از ترکیب > و 2>&1 برای هدایت همزمان خروجی و خطا به یک فایل استفاده می‌کنیم.

نحوه استفاده:

command > file 2>&1

در اینجا:

  • command: دستور یا برنامه‌ای است که اجرا می‌کنید.
  • >: این عملگر برای هدایت خروجی استاندارد (stdout) به یک فایل استفاده می‌شود.
  • 2>&1: این قسمت به سیستم اعلام می‌کند که خطای استاندارد (stderr که با عدد 2 نمایان می‌شود) باید به همان جایی هدایت شود که خروجی استاندارد (stdout) هدایت شده است.

نحوه کارکرد این ترکیب:

  1. ابتدا دستور command اجرا می‌شود و خروجی استاندارد آن به فایل هدایت می‌شود.
  2. سپس قسمت 2>&1 به سیستم می‌گوید که خروجی خطای استاندارد را نیز به همان فایل هدایت کند که خروجی استاندارد در آن قرار دارد.

این ترکیب در مواردی که نیاز دارید تمامی پیام‌ها (چه پیام‌های عادی و چه پیغام‌های خطا) را در یک فایل جمع‌آوری کنید، بسیار مفید است.

مثال 1: هدایت خروجی و خطا به یک فایل

فرض کنید شما می‌خواهید دستور ls را برای فهرست کردن محتویات یک دایرکتوری اجرا کنید، اما دایرکتوری مورد نظر وجود ندارد. در این صورت هم خروجی عادی و هم خطای آن باید در یک فایل ذخیره شود.

ls /nonexistent_directory > output.log 2>&1

در اینجا:

  • دستور ls تلاش می‌کند تا محتویات دایرکتوری /nonexistent_directory را نمایش دهد.
  • چون این دایرکتوری وجود ندارد، پیغام خطا به همراه خروجی، هر دو به فایل output.log هدایت می‌شوند.

خروجی فایل output.log:

ls: cannot access '/nonexistent_directory': No such file or directory

مثال 2: اجرای دستور و ذخیره خروجی و خطا در یک فایل

در صورتی که بخواهید یک دستور مانند echo را اجرا کنید و همزمان پیغام‌های خطا را در همان فایل ذخیره کنید، دستور به شکل زیر خواهد بود:

echo "Hello, World!" > output.log 2>&1

در اینجا:

  • دستور echo بدون هیچ مشکلی اجرا می‌شود و “Hello, World!” را به فایل output.log می‌نویسد.
  • از آنجایی که این دستور خطا تولید نمی‌کند، تنها خروجی استاندارد در فایل ذخیره می‌شود. با این حال، اگر خطاهایی ایجاد شوند، آن‌ها نیز در همان فایل ذخیره خواهند شد.

خروجی فایل output.log:

Hello, World!

مثال 3: هدایت همزمان خروجی و خطای یک دستور اشتباه

اگر از یک دستور اشتباه مانند ech (اشتباه تایپی از echo) استفاده کنید:

ech "Hello" > output.log 2>&1

در اینجا:

  • چون دستور ech اشتباه است و به عنوان دستور شناسایی نمی‌شود، خطای آن به همراه هر خروجی احتمالی به فایل output.log هدایت خواهد شد.

خروجی فایل output.log:

bash: ech: command not found

نکات مهم:

  • ترتیب در استفاده از 2>&1 بسیار مهم است. ابتدا باید خروجی استاندارد را هدایت کنید و سپس خطای استاندارد را به همان جایی که خروجی هدایت شده، متصل کنید.
  • در صورتی که از ترکیب command > file 2>&1 استفاده کنید، خروجی و خطاها همزمان به فایل نوشته می‌شوند.

جمع‌بندی

در این بخش به هدایت همزمان خروجی و خطا به یک فایل با استفاده از command > file 2>&1 پرداختیم. این روش به شما این امکان را می‌دهد که تمامی اطلاعات تولید شده توسط دستورها، شامل خروجی‌های استاندارد و خطاها، را در یک فایل واحد ذخیره کنید. این روش برای تجزیه و تحلیل دستورات و بررسی مشکلات اسکریپت‌ها و دستورات بسیار مفید است، به ویژه زمانی که نیاز دارید هر دو نوع داده را در کنار هم ذخیره کنید.

 [/cdb_course_lesson][cdb_course_lesson title=”فصل 4. پایپینگ (Piping)”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”انتقال خروجی یک دستور به عنوان ورودی دستور دیگر با استفاده از |” subtitle=”توضیحات کامل”]در سیستم‌های یونیکس و لینوکس، یک ابزار قدرتمند برای پردازش داده‌ها و ایجاد زنجیره‌ای از دستورات وجود دارد که از آن به عنوان پایپ (Pipe) یاد می‌شود. این ابزار به شما اجازه می‌دهد که خروجی یک دستور را به ورودی دستور دیگری منتقل کنید. این کار با استفاده از نماد | (پایپ) انجام می‌شود.

نحوه استفاده از |:

زمانی که از | استفاده می‌کنید، خروجی استاندارد (stdout) یک دستور به ورودی استاندارد (stdin) دستور بعدی هدایت می‌شود. این تکنیک به شما این امکان را می‌دهد که مجموعه‌ای از دستورات را به صورت زنجیره‌ای اجرا کنید.

نحوه کارکرد:

  1. ابتدا دستور اول اجرا می‌شود.
  2. خروجی استاندارد دستور اول به دستور بعدی به عنوان ورودی منتقل می‌شود.
  3. دستور دوم نیز خروجی‌ای تولید می‌کند که می‌تواند به دستور سوم منتقل شود و به همین ترتیب ادامه می‌یابد.

مثال‌ها:

مثال 1: استفاده از | برای ارسال خروجی به ورودی

فرض کنید می‌خواهید لیستی از فایل‌ها در یک دایرکتوری را مشاهده کنید و سپس نتایج را فیلتر کنید تا فقط فایل‌های متنی (.txt) نمایش داده شوند. برای این کار می‌توانید از دستور ls برای فهرست کردن فایل‌ها و دستور grep برای فیلتر کردن خروجی استفاده کنید.

ls -l | grep ".txt"

در اینجا:

  • دستور ls -l فهرست فایل‌های موجود در دایرکتوری را به صورت بلند (طولانی) نمایش می‌دهد.
  • سپس خروجی این دستور به دستور grep ".txt" ارسال می‌شود که فایل‌هایی که پسوند .txt دارند را فیلتر می‌کند.

مثال 2: استفاده از | برای شمارش تعداد خطوط

فرض کنید می‌خواهید تعداد کلمات موجود در یک فایل متنی را بدانید. برای این کار می‌توانید از دستور cat برای خواندن فایل و سپس از دستور wc -w برای شمارش کلمات استفاده کنید.

cat file.txt | wc -w

در اینجا:

  • دستور cat file.txt محتویات فایل file.txt را به خروجی استاندارد ارسال می‌کند.
  • سپس دستور wc -w تعداد کلمات در ورودی خود (که از خروجی cat دریافت کرده است) را شمارش می‌کند.

مثال 3: استفاده از | برای جستجو در میان نتایج

فرض کنید می‌خواهید جستجو کنید که آیا یک دستور خاص در میان فرایندهای در حال اجرا وجود دارد. می‌توانید از دستور ps برای نمایش فرایندهای جاری و سپس از grep برای جستجوی یک نام خاص استفاده کنید.

ps aux | grep "bash"

در اینجا:

  • دستور ps aux تمامی فرایندهای جاری را نمایش می‌دهد.
  • سپس خروجی این دستور به grep "bash" ارسال می‌شود که به دنبال فرایندهایی می‌گردد که عبارت “bash” در آن‌ها وجود دارد.

مثال 4: ترکیب چند دستور با |

شما می‌توانید چند دستور را با استفاده از | ترکیب کنید تا از قدرت پردازش داده‌ها در خطوط مختلف استفاده کنید. برای مثال، می‌توانید تمامی فایل‌های متنی را در دایرکتوری پیدا کرده، محتوای آن‌ها را نمایش داده و سپس تعداد کلمات آن‌ها را بشمارید.

ls *.txt | xargs cat | wc -w

در اینجا:

  • ls *.txt لیست فایل‌های متنی در دایرکتوری را نمایش می‌دهد.
  • xargs cat محتویات این فایل‌ها را به دستور cat ارسال می‌کند.
  • سپس دستور wc -w تعداد کلمات در خروجی cat را می‌شمارد.

نکات مهم:

  1. پایپ‌ها می‌توانند چندین بار در یک دستور استفاده شوند: به این معنی که می‌توانید مجموعه‌ای از دستورات را به هم متصل کنید.
  2. دستورها به صورت مستقل اجرا می‌شوند: هر دستور در پایپ به صورت مستقل از دیگری اجرا می‌شود و خروجی آن به دستور بعدی منتقل می‌شود.
  3. حافظه و پردازش کارآمد: استفاده از پایپ‌ها در پردازش داده‌ها باعث می‌شود که نیازی به ذخیره‌سازی موقت خروجی‌ها در فایل‌ها نباشد، که این امر پردازش را کارآمدتر می‌کند.
  4. خروجی‌ها می‌توانند به دستورهای مختلف هدایت شوند: می‌توانید از خروجی یک دستور برای هدایت به چندین دستور مختلف استفاده کنید.

جمع‌بندی

در این بخش، روش استفاده از پایپ (|) برای انتقال خروجی یک دستور به ورودی دستور دیگر را بررسی کردیم. این تکنیک به شما این امکان را می‌دهد که دستورات را به صورت زنجیره‌ای به هم متصل کنید و فرآیندهای پیچیده‌ای را به صورت ساده و مؤثر انجام دهید. استفاده از پایپ در سیستم‌های یونیکس و لینوکس برای پردازش داده‌ها، جستجو، فیلتر کردن و تحلیل اطلاعات بسیار مفید است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از پایپ برای ترکیب دستورات مانند grep، awk، و sort” subtitle=”توضیحات کامل”]در سیستم‌های یونیکس و لینوکس، ترکیب دستورات مختلف با استفاده از پایپ (|) یکی از ابزارهای قدرتمند برای پردازش داده‌ها است. در این بخش، به بررسی چگونگی استفاده از دستورات مختلف مانند grep، awk، و sort در کنار یکدیگر با استفاده از پایپ می‌پردازیم.

دستورات معرفی‌شده:

  • grep: این دستور برای جستجو و فیلتر کردن خطوطی از متن است که با یک الگوی خاص مطابقت دارند.
  • awk: یک زبان برنامه‌نویسی برای پردازش متن و فایل‌هاست که می‌تواند برای تجزیه و پردازش داده‌ها در فرمت‌های مختلف استفاده شود.
  • sort: این دستور برای مرتب‌سازی داده‌ها به ترتیب صعودی یا نزولی استفاده می‌شود.

مثال 1: جستجوی یک الگو با grep و سپس مرتب‌سازی نتایج با sort

فرض کنید می‌خواهید در یک فایل متنی تمامی خطوطی که کلمه “error” را دارند پیدا کنید و سپس آن‌ها را به ترتیب حروف مرتب کنید.

grep "error" file.txt | sort

در اینجا:

  • دستور grep "error" file.txt تمامی خطوطی که کلمه “error” را شامل می‌شوند از فایل file.txt استخراج می‌کند.
  • سپس خروجی این دستور به دستور sort منتقل می‌شود که داده‌ها را به ترتیب حروف مرتب می‌کند.

مثال 2: استخراج فیلدهای خاص با awk و سپس مرتب‌سازی با sort

فرض کنید یک فایل متنی دارید که شامل نام و سن افراد است. شما می‌خواهید سن‌ها را استخراج کرده و سپس آن‌ها را به ترتیب نزولی مرتب کنید.

awk '{print $2}' file.txt | sort -nr

در اینجا:

  • دستور awk '{print $2}' file.txt فیلد دوم (سن افراد) را از فایل file.txt استخراج می‌کند.
  • سپس خروجی آن به دستور sort -nr می‌رود که داده‌ها را به ترتیب نزولی مرتب می‌کند (-n برای مرتب‌سازی عددی و -r برای ترتیب معکوس است).

مثال 3: فیلتر کردن داده‌ها با grep و سپس پردازش داده‌های استخراج‌شده با awk

در این مثال، فرض کنید یک فایل لاگ دارید که شامل اطلاعاتی در مورد درخواست‌های HTTP است. شما می‌خواهید فقط درخواست‌های “GET” را استخراج کرده و سپس فقط آدرس‌های IP را نمایش دهید.

grep "GET" access.log | awk '{print $1}'

در اینجا:

  • دستور grep "GET" access.log تمامی خطوطی که شامل “GET” هستند از فایل access.log استخراج می‌کند.
  • سپس خروجی آن به دستور awk '{print $1}' منتقل می‌شود که اولین فیلد (آدرس IP) را از هر خط نمایش می‌دهد.

مثال 4: ترکیب grep، awk و sort برای استخراج و پردازش داده‌ها

فرض کنید شما یک فایل متنی دارید که اطلاعات کاربرانی مانند نام، سن و شغل آن‌ها را ذخیره کرده است. شما می‌خواهید نام کاربرانی را که شغل‌شان “مطور” است پیدا کرده و سپس آن‌ها را به ترتیب حروف مرتب کنید.

grep "developer" users.txt | awk '{print $1}' | sort

در اینجا:

  • دستور grep "developer" users.txt تمامی کاربرانی که شغل‌شان “developer” است را از فایل users.txt استخراج می‌کند.
  • سپس خروجی آن به دستور awk '{print $1}' می‌رود که تنها نام کاربران را نمایش می‌دهد.
  • در نهایت، این داده‌ها به دستور sort منتقل می‌شود که اسامی را به ترتیب حروف مرتب می‌کند.

مثال 5: استفاده از grep، awk و sort برای پردازش داده‌های عددی

فرض کنید یک فایل دارید که شامل اطلاعات فروش روزانه یک فروشگاه است. شما می‌خواهید تنها فروش‌های بیشتر از 1000 دلار را فیلتر کرده و سپس آن‌ها را به ترتیب نزولی مرتب کنید.

grep "sales" sales_data.txt | awk '$2 > 1000 {print $2}' | sort -nr

در اینجا:

  • دستور grep "sales" sales_data.txt تمامی خطوطی که شامل کلمه “sales” هستند را از فایل sales_data.txt استخراج می‌کند.
  • سپس دستور awk '$2 > 1000 {print $2}' فیلد دوم (مقدار فروش) را از داده‌ها استخراج کرده و تنها فروش‌هایی که بیشتر از 1000 دلار هستند را نمایش می‌دهد.
  • در نهایت، این داده‌ها به دستور sort -nr منتقل می‌شود که آن‌ها را به ترتیب نزولی مرتب می‌کند.

نکات مهم:

  1. ترکیب دستورات با پایپ به شما امکان پردازش و فیلتر کردن داده‌ها را به صورت زنجیره‌ای می‌دهد. این تکنیک برای انجام تحلیل‌های پیچیده بر روی داده‌ها بسیار مفید است.
  2. در استفاده از awk و grep، همیشه به ساختار داده‌ها دقت کنید. انتخاب فیلدها و الگوهای جستجو باید بر اساس ساختار دقیق داده‌ها انجام شود.
  3. استفاده از sort همراه با -n برای مرتب‌سازی عددی و -r برای ترتیب معکوس می‌تواند برای مرتب‌سازی داده‌های عددی و متنی مفید باشد.
  4. اجتناب از استفاده از پایپ‌های بیش از حد: استفاده از تعداد زیاد پایپ‌ها ممکن است باعث کاهش کارایی شود. به همین دلیل، بهتر است از ترکیب بهینه‌تری از دستورات استفاده کنید.

جمع‌بندی

در این بخش، نحوه استفاده از پایپ (|) برای ترکیب دستورات مختلف مانند grep، awk و sort را بررسی کردیم. این تکنیک‌ها به شما این امکان را می‌دهند که به راحتی داده‌ها را فیلتر، پردازش و مرتب‌سازی کنید و از آن‌ها برای تحلیل‌های پیچیده و پردازش داده‌ها در سیستم‌های یونیکس و لینوکس استفاده کنید. استفاده از پایپ برای ترکیب دستورات یکی از ابزارهای بسیار قدرتمند برای اتوماسیون و پردازش داده‌ها است.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. تعامل با فایل‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”خواندن محتویات یک فایل با استفاده از cat یا less” subtitle=”توضیحات کامل”]در سیستم‌عامل‌های یونیکس و لینوکس، برای مشاهده محتویات فایل‌ها، دستورات مختلفی وجود دارد. دو دستور پرکاربرد برای این کار، cat و less هستند که هرکدام ویژگی‌های خاص خود را دارند و در شرایط مختلف مورد استفاده قرار می‌گیرند.

دستور cat

دستور cat (که مخفف “concatenate” است) برای نمایش محتویات یک یا چند فایل به صورت پیوسته و کامل در ترمینال استفاده می‌شود. این دستور به طور معمول برای فایل‌های کوچک و زمانی که نیاز به مشاهده سریع محتوای فایل دارید، استفاده می‌شود.

نحوه استفاده:

cat filename

مثال:

اگر شما یک فایل به نام file.txt دارید و می‌خواهید محتویات آن را مشاهده کنید، از دستور زیر استفاده می‌کنید:

cat file.txt

این دستور تمامی محتوای فایل را در ترمینال نمایش می‌دهد. اگر فایل خیلی بزرگ باشد، تمامی اطلاعات آن به صورت یکجا در ترمینال نشان داده می‌شود که می‌تواند خواندن آن را سخت کند.

مشاهده چندین فایل:

شما می‌توانید محتویات چندین فایل را با هم نمایش دهید:

cat file1.txt file2.txt

این دستور محتویات هر دو فایل file1.txt و file2.txt را به صورت پشت سر هم در ترمینال نمایش می‌دهد.

نکات:

  • دستور cat به طور پیش‌فرض محتوای فایل‌ها را بدون هیچ‌گونه صفحه‌بندی یا کنترل نمایش می‌دهد. اگر فایل بزرگ باشد، تمامی محتوای آن به سرعت در ترمینال نمایش داده می‌شود.
  • در صورت نیاز به ذخیره محتویات یک فایل در یک فایل دیگر، می‌توانید از دستور cat با نشانه‌گذاری خروجی استفاده کنید:
    cat file.txt > newfile.txt
    

    این دستور محتوای file.txt را در newfile.txt ذخیره می‌کند.

دستور less

دستور less به شما این امکان را می‌دهد که محتویات یک فایل را به صورت صفحه به صفحه مشاهده کنید. این دستور برای فایل‌های بزرگ مناسب است، زیرا به شما این امکان را می‌دهد که تنها بخش‌هایی از فایل را که نیاز دارید مشاهده کنید، بدون اینکه تمامی محتویات به سرعت در ترمینال نمایش داده شود.

نحوه استفاده:

less filename

مثال:

برای مشاهده محتویات فایل file.txt به صورت صفحه به صفحه:

less file.txt

با استفاده از این دستور:

  • می‌توانید با استفاده از کلیدهای جهت‌نما یا صفحه‌کلید به بالا و پایین بروید.
  • برای جستجو در فایل، می‌توانید از کلید / و سپس عبارت جستجو استفاده کنید.
  • برای خروج از دستور less، کافی است کلید q را فشار دهید.

نکات:

  • less برای فایل‌های بزرگ مناسب‌تر از cat است زیرا به شما این امکان را می‌دهد که محتویات فایل را به راحتی پیمایش کنید.
  • شما می‌توانید از less برای مشاهده خروجی دستورات دیگر نیز استفاده کنید، مانند:
    ls -l | less
    

    این دستور خروجی دستور ls -l را به less می‌فرستد، بنابراین می‌توانید نتایج را به صورت صفحه به صفحه مشاهده کنید.

تفاوت‌ها بین cat و less

ویژگی cat less
نحوه نمایش نمایش همه محتویات به صورت یکجا صفحه به صفحه نمایش داده می‌شود
کاربرد معمول فایل‌های کوچک و نیاز به مشاهده سریع فایل‌های بزرگ و نیاز به پیمایش
جستجو ندارد دارد (با استفاده از /)
پیمایش در فایل ندارد امکان پیمایش به بالا و پایین
خروجی به فایل cat file > newfile.txt نمی‌توان مستقیماً خروجی به فایل نوشت
بهینه برای فایل‌های کوتاه فایل‌های طولانی و بزرگ

جمع‌بندی

در این بخش، دو دستور پرکاربرد برای خواندن محتویات فایل‌ها در شل یعنی cat و less را بررسی کردیم. دستور cat برای مشاهده سریع محتویات فایل‌های کوچک مناسب است، در حالی که دستور less برای مشاهده محتویات فایل‌های بزرگ به صورت صفحه به صفحه و با قابلیت جستجو و پیمایش در فایل، کاربرد دارد. انتخاب بین این دو دستور بستگی به اندازه فایل و نیاز شما به مشاهده سریع یا کنترل بیشتر بر روی نمایش محتویات فایل دارد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”خواندن فایل خط به خط در یک حلقه با استفاده از while و <” subtitle=”توضیحات کامل”]برای خواندن فایل‌ها در شل اسکریپت‌ها به صورت خط به خط، می‌توان از دستور while همراه با ورودی استاندارد (<) استفاده کرد. این روش برای پردازش فایل‌هایی که شامل اطلاعات زیادی هستند بسیار مناسب است، زیرا می‌توانید هر خط از فایل را به صورت جداگانه پردازش کنید.

نحوه استفاده از دستور while برای خواندن خط به خط

دستور while در شل برای تکرار یک بخش از کد تا زمانی که شرط خاصی برقرار باشد استفاده می‌شود. هنگامی که این دستور را با ورودی فایل ترکیب می‌کنید، به راحتی می‌توانید هر خط از فایل را یکی یکی بخوانید و پردازش کنید.

ساختار کلی:

while IFS= read -r line; do
  # پردازش هر خط از فایل
done < filename

در اینجا:

  • IFS= read -r line: برای خواندن هر خط از فایل به صورت کامل و بدون جدا کردن فضاهای اضافی یا کاراکترهای خاص مانند تب (tab) استفاده می‌شود.
  • done < filename: این بخش فایل را به دستور while می‌دهد تا هر خط از آن خوانده شود.

مثال:

فرض کنید یک فایل به نام file.txt دارید که شامل چندین خط است و شما می‌خواهید هر خط از این فایل را چاپ کنید:

#!/bin/bash

# فایل را خط به خط می‌خوانیم
while IFS= read -r line; do
  echo "خط خوانده شده: $line"
done < file.txt

در این اسکریپت:

  • دستور read -r line هر خط از فایل file.txt را می‌خواند.
  • هر خط از فایل با استفاده از دستور echo چاپ می‌شود.

توضیحات:

  1. IFS=: به این معنی است که هیچ کاراکتر جداکننده‌ای برای ورودی در نظر گرفته نمی‌شود. به این ترتیب، فضاها و تب‌ها به عنوان بخشی از خط خوانده می‌شوند.
  2. -r: این گزینه از دستور read برای جلوگیری از تفسیر کاراکترهای خاص مانند \n یا \t استفاده می‌شود. با این گزینه، همه کاراکترها به صورت مستقیم و بدون هیچ تغییراتی خوانده می‌شوند.
  3. ورودی فایل با <: با استفاده از < filename، فایل به عنوان ورودی به حلقه while داده می‌شود.

پردازش محتوای هر خط

پس از اینکه هر خط از فایل خوانده شد، شما می‌توانید آن را پردازش کنید. به عنوان مثال، اگر بخواهید فقط خطوطی را که شامل یک کلمه خاص هستند چاپ کنید، می‌توانید از دستور grep یا دستورات شرطی استفاده کنید.

مثال با شرط:

در این مثال، تنها خطوطی که شامل کلمه “error” هستند چاپ می‌شوند:

#!/bin/bash

while IFS= read -r line; do
  if [[ "$line" == *"error"* ]]; then
    echo "خط شامل کلمه error: $line"
  fi
done < file.txt

در اینجا:

  • دستور if بررسی می‌کند که آیا خط شامل کلمه “error” است یا خیر.
  • اگر کلمه “error” در خط وجود داشته باشد، آن خط چاپ می‌شود.

استفاده از متغیرهای دیگر در داخل حلقه

در صورت نیاز می‌توانید از متغیرهای مختلف برای پردازش خط به خط استفاده کنید. به عنوان مثال، اگر بخواهید تعداد کلماتی که در هر خط وجود دارد را بشمارید، می‌توانید از دستور wc -w استفاده کنید.

مثال:

#!/bin/bash

while IFS= read -r line; do
  word_count=$(echo "$line" | wc -w)
  echo "تعداد کلمات در خط: $word_count"
done < file.txt

در این اسکریپت:

  • برای هر خط از فایل، تعداد کلمات آن با استفاده از دستور wc -w شمارش می‌شود.
  • تعداد کلمات در هر خط چاپ می‌شود.

جمع‌بندی

در این بخش، نحوه خواندن یک فایل به صورت خط به خط با استفاده از حلقه while و ورودی فایل (<) آموزش داده شد. این روش یکی از روش‌های پرکاربرد برای پردازش فایل‌ها در شل است و به شما امکان می‌دهد که هر خط از فایل را به صورت جداگانه پردازش کرده و در صورت نیاز آن را ویرایش، جستجو یا شمارش کنید. همچنین، با استفاده از ترکیب دستورات مختلف مانند grep یا wc می‌توانید پردازش‌های پیچیده‌تری روی هر خط از فایل انجام دهید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پردازش هر خط فایل با دستورات شل” subtitle=”توضیحات کامل”]پردازش هر خط از یک فایل در اسکریپت‌های شل، یکی از مهم‌ترین و رایج‌ترین کارهایی است که در اسکریپت‌نویسی انجام می‌شود. این عملیات معمولاً به کار می‌آید زمانی که نیاز دارید که هر خط از یک فایل متنی را بخوانید و آن را پردازش کنید، مثلاً برای جستجوی الگوها، شمارش کلمات، یا اعمال تغییرات خاص بر روی هر خط.

در این بخش، نحوه پردازش هر خط از یک فایل با استفاده از دستورات مختلف شل را بررسی خواهیم کرد.

خواندن خط به خط فایل

همانطور که در بخش‌های قبلی گفتیم، می‌توانیم از دستور while همراه با read برای خواندن هر خط از یک فایل استفاده کنیم. این روش خط به خط عمل کرده و به ما این امکان را می‌دهد که روی هر خط پردازش‌های مختلفی انجام دهیم.

ساختار کلی این دستور به صورت زیر است:

while IFS= read -r line; do
  # پردازش هر خط
done < filename

در اینجا:

  • IFS= برای جلوگیری از حذف فضاهای اضافی در هر خط استفاده می‌شود.
  • read -r line هر خط از فایل را به صورت کامل خوانده و آن را در متغیر line قرار می‌دهد.
  • در داخل بلوک do ... done، می‌توانیم هر گونه پردازشی که بخواهیم روی line انجام دهیم.

پردازش خطوط با دستورات شل

حالا که با نحوه خواندن خط به خط فایل آشنا شدیم، به بررسی چندین روش مختلف برای پردازش هر خط می‌پردازیم. این پردازش‌ها می‌تواند شامل جستجو، فیلتر کردن، و تغییرات روی متن باشد.

1. جستجو و فیلتر کردن با grep

اگر بخواهید تنها خطوطی را که شامل یک عبارت خاص هستند پردازش کنید، می‌توانید از دستور grep برای فیلتر کردن خطوط استفاده کنید. به این ترتیب، تنها خطوطی که شامل الگوی خاصی هستند، به پردازش شما وارد خواهند شد.

#!/bin/bash

while IFS= read -r line; do
  if echo "$line" | grep -q "error"; then
    echo "خط شامل 'error': $line"
  fi
done < file.txt

در این اسکریپت:

  • دستور grep -q "error" بررسی می‌کند که آیا عبارت “error” در خط وجود دارد یا خیر.
  • اگر عبارت پیدا شود، آن خط چاپ می‌شود.

2. شمارش کلمات در هر خط با wc -w

اگر نیاز دارید که تعداد کلمات موجود در هر خط را بشمارید، می‌توانید از دستور wc -w برای شمارش کلمات استفاده کنید.

#!/bin/bash

while IFS= read -r line; do
  word_count=$(echo "$line" | wc -w)
  echo "تعداد کلمات در خط: $word_count"
done < file.txt

در اینجا:

  • wc -w تعداد کلمات را در هر خط شمارش می‌کند.
  • نتیجه شمارش در متغیر word_count ذخیره می‌شود و سپس چاپ می‌شود.

3. تقسیم و پردازش بخش‌های مختلف خط

گاهی ممکن است بخواهید که یک خط را به چند بخش تقسیم کنید. برای این کار می‌توانید از دستور awk یا استفاده از IFS برای تقسیم خط به اجزای مختلف استفاده کنید.

#!/bin/bash

while IFS= read -r line; do
  # فرض کنید هر خط شامل نام و سن افراد است (نام، سن)
  IFS=" " read -r name age <<< "$line"
  echo "نام: $name، سن: $age"
done < file.txt

در اینجا:

  • از IFS=" " برای تعیین جداکننده (در اینجا فاصله) استفاده کرده‌ایم تا خط به دو قسمت تقسیم شود.
  • سپس نام و سن را به متغیرهای name و age اختصاص داده و آنها را چاپ می‌کنیم.

4. جایگزینی کلمات با sed

اگر نیاز دارید که در هر خط یک کلمه را با کلمه‌ای دیگر جایگزین کنید، می‌توانید از دستور sed استفاده کنید.

#!/bin/bash

while IFS= read -r line; do
  # جایگزینی کلمه "old" با "new"
  new_line=$(echo "$line" | sed 's/old/new/g')
  echo "$new_line"
done < file.txt

در اینجا:

  • دستور sed 's/old/new/g' هر کلمه “old” را با “new” جایگزین می‌کند.
  • نتیجه جایگزینی در متغیر new_line ذخیره می‌شود و سپس چاپ می‌شود.

5. پردازش داده‌های عددی

اگر در فایل شما داده‌های عددی وجود دارد و بخواهید عملیات ریاضی انجام دهید، می‌توانید از دستورات ریاضی شل استفاده کنید.

#!/bin/bash

while IFS= read -r line; do
  # فرض کنید هر خط شامل دو عدد است
  IFS=" " read -r num1 num2 <<< "$line"
  sum=$((num1 + num2))
  echo "جمع: $sum"
done < file.txt

در اینجا:

  • دو عدد از هر خط با استفاده از read جدا می‌شوند.
  • سپس با استفاده از (( ... )) جمع آنها محاسبه شده و چاپ می‌شود.

جمع‌بندی

پردازش هر خط از یک فایل در شل با استفاده از دستور while و read یک روش بسیار کارآمد و انعطاف‌پذیر برای انجام عملیات مختلف روی فایل‌های متنی است. شما می‌توانید از این روش برای جستجو و فیلتر کردن، شمارش کلمات، تقسیم خطوط به بخش‌های مختلف، جایگزینی کلمات و انجام محاسبات عددی استفاده کنید. با ترکیب این دستورات با دیگر ابزارهای شل مانند grep, awk, sed و wc می‌توانید پردازش‌های پیچیده‌ای را به راحتی انجام دهید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. خواندن چندین خط از فایل”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از دستور read با گزینه‌های مختلف برای پردازش چندین خط” subtitle=”توضیحات کامل”]دستور read یکی از مهم‌ترین و پرکاربردترین دستورات در اسکریپت‌نویسی شل است که برای خواندن ورودی از کاربر یا از فایل‌ها به کار می‌رود. علاوه بر این، دستور read می‌تواند با استفاده از گزینه‌های مختلف به صورت پیشرفته‌تری برای پردازش چندین خط استفاده شود.

در این بخش، با استفاده از دستور read و گزینه‌های مختلف، نحوه پردازش چندین خط از ورودی‌ها یا فایل‌ها را بررسی خواهیم کرد.

ساختار عمومی دستور read

ساختار معمول استفاده از دستور read به صورت زیر است:

read [options] variable

در اینجا:

  • [options] به گزینه‌های مختلفی اشاره دارد که می‌توان به دستور read اضافه کرد.
  • variable متغیری است که مقداری که از ورودی خوانده شده در آن ذخیره می‌شود.

گزینه‌های مختلف دستور read

دستور read با استفاده از گزینه‌های مختلف می‌تواند به شکلی متفاوت از حالت معمول عمل کند. در اینجا برخی از گزینه‌های مهم دستور read را بررسی می‌کنیم.

1. گزینه -r: جلوگیری از پردازش کاراکترهای خاص

به طور پیش‌فرض، دستور read کاراکترهای خاص مانند بک‌اسلش \ را به عنوان escape characters تفسیر می‌کند. اما با استفاده از گزینه -r می‌توانید این رفتار را غیرفعال کنید و هر ورودی را به صورت خام و بدون پردازش دریافت کنید.

#!/bin/bash

echo "لطفاً خطی وارد کنید:"
read -r input
echo "ورودی شما: $input"

در اینجا:

  • گزینه -r باعث می‌شود که هیچ کاراکتر escape پردازش نشود، بنابراین کاراکترهایی مانند \ به صورت معمولی در نظر گرفته می‌شوند.

2. گزینه -a: ذخیره‌سازی ورودی‌ها در یک آرایه

اگر بخواهید ورودی‌های مختلف را در یک آرایه ذخیره کنید، می‌توانید از گزینه -a استفاده کنید. این گزینه تمام ورودی‌ها را به عناصر مختلف یک آرایه اختصاص می‌دهد.

#!/bin/bash

echo "لطفاً چند کلمه وارد کنید:"
read -a words
echo "کلمات وارد شده: ${words[0]}, ${words[1]}, ${words[2]}"

در اینجا:

  • ورودی‌های مختلف که توسط کاربر وارد می‌شوند، به عناصر مختلف آرایه words اختصاص می‌یابند.
  • شما می‌توانید به هر کلمه وارد شده به صورت جداگانه دسترسی پیدا کنید.

3. گزینه -d: تعیین جداکننده برای ورودی‌ها

به طور پیش‌فرض، دستور read ورودی را تا رسیدن به خط جدید (newline) می‌خواند. با استفاده از گزینه -d می‌توانید یک جداکننده دیگر برای پایان ورودی تعیین کنید. برای مثال، ممکن است بخواهید ورودی را تا رسیدن به کاراکتری خاص مانند کاما یا هر کاراکتر دیگری بخوانید.

#!/bin/bash

echo "لطفاً ورودی را وارد کنید (با استفاده از ویرگول جدا کنید):"
read -d "," input
echo "ورودی شما: $input"

در اینجا:

  • گزینه -d "," باعث می‌شود که دستور read ورودی را تا رسیدن به کاما بخواند و سپس آن را در متغیر input ذخیره کند.

4. گزینه -n: خواندن تعداد مشخصی از کاراکترها

اگر بخواهید تنها تعداد معینی از کاراکترها را از ورودی بخوانید، می‌توانید از گزینه -n استفاده کنید.

#!/bin/bash

echo "لطفاً 5 کاراکتر وارد کنید:"
read -n 5 input
echo "ورودی شما: $input"

در اینجا:

  • گزینه -n 5 باعث می‌شود که تنها 5 کاراکتر از ورودی خوانده شود.

5. گزینه -e: فعال کردن قابلیت تکمیل خودکار

در برخی شل‌ها مانند bash، می‌توانید از گزینه -e برای فعال کردن قابلیت تکمیل خودکار استفاده کنید. این ویژگی به شما این امکان را می‌دهد که با فشردن دکمه Tab، تکمیل خودکار ورودی را فعال کنید.

#!/bin/bash

echo "لطفاً یک مسیر وارد کنید:"
read -e input
echo "مسیر وارد شده: $input"

در اینجا:

  • گزینه -e باعث می‌شود که از قابلیت تکمیل خودکار در ورودی استفاده شود (برای مثال مسیرهای فایل).

6. گزینه -p: چاپ یک پیام قبل از دریافت ورودی

اگر بخواهید که پیش از دریافت ورودی از کاربر، یک پیام خاص چاپ شود، می‌توانید از گزینه -p استفاده کنید.

#!/bin/bash

read -p "لطفاً نام خود را وارد کنید: " name
echo "سلام، $name!"

در اینجا:

  • گزینه -p پیام “لطفاً نام خود را وارد کنید: ” را قبل از دریافت ورودی چاپ می‌کند.

پردازش چندین خط با دستور read

یکی از رایج‌ترین کاربردهای دستور read زمانی است که بخواهید چندین خط را از یک فایل یا ورودی بخوانید و آن‌ها را پردازش کنید. این کار می‌تواند با استفاده از دستور while و دستور read انجام شود.

در اینجا یک مثال برای خواندن هر خط از یک فایل و پردازش آن آورده شده است:

#!/bin/bash

while IFS= read -r line; do
  echo "خط خوانده شده: $line"
done < file.txt

در اینجا:

  • دستور while IFS= read -r line هر خط از فایل file.txt را می‌خواند و آن را در متغیر line ذخیره می‌کند.
  • سپس محتوای هر خط چاپ می‌شود.

جمع‌بندی

دستور read در شل به شما این امکان را می‌دهد که ورودی‌های مختلف را از کاربر یا فایل‌ها بخوانید و پردازش کنید. با استفاده از گزینه‌های مختلف این دستور، می‌توانید ورودی‌ها را به شکلی انعطاف‌پذیر و پیشرفته‌تر پردازش کنید. به ویژه، گزینه‌هایی مانند -r, -a, -d, -n, -e, و -p می‌توانند به شما کمک کنند تا ورودی‌ها را مطابق نیاز خود پردازش کرده و به شکلی مؤثرتر از آن‌ها استفاده کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مدیریت خطوط طولانی با استفاده از IFS” subtitle=”توضیحات کامل”]یکی از مشکلات رایجی که در هنگام پردازش ورودی‌ها و فایل‌ها در شل به وجود می‌آید، مدیریت خطوط طولانی است. شل معمولاً برای پردازش داده‌ها از یک جداکننده (delimiter) به نام IFS (Internal Field Separator) استفاده می‌کند. این جداکننده مشخص می‌کند که چطور باید ورودی‌ها به بخش‌های مختلف تقسیم شوند. به‌طور پیش‌فرض، IFS به صورت فضای خالی، تب و خط جدید تنظیم شده است.

در این بخش، نحوه استفاده از IFS برای مدیریت خطوط طولانی را بررسی خواهیم کرد. این موضوع زمانی مفید است که شما نیاز دارید داده‌های طولانی را به بخش‌های مختلف تقسیم کرده و پردازش کنید.

مفهوم IFS (Internal Field Separator)

متغیر IFS در شل برای تعیین کاراکترهای جداکننده بین بخش‌های مختلف ورودی به کار می‌رود. به طور پیش‌فرض، این متغیر به صورت زیر تنظیم شده است:

IFS=" \t\n"

یعنی فضای خالی، تب (\t) و خط جدید (\n) به عنوان جداکننده‌های پیش‌فرض در نظر گرفته می‌شوند. به همین دلیل، زمانی که ورودی به دستور read داده می‌شود، شل آن را به بخش‌های مختلف تقسیم می‌کند و هر بخش را به یک متغیر اختصاص می‌دهد.

مدیریت خطوط طولانی با تغییر مقدار IFS

در بسیاری از مواقع، خطوط طولانی ورودی می‌توانند مشکل‌ساز باشند، زیرا ممکن است شامل کاراکترهایی مانند فاصله‌های اضافی باشند که شل آن‌ها را به عنوان جداکننده‌ها در نظر بگیرد و باعث تقسیم شدن غیرمنتظره ورودی شود. با تغییر مقدار IFS می‌توانید این مشکل را برطرف کنید.

فرض کنید ورودی‌ای دارید که شامل فیلدهایی با فاصله‌های طولانی است و نمی‌خواهید فاصله‌ها باعث تقسیم نامطلوب داده‌ها شوند. برای این کار می‌توانید IFS را به یک مقدار مناسب تغییر دهید.

مثال 1: تغییر IFS برای جلوگیری از تقسیم غیرمنتظره

#!/bin/bash

# تنظیم IFS به خط جدید برای جلوگیری از تقسیم داده‌ها بر اساس فاصله
IFS=$'\n'

long_line="این یک خط بسیار طولانی است که شامل فاصله‌های زیادی می‌باشد و نمی‌خواهیم این فاصله‌ها موجب تقسیم شود."

# استفاده از دستور read برای خواندن ورودی
read -r line <<< "$long_line"

echo "خط خوانده شده: $line"

در اینجا:

  • مقدار IFS به \n تغییر داده شده است تا فقط خط جدید به عنوان جداکننده عمل کند.
  • این کار باعث می‌شود که فاصله‌ها در داخل خط تاثیری در پردازش داده‌ها نداشته باشند.
  • ورودی به صورت یک خط کامل در متغیر line ذخیره می‌شود.

مثال 2: استفاده از IFS برای پردازش داده‌های طولانی به صورت صحیح

فرض کنید شما یک فایل دارید که شامل داده‌های طولانی است و می‌خواهید این داده‌ها را به بخش‌های مختلف تقسیم کنید. با استفاده از IFS می‌توانید این کار را به راحتی انجام دهید.

#!/bin/bash

# تنظیم IFS به کاما برای تقسیم داده‌ها
IFS=','

long_line="آب,برنج,سبزی,گوشت,میوه"

# استفاده از دستور read برای خواندن ورودی و تقسیم آن به بخش‌های مختلف
read -r -a items <<< "$long_line"

# چاپ داده‌های تقسیم شده
echo "آب: ${items[0]}"
echo "برنج: ${items[1]}"
echo "سبزی: ${items[2]}"
echo "گوشت: ${items[3]}"
echo "میوه: ${items[4]}"

در اینجا:

  • مقدار IFS به کاما (',') تنظیم شده است تا ورودی بر اساس کاما تقسیم شود.
  • ورودی به آرایه items تقسیم شده و هر بخش به صورت جداگانه در متغیرهای آرایه ذخیره می‌شود.
  • سپس هر یک از بخش‌ها چاپ می‌شود.

پردازش خطوط طولانی در فایل‌ها

اگر بخواهید خطوط طولانی را در یک فایل پردازش کنید و مطمئن شوید که فضای خالی یا کاراکترهای اضافی به درستی مدیریت می‌شوند، می‌توانید از IFS همراه با دستور while استفاده کنید. این روش به شما این امکان را می‌دهد که ورودی‌ها را خط به خط پردازش کرده و از مشکلات مربوط به خطوط طولانی جلوگیری کنید.

#!/bin/bash

# تنظیم IFS به خط جدید
IFS=$'\n'

# خواندن فایل خط به خط
while read -r line; do
  # پردازش خط
  echo "خط خوانده شده: $line"
done < long_file.txt

در اینجا:

  • دستور while به شما این امکان را می‌دهد که فایل long_file.txt را خط به خط بخوانید.
  • مقدار IFS به خط جدید (\n) تغییر داده شده تا خطوط طولانی به درستی خوانده شوند.
  • هر خط از فایل در متغیر line ذخیره شده و سپس پردازش می‌شود.

مثال 3: استفاده از IFS برای پردازش داده‌های پیچیده

گاهی اوقات ورودی‌های شما ممکن است شامل کاراکترهای خاصی باشند که باید به صورت جداگانه از هم جدا شوند. به‌طور مثال، داده‌هایی که از چندین فیلد با کاراکترهای ویژه مانند کاراکترهای فاصله و کاما تشکیل شده‌اند.

#!/bin/bash

# تنظیم IFS به فاصله و کاما
IFS=', '

line="نام, شغل, سن, محل زندگی"

# خواندن ورودی و تقسیم آن به بخش‌های مختلف
read -r name job age location <<< "$line"

# چاپ بخش‌های مختلف
echo "نام: $name"
echo "شغل: $job"
echo "سن: $age"
echo "محل زندگی: $location"

در اینجا:

  • مقدار IFS به فاصله و کاما تغییر یافته است تا داده‌ها بر اساس این دو جداکننده تقسیم شوند.
  • هر بخش از ورودی به طور جداگانه در متغیرهای name, job, age و location ذخیره می‌شود.

جمع‌بندی

در شل اسکریپت‌نویسی، مدیریت خطوط طولانی یکی از چالش‌های رایج است که می‌تواند با استفاده از متغیر IFS به سادگی برطرف شود. با تغییر مقدار IFS، می‌توان جداکننده‌های مورد نظر را مشخص کرده و از پردازش نامناسب ورودی‌ها جلوگیری کرد. این کار در مواقعی که نیاز به پردازش داده‌های پیچیده یا خطوط طولانی وجود دارد، بسیار مفید است. تنظیم صحیح IFS برای مدیریت خطوط طولانی می‌تواند به شما کمک کند تا داده‌ها را به درستی پردازش کرده و از مشکلات مربوط به تقسیم‌بندی غیرمنتظره جلوگیری کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 7. نوشتن داده‌ها در فایل‌های موقتی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ایجاد فایل‌های موقتی با استفاده از دستورات mktemp و tempfile” subtitle=”توضیحات کامل”]در بسیاری از موارد، در اسکریپت‌نویسی نیاز به ایجاد فایل‌های موقتی برای ذخیره‌سازی داده‌ها، نتایج موقت، یا انجام پردازش‌های موقتی وجود دارد. این فایل‌ها معمولاً پس از اتمام پردازش باید حذف شوند. در شل، برای ایجاد چنین فایل‌هایی از دستورات mktemp و tempfile می‌توان استفاده کرد. این دستورات به شما کمک می‌کنند تا به راحتی فایل‌های موقتی امن و قابل مدیریت بسازید.

دستور mktemp

دستور mktemp برای ایجاد فایل‌های موقتی استفاده می‌شود. این دستور یک فایل موقتی با نامی منحصر به فرد و بدون تداخل با سایر فایل‌ها ایجاد می‌کند. معمولاً از این دستور برای جلوگیری از برخورد نام‌ها و ایجاد فایل‌های امن استفاده می‌شود.

ساختار کلی دستور mktemp:

mktemp [اختیاری]

مثال 1: ایجاد فایل موقتی با استفاده از mktemp

در این مثال، از دستور mktemp برای ایجاد یک فایل موقتی استفاده می‌کنیم:

#!/bin/bash

# ایجاد یک فایل موقتی
temp_file=$(mktemp)

echo "این یک فایل موقتی است: $temp_file"

# انجام پردازش‌ها و ذخیره‌سازی داده‌ها در فایل موقتی
echo "داده‌های موقتی" > "$temp_file"

# نمایش محتویات فایل موقتی
cat "$temp_file"

# حذف فایل موقتی پس از اتمام پردازش
rm "$temp_file"

در اینجا:

  • دستور mktemp یک فایل موقتی با نامی منحصر به فرد ایجاد می‌کند.
  • از متغیر temp_file برای ذخیره مسیر فایل موقتی استفاده می‌شود.
  • پس از استفاده از فایل، آن را با دستور rm حذف می‌کنیم.

گزینه‌های مختلف دستور mktemp

  1. استفاده از پیشوند و پسوند خاص برای نام فایل موقتی: شما می‌توانید پیشوند یا پسوند خاصی را به نام فایل موقتی اضافه کنید. به عنوان مثال:
    temp_file=$(mktemp temp_XXXXXX.txt)
    

    در اینجا، temp_XXXXXX.txt به عنوان الگوی نام فایل استفاده می‌شود. شل به طور خودکار قسمت XXXXXX را با کاراکترهای تصادفی پر خواهد کرد.

  2. ایجاد دایرکتوری موقتی: اگر بخواهید یک دایرکتوری موقتی ایجاد کنید، می‌توانید از گزینه -d استفاده کنید:
    temp_dir=$(mktemp -d)
    echo "دایرکتوری موقتی: $temp_dir"
    

    این دستور یک دایرکتوری موقتی ایجاد می‌کند که می‌توانید فایل‌ها را در آن ذخیره کنید.

دستور tempfile

دستور tempfile نیز برای ایجاد فایل‌های موقتی استفاده می‌شود، اما استفاده از آن کمی قدیمی‌تر و در برخی از سیستم‌ها ممکن است محدود باشد. این دستور یک فایل موقتی با یک نام منحصر به فرد ایجاد می‌کند و به طور خودکار این فایل را باز می‌کند تا بتوانید در آن داده‌ها را بنویسید. دستور tempfile در اکثر توزیع‌های لینوکس به صورت پیش‌فرض نصب نشده است، اما در صورتی که نصب باشد، می‌تواند جایگزین خوبی برای mktemp باشد.

ساختار کلی دستور tempfile:

tempfile

مثال 2: ایجاد فایل موقتی با استفاده از tempfile

#!/bin/bash

# ایجاد یک فایل موقتی با استفاده از tempfile
temp_file=$(tempfile)

echo "این یک فایل موقتی است که با tempfile ساخته شده است: $temp_file"

# نوشتن داده در فایل موقتی
echo "داده‌های موقتی با tempfile" > "$temp_file"

# نمایش محتویات فایل موقتی
cat "$temp_file"

# حذف فایل موقتی پس از اتمام پردازش
rm "$temp_file"

در اینجا:

  • دستور tempfile یک فایل موقتی می‌سازد که می‌توانید در آن داده‌ها را ذخیره کنید.
  • پس از انجام پردازش‌ها، فایل با دستور rm حذف می‌شود.

مزایای استفاده از mktemp و tempfile

  1. امنیت: استفاده از mktemp و tempfile به شما کمک می‌کند که فایل‌های موقتی را به صورت امن ایجاد کنید. این دستورات نام‌های منحصر به فرد برای فایل‌ها انتخاب می‌کنند که خطر تصادفی بازنویسی فایل‌ها یا برخورد نام‌ها را کاهش می‌دهد.
  2. مدیریت ساده: این دستورات به شما این امکان را می‌دهند که فایل‌ها یا دایرکتوری‌های موقتی بسازید و پس از اتمام پردازش‌ها آن‌ها را حذف کنید.
  3. صرفه‌جویی در منابع: ایجاد فایل‌های موقتی برای ذخیره‌سازی داده‌ها یا نتایج موقتی به شما کمک می‌کند که نیازی به استفاده از فضای دائمی یا پایگاه داده برای این داده‌ها نباشید.

جمع‌بندی

در این بخش، نحوه ایجاد فایل‌های موقتی با استفاده از دستورات mktemp و tempfile بررسی شد. این دستورات به شما امکان می‌دهند فایل‌هایی امن و منحصر به فرد بسازید که می‌توانید در اسکریپت‌های خود از آن‌ها برای ذخیره‌سازی موقت داده‌ها استفاده کنید. دستور mktemp به دلیل داشتن گزینه‌های متعدد مانند تنظیم پیشوند و پسوند برای فایل‌ها، گزینه‌ای قدرتمند و پرکاربرد است. استفاده از این دستورات برای جلوگیری از برخورد نام فایل‌ها و مدیریت بهتر منابع بسیار مهم است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نوشتن خروجی در فایل موقتی و بازیابی آن” subtitle=”توضیحات کامل”]در سیستم‌های مبتنی بر یونیکس، ممکن است نیاز داشته باشید که در حین اجرای اسکریپت‌ها یا برنامه‌ها خروجی‌ها را به صورت موقت ذخیره کنید و سپس آن‌ها را برای استفاده‌های بعدی بازیابی کنید. این کار معمولاً با استفاده از فایل‌های موقتی (Temporary Files) انجام می‌شود. این فایل‌ها به شما این امکان را می‌دهند که داده‌ها را موقتا ذخیره کنید و پس از اتمام پردازش، آن‌ها را حذف کنید.

در این بخش، به نحوه نوشتن خروجی در فایل‌های موقتی و بازیابی آن‌ها پرداخته می‌شود.

1. استفاده از دستور mktemp

دستور mktemp برای ایجاد فایل‌های موقتی استفاده می‌شود. این دستور معمولاً یک نام فایل منحصربه‌فرد تولید می‌کند و آن را در مسیر مشخص شده ذخیره می‌کند.

مثال:

tempfile=$(mktemp /tmp/tempfile.XXXXXX)
echo "Hello, this is a temporary file" > "$tempfile"
cat "$tempfile"
rm "$tempfile"

در اینجا:

  • mktemp /tmp/tempfile.XXXXXX یک فایل موقت با نام منحصربه‌فرد در مسیر /tmp ایجاد می‌کند.
  • دستور echo محتوای “Hello, this is a temporary file” را در فایل موقت می‌نویسد.
  • دستور cat محتوای فایل موقت را نمایش می‌دهد.
  • دستور rm فایل موقت را پس از استفاده حذف می‌کند.

2. استفاده از دستور tempfile

دستور tempfile نیز مشابه mktemp است و برای ایجاد فایل‌های موقتی استفاده می‌شود. این دستور فایل‌های موقتی را در مسیر پیش‌فرض ذخیره می‌کند و به شما امکان می‌دهد که محتویات را در آن‌ها بنویسید.

مثال:

tempfile=$(tempfile)
echo "Temporary file content" > "$tempfile"
cat "$tempfile"
rm "$tempfile"

در اینجا:

  • دستور tempfile یک فایل موقت ایجاد می‌کند.
  • دستور echo محتوای “Temporary file content” را به فایل موقت می‌نویسد.
  • دستور cat محتوای فایل موقت را نمایش می‌دهد.
  • دستور rm فایل موقت را پس از استفاده حذف می‌کند.

3. استفاده از متغیرهای محیطی برای ذخیره داده‌ها در فایل‌های موقتی

در برخی موارد، ممکن است بخواهید فایل‌های موقتی را به صورت داینامیک از طریق متغیرهای محیطی یا دستورات اسکریپت ایجاد کنید.

مثال:

tempfile=$(mktemp)
echo "Storing temporary data" > "$tempfile"
data=$(cat "$tempfile")
echo "The data from the temporary file: $data"
rm "$tempfile"

در اینجا:

  • دستور mktemp یک فایل موقتی بدون مسیر مشخص ایجاد می‌کند.
  • دستور echo محتوای “Storing temporary data” را در فایل موقت می‌نویسد.
  • دستور cat برای خواندن محتویات فایل موقت استفاده می‌شود.
  • دستور echo محتوای فایل موقت را چاپ می‌کند.
  • دستور rm فایل موقت را پس از استفاده حذف می‌کند.

4. بازیابی فایل‌های موقتی

پس از نوشتن داده‌ها به فایل موقت، ممکن است نیاز داشته باشید که این فایل‌ها را برای پردازش‌های بعدی بازخوانی کنید. در این موارد، می‌توانید از دستور cat یا هر دستور دیگری برای خواندن داده‌ها از فایل موقت استفاده کنید.

مثال:

tempfile=$(mktemp)
echo "This is some temporary data" > "$tempfile"
# بازیابی داده‌ها از فایل موقت
retrieved_data=$(cat "$tempfile")
echo "Retrieved data: $retrieved_data"
rm "$tempfile"

در اینجا:

  • داده‌ها به فایل موقت نوشته می‌شوند.
  • پس از آن، با استفاده از دستور cat داده‌ها از فایل موقت خوانده می‌شوند و در متغیر retrieved_data ذخیره می‌شوند.
  • سپس داده‌های بازیابی شده نمایش داده می‌شوند.
  • در نهایت، فایل موقت حذف می‌شود.

جمع بندی

  • فایل‌های موقتی ابزار مفیدی برای ذخیره‌سازی داده‌ها به صورت موقت در شل اسکریپت‌ها هستند.
  • دستور mktemp برای ایجاد فایل‌های موقتی با نام‌های منحصربه‌فرد استفاده می‌شود.
  • دستور tempfile مشابه mktemp است و برای ایجاد فایل‌های موقتی استفاده می‌شود.
  • پس از نوشتن داده‌ها در فایل موقت، می‌توان آن‌ها را با دستور cat یا روش‌های دیگر بازیابی کرد.
  • استفاده از فایل‌های موقتی به شما امکان می‌دهد که داده‌ها را بدون نیاز به ذخیره‌سازی دائمی مدیریت کنید.

[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پاک کردن فایل‌های موقتی پس از استفاده” subtitle=”توضیحات کامل”]در بسیاری از اسکریپت‌ها و فرآیندهای شل، ممکن است نیاز به ایجاد فایل‌های موقتی برای ذخیره‌سازی داده‌ها به صورت موقت وجود داشته باشد. با این حال، پس از اتمام کار با این فایل‌ها، باید این فایل‌ها را پاک کرد تا از بروز مشکلات مربوط به مصرف فضای دیسک و یا نشت داده‌ها جلوگیری شود. به همین دلیل، پاک‌سازی فایل‌های موقتی بعد از استفاده یک مرحله مهم است.

در این بخش به نحوه پاک کردن فایل‌های موقتی پس از استفاده در شل پرداخته خواهد شد.

1. استفاده از دستور rm برای حذف فایل‌های موقتی

برای حذف فایل‌های موقتی پس از استفاده، ساده‌ترین روش استفاده از دستور rm است. دستور rm برای حذف فایل‌ها و دایرکتوری‌ها به کار می‌رود.

مثال:

tempfile=$(mktemp /tmp/tempfile.XXXXXX)
echo "This is a temporary file" > "$tempfile"
cat "$tempfile"
rm "$tempfile"  # حذف فایل موقت

در این مثال:

  • دستور mktemp یک فایل موقتی ایجاد می‌کند.
  • داده‌هایی در این فایل نوشته می‌شود.
  • پس از استفاده از فایل (مثلاً با دستور cat)، فایل موقت با استفاده از دستور rm حذف می‌شود.

2. استفاده از trap برای پاک‌سازی خودکار فایل‌های موقتی

در برخی مواقع، ممکن است بخواهید فایل‌های موقتی را به‌طور خودکار پس از اتمام اسکریپت پاک کنید، به خصوص زمانی که اسکریپت در حال انجام چندین عملیات است. دستور trap در شل می‌تواند به شما کمک کند تا فایل‌های موقتی را در صورت بروز خطا یا پس از پایان اجرای اسکریپت حذف کنید.

مثال:

tempfile=$(mktemp /tmp/tempfile.XXXXXX)

# استفاده از دستور trap برای حذف فایل موقت در صورت بروز خطا یا پایان اسکریپت
trap "rm -f $tempfile" EXIT

echo "Temporary data written to $tempfile"
cat "$tempfile"
# فایل موقت به‌طور خودکار پس از اتمام اسکریپت حذف می‌شود

در اینجا:

  • دستور trap با گزینه EXIT برای اطمینان از حذف فایل موقت هنگام اتمام اسکریپت تنظیم شده است.
  • حتی در صورتی که اسکریپت با خطا مواجه شود، دستور trap فایل موقت را حذف می‌کند.

3. استفاده از mktemp در ترکیب با trap

دستور mktemp به‌طور خودکار یک فایل موقت با نام منحصربه‌فرد ایجاد می‌کند. اگر می‌خواهید این فایل را پس از اتمام کار حذف کنید، می‌توانید دستور trap را با mktemp ترکیب کنید.

مثال:

tempfile=$(mktemp)

# تنظیم trap برای حذف خودکار فایل موقت
trap "rm -f $tempfile" EXIT

echo "Temporary content stored in $tempfile"
echo "Temporary content" > "$tempfile"
cat "$tempfile"

# فایل موقت حذف می‌شود پس از اتمام اسکریپت

در اینجا:

  • پس از ایجاد فایل موقت، دستور trap فایل موقت را پس از اتمام اسکریپت حذف می‌کند.
  • این کار باعث می‌شود که از فراموش کردن حذف فایل‌ها جلوگیری شود.

4. بررسی وجود فایل موقت قبل از حذف

گاهی اوقات ممکن است بخواهید قبل از حذف فایل‌های موقتی از وجود آن‌ها مطمئن شوید. به این صورت می‌توانید از دستور -f در کنار rm برای جلوگیری از خطا در صورت نبود فایل استفاده کنید.

مثال:

tempfile=$(mktemp)

# بررسی وجود فایل قبل از حذف
if [ -f "$tempfile" ]; then
    rm "$tempfile"
    echo "Temporary file deleted."
else
    echo "No temporary file to delete."
fi

در اینجا:

  • ابتدا بررسی می‌شود که آیا فایل موقت وجود دارد یا خیر.
  • در صورت وجود فایل، آن را حذف می‌کنیم.

جمع بندی

  • برای حذف فایل‌های موقتی، از دستور rm استفاده می‌شود که فایل‌ها را پاک می‌کند.
  • دستور trap امکان حذف خودکار فایل‌های موقتی را پس از پایان اسکریپت یا در صورت بروز خطا فراهم می‌آورد.
  • ترکیب mktemp با trap به شما این امکان را می‌دهد که به‌طور خودکار فایل‌های موقتی را مدیریت کنید.
  • همچنین می‌توانید قبل از حذف فایل، بررسی کنید که آیا فایل موقتی وجود دارد یا نه، تا از بروز خطاهای احتمالی جلوگیری کنید.
  • همیشه پس از استفاده از فایل‌های موقتی آن‌ها را پاک کنید تا از مشکلات مربوط به فضای دیسک و نگهداری داده‌های غیرضروری جلوگیری کنید.

[/cdb_course_lesson][cdb_course_lesson title=”فصل 8. کار با ورودی‌های استاندارد (stdin)”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”دریافت ورودی از کاربر به‌صورت مستقیم از کنسول” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، گاهی اوقات نیاز است که ورودی‌هایی از کاربر به‌طور مستقیم از کنسول دریافت کنید. این ورودی‌ها می‌توانند شامل داده‌هایی باشند که اسکریپت شما برای انجام پردازش‌های خاص به آن‌ها نیاز دارد. برای این کار، شل دستوراتی را فراهم کرده است که به شما این امکان را می‌دهد تا از کاربر داده‌ها را بخواهید و در اسکریپت خود از آن‌ها استفاده کنید.

1. استفاده از دستور read

دستور read یکی از رایج‌ترین و ساده‌ترین دستورات برای دریافت ورودی از کاربر در شل است. با استفاده از این دستور، می‌توانید ورودی کاربر را در یک متغیر ذخیره کنید و از آن در قسمت‌های مختلف اسکریپت استفاده کنید.

مثال ساده:

echo "Enter your name:"
read name
echo "Hello, $name!"

در این مثال:

  • ابتدا با استفاده از echo از کاربر خواسته می‌شود که نام خود را وارد کند.
  • سپس دستور read ورودی کاربر را در متغیر name ذخیره می‌کند.
  • در نهایت، با استفاده از echo نام وارد شده به‌عنوان پیام نمایش داده می‌شود.

2. دریافت ورودی بدون نمایش داده‌ها (برای رمز عبور)

اگر نیاز دارید که ورودی کاربر را دریافت کنید و به‌طور خاص نخواهید که این ورودی در کنسول نمایش داده شود (مثلاً برای دریافت رمز عبور)، می‌توانید از گزینه -s برای دستور read استفاده کنید.

مثال:

echo "Enter your password:"
read -s password
echo "Your password has been set."

در این مثال:

  • گزینه -s به دستور read اضافه شده است که باعث می‌شود ورودی کاربر نمایش داده نشود.
  • این روش معمولاً برای دریافت رمز عبور از کاربر استفاده می‌شود.

3. تعیین مقدار پیش‌فرض در صورت وارد نکردن ورودی

در برخی موارد ممکن است بخواهید که یک مقدار پیش‌فرض برای ورودی کاربر تعیین کنید تا در صورتی که کاربر هیچ ورودی نداد، از آن مقدار استفاده شود. این کار با استفاده از دستور read و تنظیم یک مقدار پیش‌فرض برای متغیر انجام می‌شود.

مثال:

echo "Enter your favorite color (default is blue):"
read color
color=${color:-blue}  # اگر ورودی خالی باشد، مقدار پیش‌فرض blue استفاده می‌شود
echo "Your favorite color is $color."

در اینجا:

  • از دستور read برای دریافت ورودی استفاده می‌شود.
  • اگر کاربر هیچ ورودی ندهد (یعنی ورودی خالی باشد)، مقدار پیش‌فرض blue به متغیر color اختصاص می‌یابد.

4. دریافت چندین ورودی در یک خط

برای دریافت چندین ورودی از کاربر در یک خط، می‌توانید از دستور read با لیست متغیرها استفاده کنید. این کار به شما این امکان را می‌دهد که چندین مقدار را از کاربر بگیرید و آن‌ها را در متغیرهای مختلف ذخیره کنید.

مثال:

echo "Enter your first name and last name:"
read first_name last_name
echo "Hello, $first_name $last_name!"

در این مثال:

  • از دستور read برای دریافت نام و نام خانوادگی در یک خط استفاده می‌شود.
  • ورودی‌های داده شده توسط کاربر به ترتیب در متغیرهای first_name و last_name ذخیره می‌شوند.

5. محدود کردن طول ورودی

گاهی اوقات ممکن است بخواهید طول ورودی کاربر را محدود کنید. برای این کار می‌توانید از دستور read همراه با ابزارهایی مانند cut یا head استفاده کنید تا طول ورودی را کنترل کنید.

مثال:

echo "Enter your username (max 5 characters):"
read username
username=$(echo $username | cut -c 1-5)  # محدود کردن طول به 5 کاراکتر
echo "Your username is $username."

در اینجا:

  • دستور cut برای محدود کردن ورودی به 5 کاراکتر اول استفاده شده است.
  • این روش زمانی مفید است که ورودی طولانی‌تر از حد مجاز باشد.

6. بررسی ورودی معتبر

گاهی اوقات ممکن است بخواهید ورودی کاربر را بررسی کنید و از ورود داده‌های غیرمعتبر جلوگیری کنید. این کار با استفاده از دستورات شرطی (if) در شل امکان‌پذیر است.

مثال:

echo "Enter your age:"
read age
if [[ ! "$age" =~ ^[0-9]+$ ]]; then
    echo "Invalid input. Please enter a valid number."
else
    echo "Your age is $age."
fi

در اینجا:

  • ورودی کاربر با استفاده از یک عبارت منظم (regular expression) بررسی می‌شود.
  • اگر ورودی عددی نباشد، پیامی مبنی بر ورودی نامعتبر نمایش داده می‌شود.

جمع بندی

  • دستور read یک روش ساده و کاربردی برای دریافت ورودی از کاربر است.
  • با استفاده از گزینه -s می‌توانید ورودی‌هایی مانند رمز عبور را بدون نمایش در کنسول دریافت کنید.
  • با استفاده از متغیرهای پیش‌فرض، می‌توانید مقادیر پیش‌فرض را برای ورودی‌ها تعیین کنید.
  • برای دریافت چندین ورودی در یک خط، از دستور read همراه با لیست متغیرها استفاده می‌شود.
  • می‌توانید طول ورودی را با استفاده از ابزارهایی مانند cut محدود کنید.
  • بررسی ورودی معتبر می‌تواند با استفاده از دستورات شرطی و عبارات منظم انجام شود.

این روش‌ها به شما کمک می‌کند تا ورودی‌های کاربر را به‌طور مؤثر و ایمن در اسکریپت‌های شل مدیریت کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پردازش ورودی با دستورات read، cat و grep” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، گاهی اوقات نیاز دارید که ورودی‌هایی را از کاربر یا فایل‌ها بگیرید و آن‌ها را پردازش کنید. برای انجام این کار، دستورات مختلفی مانند read، cat و grep را می‌توان به‌طور مؤثر برای پردازش ورودی استفاده کرد. در این بخش، به بررسی نحوه استفاده از این دستورات خواهیم پرداخت.

1. پردازش ورودی با دستور read

دستور read برای دریافت ورودی از کاربر از کنسول به‌کار می‌رود. این ورودی می‌تواند برای انجام پردازش‌ها یا ذخیره‌سازی در متغیرهای مختلف استفاده شود. در بسیاری از موارد، ورودی از کاربر یا حتی از فایل‌ها گرفته می‌شود و سپس با استفاده از دستورات دیگر پردازش می‌شود.

مثال: پردازش ورودی با read برای جستجو در یک فایل

در این مثال، ورودی کاربر برای جستجو در یک فایل خاص دریافت می‌شود و سپس نتایج آن به نمایش گذاشته می‌شود:

echo "Enter the word you want to search:"
read word
echo "Searching for '$word' in file.txt..."
grep "$word" file.txt

در اینجا:

  • با استفاده از read از کاربر خواسته می‌شود تا کلمه‌ای را وارد کند.
  • سپس دستور grep برای جستجو در فایل file.txt استفاده می‌شود و نتایج آن نمایش داده می‌شود.

2. پردازش ورودی با دستور cat

دستور cat یکی از دستورات معروف شل برای نمایش محتویات فایل‌ها است. همچنین می‌توانید از آن برای ارسال ورودی از فایل‌ها به دستورات دیگر استفاده کنید.

مثال: خواندن یک فایل با cat و پردازش محتوای آن

در این مثال، از دستور cat برای خواندن محتوای یک فایل استفاده می‌شود و سپس با استفاده از grep به جستجوی کلمات خاص پرداخته می‌شود:

echo "Enter the word you want to search in the file:"
read word
cat file.txt | grep "$word"

در اینجا:

  • ابتدا محتویات فایل file.txt با استفاده از دستور cat خوانده می‌شود.
  • سپس دستور grep برای جستجو در آن محتویات بر اساس ورودی کاربر استفاده می‌شود.

نکته: استفاده از cat با لوله (pipe) برای انتقال داده‌ها به دستورات دیگر

در شل، می‌توان از لوله (pipe) برای ارسال خروجی یک دستور به ورودی دستور دیگر استفاده کرد. در اینجا، خروجی دستور cat به دستور grep ارسال می‌شود.

3. پردازش ورودی با دستور grep

دستور grep یکی از دستورات مفید برای جستجو در محتویات فایل‌ها است. این دستور به شما این امکان را می‌دهد تا رشته‌های خاصی را در فایل‌ها یا ورودی‌ها جستجو کنید و نتایج آن را به نمایش بگذارید.

مثال: جستجو در یک فایل و نمایش خطوط تطبیق یافته

در این مثال، ورودی کاربر از دستور read دریافت می‌شود و سپس با استفاده از دستور grep در یک فایل جستجو می‌شود:

echo "Enter the search term:"
read term
grep "$term" file.txt

در اینجا:

  • دستور read از کاربر یک کلمه برای جستجو دریافت می‌کند.
  • سپس با استفاده از دستور grep در فایل file.txt به جستجو پرداخته می‌شود.

مثال: جستجو با استفاده از گزینه‌های پیشرفته grep

grep دارای گزینه‌های مختلفی است که می‌تواند در جستجوها مفید باشد. مثلاً با استفاده از گزینه -i می‌توانید جستجو را به‌طور غیرحساس به حروف بزرگ و کوچک انجام دهید.

echo "Enter the term to search for (case insensitive):"
read term
grep -i "$term" file.txt

در اینجا:

  • با استفاده از گزینه -i، جستجو حساس به حروف بزرگ و کوچک نیست.

مثال: جستجو و شمارش تعداد خطوط تطبیق یافته با grep

اگر بخواهید تعداد خطوطی که با عبارت جستجو شده تطبیق دارند را بشمارید، می‌توانید از گزینه -c استفاده کنید.

echo "Enter the search term:"
read term
grep -c "$term" file.txt

در اینجا:

  • دستور grep -c تعداد خطوطی که شامل کلمه جستجو شده هستند را به نمایش می‌گذارد.

4. ترکیب cat و grep برای پردازش ورودی

گاهی اوقات، می‌خواهید خروجی یک دستور مانند cat را از طریق لوله (pipe) به دستور grep ارسال کنید تا در آن جستجو کنید. این ترکیب به شما امکان می‌دهد تا نتایج را از یک فایل بزرگ یا ورودی پیچیده‌تر استخراج کنید.

مثال: خواندن یک فایل با cat و جستجو در آن با grep

cat file.txt | grep "search_term"

در اینجا:

  • دستور cat محتویات file.txt را می‌خواند.
  • سپس محتویات با استفاده از grep جستجو می‌شود و تنها خطوطی که شامل عبارت search_term هستند نمایش داده می‌شود.

5. استفاده از دستور grep برای پردازش ورودی خط به خط

اگر ورودی شما از چندین خط تشکیل شده باشد و بخواهید آن‌ها را خط به خط پردازش کنید، می‌توانید از دستور grep برای جستجو در هر خط استفاده کنید.

مثال: جستجو در ورودی چندخطی

echo "Enter your lines of text (Ctrl+D to end):"
cat | grep "search_term"

در اینجا:

  • از cat برای دریافت ورودی چندخطی استفاده می‌شود.
  • سپس از grep برای جستجو در آن ورودی استفاده می‌شود.

جمع بندی

در این بخش:

  • دستور read برای دریافت ورودی از کاربر استفاده می‌شود و ورودی را در متغیرهای مختلف ذخیره می‌کند.
  • دستور cat برای خواندن محتویات فایل‌ها و ارسال آن‌ها به دستورات دیگر استفاده می‌شود.
  • دستور grep برای جستجو در متن‌ها و فایل‌ها با استفاده از عبارات منظم (regular expressions) و گزینه‌های مختلف به‌کار می‌رود.
  • می‌توان با ترکیب این دستورات، ورودی‌های پیچیده‌تر را پردازش کرد و نتایج دلخواه را استخراج نمود.

این دستورات ابزارهای مفیدی هستند که به شما کمک می‌کنند تا ورودی‌های متنی را به‌طور مؤثر پردازش کرده و اطلاعات مورد نظر خود را استخراج کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 9. کار با خروجی‌های استاندارد (stdout)”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ذخیره خروجی دستورات در متغیرها” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها، گاهی اوقات لازم است که خروجی یک دستور را ذخیره کرده و از آن در مراحل بعدی اسکریپت استفاده کنید. این کار می‌تواند برای پردازش اطلاعات، تصمیم‌گیری‌ها یا حتی ایجاد گزارش‌ها و فایل‌ها مفید باشد. برای ذخیره خروجی دستورات در متغیرها از روش‌های مختلفی می‌توان استفاده کرد که در این بخش بررسی خواهیم کرد.

1. استفاده از دستور $(command) برای ذخیره خروجی دستور در متغیر

یکی از روش‌های معمول برای ذخیره خروجی دستورات در متغیرها، استفاده از علامت $() است. این روش، خروجی یک دستور را می‌گیرد و آن را به متغیری اختصاص می‌دهد.

مثال: ذخیره تاریخ و زمان جاری در یک متغیر

در این مثال، از دستور date برای گرفتن تاریخ و زمان جاری سیستم استفاده کرده و آن را در یک متغیر به نام current_date ذخیره می‌کنیم:

current_date=$(date)
echo "Current Date and Time: $current_date"

در اینجا:

  • دستور date تاریخ و زمان جاری را به‌صورت متنی بازمی‌گرداند.
  • این خروجی به متغیر current_date اختصاص می‌یابد.
  • سپس با استفاده از echo تاریخ و زمان جاری را نمایش می‌دهیم.

2. استفاده از backticks command (روش قدیمی‌تر)

روش قدیمی‌تر برای ذخیره خروجی دستورات در متغیرها استفاده از backticks (“) است. این روش مشابه با استفاده از $() است، اما استفاده از $() به‌طور گسترده‌تر توصیه می‌شود، زیرا خواناتر و ساده‌تر است. با این حال، هنوز هم می‌توان از backticks استفاده کرد.

مثال: ذخیره خروجی دستور ls در یک متغیر با استفاده از backticks

file_list=`ls`
echo "List of files: $file_list"

در اینجا:

  • دستور ls فهرست فایل‌های موجود در دایرکتوری جاری را بازمی‌گرداند.
  • خروجی این دستور در متغیر file_list ذخیره می‌شود.
  • سپس با استفاده از echo فهرست فایل‌ها نمایش داده می‌شود.

3. ذخیره خروجی دستور grep در متغیر برای پردازش

در بسیاری از موارد، شما ممکن است بخواهید خروجی یک دستور جستجو مانند grep را ذخیره کنید تا بتوانید آن را برای پردازش‌های بعدی استفاده کنید.

مثال: جستجو برای یک کلمه خاص در یک فایل و ذخیره نتیجه در متغیر

search_result=$(grep "keyword" file.txt)
echo "Search results: $search_result"

در اینجا:

  • دستور grep برای جستجوی عبارت "keyword" در فایل file.txt استفاده می‌شود.
  • خروجی جستجو در متغیر search_result ذخیره می‌شود.
  • سپس با استفاده از echo نتایج جستجو نمایش داده می‌شود.

4. ذخیره خروجی چند خطی در متغیر

گاهی اوقات خروجی دستور مورد نظر شما ممکن است شامل چندین خط باشد. در این موارد نیز می‌توانید خروجی چند خطی را در متغیر ذخیره کنید.

مثال: ذخیره خروجی چند خطی در یک متغیر

multi_line_output=$(cat file.txt)
echo "File content:"
echo "$multi_line_output"

در اینجا:

  • دستور cat file.txt محتویات فایل را می‌خواند که ممکن است شامل چندین خط باشد.
  • خروجی آن در متغیر multi_line_output ذخیره می‌شود.
  • سپس با استفاده از echo محتویات فایل نمایش داده می‌شود.

5. پردازش خروجی دستور و ذخیره آن در متغیر

گاهی اوقات ممکن است بخواهید خروجی دستور را پردازش کرده و آن را در متغیر ذخیره کنید. به‌عنوان مثال، ممکن است بخواهید فقط بخش خاصی از خروجی را ذخیره کنید یا از داده‌ها برای انجام محاسبات استفاده کنید.

مثال: ذخیره تعداد خطوط فایل با استفاده از wc -l

در اینجا، می‌خواهیم تعداد خطوط یک فایل را حساب کنیم و آن را در متغیر ذخیره کنیم:

line_count=$(wc -l < file.txt)
echo "The file has $line_count lines."

در اینجا:

  • دستور wc -l تعداد خطوط فایل file.txt را می‌شمارد.
  • این خروجی به متغیر line_count اختصاص می‌یابد.
  • سپس با استفاده از echo تعداد خطوط فایل نمایش داده می‌شود.

6. ذخیره خروجی دستور به همراه خطاها

گاهی اوقات ممکن است بخواهید هم خروجی استاندارد و هم خروجی خطا را در یک متغیر ذخیره کنید. برای این کار می‌توان از 2>&1 استفاده کرد که هم خطا و هم خروجی استاندارد را به متغیر ارسال می‌کند.

مثال: ذخیره خروجی و خطاها در یک متغیر

command_output=$(ls non_existing_directory 2>&1)
echo "Command output: $command_output"

در اینجا:

  • دستور ls non_existing_directory تلاش می‌کند تا فهرست محتویات یک دایرکتوری غیرموجود را نمایش دهد.
  • از 2>&1 استفاده می‌شود تا هم خطای رخ داده و هم خروجی استاندارد در یک متغیر به نام command_output ذخیره شوند.
  • سپس با استفاده از echo خروجی و خطاها نمایش داده می‌شود.

7. استفاده از متغیرها در اسکریپت‌ها

پس از ذخیره خروجی دستورات در متغیرها، می‌توانید این متغیرها را برای پردازش‌های بعدی در اسکریپت خود استفاده کنید. این به شما امکان می‌دهد که از نتایج دستورات قبلی برای انجام عملیات‌های پیچیده‌تر استفاده کنید.

مثال: استفاده از متغیر برای تصمیم‌گیری در اسکریپت

disk_space=$(df / | grep / | awk '{ print $4 }')
if [ $disk_space -lt 1000000 ]; then
  echo "Warning: Low disk space!"
else
  echo "Sufficient disk space available."
fi

در اینجا:

  • دستور df / فضای دیسک موجود برای دایرکتوری ریشه را بررسی می‌کند.
  • خروجی آن با استفاده از grep و awk پردازش شده و فضای آزاد دیسک در متغیر disk_space ذخیره می‌شود.
  • سپس با استفاده از شرط if، بررسی می‌شود که آیا فضای دیسک کمتر از یک مقدار خاص است یا خیر.

جمع بندی

در این بخش:

  • توضیح دادیم که چگونه می‌توانید خروجی دستورات مختلف را با استفاده از $() (یا backticks) در متغیرها ذخیره کنید.
  • این متغیرها سپس می‌توانند برای پردازش‌های بعدی یا تصمیم‌گیری‌ها در اسکریپت‌ها استفاده شوند.
  • چندین مثال برای ذخیره خروجی دستورات مختلف مانند cat، grep، wc -l و غیره آورده شد که می‌توانند به شما کمک کنند تا این مفاهیم را به‌طور مؤثر در اسکریپت‌های خود پیاده‌سازی کنید.

[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”انتقال خروجی به فایل‌ها یا دستورات دیگر” subtitle=”توضیحات کامل”]در اسکریپت‌های شل، ممکن است بخواهید خروجی یک دستور را به فایل‌ها یا حتی به دستورات دیگر ارسال کنید. این امکان به شما این اجازه را می‌دهد که اطلاعات را ذخیره کنید یا نتایج یک دستور را برای پردازش‌های بیشتر در دستور دیگری استفاده کنید. در این بخش به روش‌های مختلف انتقال خروجی به فایل‌ها و دستورات دیگر خواهیم پرداخت.

1. هدایت خروجی به یک فایل با استفاده از >

یکی از رایج‌ترین روش‌ها برای ذخیره خروجی دستورات در یک فایل، استفاده از علامت > است. این علامت خروجی دستور را به فایل مورد نظر هدایت می‌کند و در صورت وجود فایل، محتوای آن را بازنویسی می‌کند.

مثال: ذخیره خروجی دستور ls در یک فایل

ls > file_list.txt

در اینجا:

  • دستور ls فهرست فایل‌ها و دایرکتوری‌های موجود در دایرکتوری جاری را می‌گیرد.
  • خروجی این دستور در فایل file_list.txt ذخیره می‌شود.
  • اگر فایل file_list.txt از قبل وجود داشته باشد، محتوای آن با خروجی جدید بازنویسی می‌شود.

2. اضافه کردن خروجی به انتهای یک فایل با استفاده از >>

اگر بخواهید خروجی دستور را به انتهای یک فایل اضافه کنید، می‌توانید از دو علامت >> استفاده کنید. این کار به شما این امکان را می‌دهد که اطلاعات جدید را به‌جای بازنویسی، به انتهای فایل موجود اضافه کنید.

مثال: اضافه کردن فهرست فایل‌ها به انتهای یک فایل

ls >> file_list.txt

در اینجا:

  • دستور ls فهرست فایل‌ها را می‌گیرد.
  • خروجی این دستور به انتهای فایل file_list.txt اضافه می‌شود.
  • اگر فایل file_list.txt وجود نداشته باشد، این فایل جدید ایجاد خواهد شد.

3. هدایت خروجی خطاها به فایل با استفاده از 2>

گاهی اوقات ممکن است شما بخواهید فقط خطاهای یک دستور را در یک فایل ذخیره کنید. برای این کار از 2> استفاده می‌شود. عدد 2 به معنی فایل خطا (stderr) است.

مثال: ذخیره خطاهای دستور ls در یک فایل

ls /nonexistent_directory 2> error_log.txt

در اینجا:

  • دستور ls /nonexistent_directory سعی می‌کند فهرست محتویات دایرکتوری‌ای را که وجود ندارد، نمایش دهد.
  • خطای تولید شده (مثلاً “No such file or directory”) در فایل error_log.txt ذخیره می‌شود.
  • این خطا فقط در فایل error_log.txt ذخیره خواهد شد و هیچ خروجی استانداردی به کنسول نمایش داده نمی‌شود.

4. هدایت خروجی استاندارد و خطاها به یک فایل با استفاده از 2>&1

گاهی اوقات ممکن است بخواهید هم خروجی استاندارد (stdout) و هم خروجی خطا (stderr) را به یک فایل ارسال کنید. برای این کار می‌توانید از ترکیب 2>&1 استفاده کنید.

مثال: هدایت همزمان خروجی و خطا به یک فایل

ls /nonexistent_directory > output_and_errors.txt 2>&1

در اینجا:

  • دستور ls /nonexistent_directory تلاش می‌کند محتویات یک دایرکتوری غیراستاندارد را نشان دهد.
  • هم خروجی استاندارد و هم خروجی خطا به فایل output_and_errors.txt هدایت می‌شود.
  • 2>&1 نشان می‌دهد که خطاها (stderr) به همان مقصدی که خروجی استاندارد (stdout) هدایت می‌شود، ارسال شوند.

5. انتقال خروجی به دستور دیگر با استفاده از | (پایپ)

یکی از روش‌های بسیار پرکاربرد در شل اسکریپت‌ها برای انتقال خروجی یک دستور به دستور دیگری، استفاده از علامت | (پایپ) است. این روش به شما امکان می‌دهد که خروجی یک دستور را به ورودی دستور دیگری ارسال کنید. به این تکنیک، “پایپینگ” گفته می‌شود.

مثال: انتقال خروجی دستور ls به دستور grep برای جستجو

ls | grep "file"

در اینجا:

  • دستور ls فهرست تمام فایل‌ها و دایرکتوری‌ها را نمایش می‌دهد.
  • خروجی دستور ls به دستور grep ارسال می‌شود.
  • دستور grep جستجو می‌کند تا فقط فایل‌هایی که کلمه “file” در نامشان وجود دارد را نشان دهد.

6. استفاده از tee برای هدایت خروجی به چند مقصد

دستور tee این امکان را به شما می‌دهد که خروجی یک دستور را همزمان به یک فایل بنویسید و آن را روی کنسول نمایش دهید. به عبارت دیگر، tee می‌تواند خروجی یک دستور را به چندین مقصد ارسال کند.

مثال: استفاده از tee برای نمایش و ذخیره خروجی

ls | tee file_list.txt

در اینجا:

  • دستور ls فهرست فایل‌ها را تولید می‌کند.
  • خروجی این دستور همزمان به فایل file_list.txt ذخیره می‌شود و در کنسول نیز نمایش داده می‌شود.

برای ذخیره خروجی در چند فایل به‌طور همزمان، می‌توان از دستور tee به همراه گزینه -a برای افزودن به فایل‌های موجود استفاده کرد.

مثال: اضافه کردن خروجی به چند فایل با tee

ls | tee -a file1.txt file2.txt

در اینجا:

  • خروجی دستور ls به هر دو فایل file1.txt و file2.txt اضافه می‌شود.
  • همچنین این خروجی در کنسول نیز نمایش داده می‌شود.

7. انتقال خروجی یک دستور به ورودی دستور دیگر با xargs

دستور xargs به شما این امکان را می‌دهد که خروجی یک دستور را به عنوان ورودی به دستور دیگری بدهید. این دستور به‌ویژه در زمانی که خروجی دستور اول شامل تعداد زیادی از داده‌ها باشد، بسیار مفید است.

مثال: استفاده از xargs برای حذف فایل‌های مشخص‌شده

find . -name "*.tmp" | xargs rm

در اینجا:

  • دستور find . -name "*.tmp" تمام فایل‌های با پسوند .tmp را پیدا می‌کند.
  • خروجی این دستور که فهرستی از فایل‌ها است، به دستور xargs ارسال می‌شود.
  • سپس xargs این فهرست را به دستور rm منتقل می‌کند تا فایل‌های مشخص‌شده حذف شوند.

جمع بندی

در این بخش بررسی کردیم که چگونه می‌توانید خروجی یک دستور را به فایل‌ها یا دستورات دیگر ارسال کنید. روش‌های مختلفی برای این کار وجود دارد که شامل:

  • استفاده از > و >> برای هدایت خروجی به فایل‌ها.
  • هدایت خطاها با استفاده از 2> و هدایت همزمان خروجی استاندارد و خطاها با 2>&1.
  • استفاده از | برای انتقال خروجی به دستور دیگر (پایپینگ).
  • استفاده از tee برای هدایت خروجی به فایل و نمایش همزمان آن در کنسول.
  • استفاده از xargs برای ارسال خروجی به دستور دیگر.

این تکنیک‌ها به شما کمک می‌کنند که فرآیندهای پیچیده‌تری را در اسکریپت‌های شل ایجاد کنید و خروجی‌ها را به‌طور مؤثر مدیریت کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 10. مدیریت خطاها در ورودی و خروجی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”هدایت خطاهای استاندارد به فایل برای اشکال‌زدایی” subtitle=”توضیحات کامل”]در شل اسکریپت‌ها و دستورات لینوکس، خطاهای استاندارد (stderr) ممکن است حاوی اطلاعات مهمی برای تشخیص مشکلات و اشکال‌زدایی باشند. به‌طور پیش‌فرض، این خطاها به کنسول ارسال می‌شوند، اما می‌توان آن‌ها را به یک فایل هدایت کرد تا به راحتی مورد بررسی قرار گیرند. این روش به‌ویژه در زمان اجرای اسکریپت‌های پیچیده و بررسی خطاهای احتمالی بسیار مفید است.

در این بخش، روش‌هایی برای هدایت خطاهای استاندارد به فایل‌ها و نحوه استفاده از آن‌ها برای اشکال‌زدایی توضیح داده می‌شود.

1. هدایت خطاها با استفاده از 2>

برای هدایت خروجی خطاهای استاندارد به یک فایل، از علامت 2> استفاده می‌شود. در اینجا عدد 2 نشان‌دهنده فایل خطا (stderr) است، در حالی که > به‌طور پیش‌فرض برای هدایت خروجی استاندارد (stdout) استفاده می‌شود.

مثال: هدایت خطای دستور ls به یک فایل

ls /nonexistent_directory 2> error_log.txt

در اینجا:

  • دستور ls /nonexistent_directory سعی می‌کند فهرست دایرکتوری‌ای که وجود ندارد را نمایش دهد.
  • خطای تولید شده (مثل “No such file or directory”) به فایل error_log.txt هدایت می‌شود.
  • هیچ‌کدام از خطاها به کنسول نمایش داده نمی‌شود.

2. هدایت همزمان خروجی استاندارد و خطا به یک فایل

اگر بخواهید هم خروجی استاندارد (stdout) و هم خطاها (stderr) را به یک فایل ارسال کنید، می‌توانید از ترکیب 2>&1 استفاده کنید. این ترکیب موجب می‌شود که فایل خطا (stderr) به همان جایی هدایت شود که فایل خروجی استاندارد (stdout) هدایت می‌شود.

مثال: هدایت همزمان خروجی و خطا به یک فایل

ls /nonexistent_directory > output_and_errors.txt 2>&1

در اینجا:

  • دستور ls /nonexistent_directory خطا می‌دهد چون دایرکتوری مورد نظر وجود ندارد.
  • هم خروجی استاندارد و هم خطاها به فایل output_and_errors.txt هدایت می‌شوند.
  • 2>&1 باعث می‌شود که خطاها به همان مکان خروجی استاندارد هدایت شوند.

3. هدایت خطاها به فایل و نمایش آن‌ها در کنسول با استفاده از tee

گاهی اوقات ممکن است بخواهید خطاها را هم در فایل ذخیره کنید و هم آن‌ها را همزمان در کنسول نمایش دهید. برای این کار می‌توانید از دستور tee استفاده کنید که به شما این امکان را می‌دهد که خروجی‌ها را به‌طور همزمان در کنسول و در فایل ذخیره کنید.

مثال: هدایت خطاها به فایل و نمایش آن‌ها در کنسول

ls /nonexistent_directory 2>&1 | tee error_log.txt

در اینجا:

  • دستور ls /nonexistent_directory خطا می‌دهد.
  • خروجی خطاها به کنسول نمایش داده می‌شود.
  • همچنین خطاها به فایل error_log.txt ذخیره می‌شوند.

4. هدایت خطاهای یک دستور به یک فایل خاص در کنار خروجی‌های دیگر

گاهی اوقات ممکن است بخواهید خروجی‌های استاندارد و خطاها را در دو فایل مختلف ذخیره کنید. برای این کار می‌توانید از هدایت متفاوت برای هرکدام استفاده کنید.

مثال: هدایت خروجی استاندارد و خطا به فایل‌های مختلف

ls /nonexistent_directory > output.txt 2> error_log.txt

در اینجا:

  • خروجی استاندارد (stdout) در فایل output.txt ذخیره می‌شود.
  • خطاها (stderr) در فایل error_log.txt ذخیره می‌شوند.

این روش برای مواقعی مفید است که بخواهید خروجی‌های درست و خطاها را جداگانه مدیریت کنید.

5. هدایت خطاها در اسکریپت‌ها برای اشکال‌زدایی

در هنگام نوشتن اسکریپت‌ها، ممکن است بخواهید تمامی خطاهای تولیدی در طول اجرا را به یک فایل هدایت کنید تا پس از اجرای اسکریپت به راحتی مشکلات را بررسی کنید. این روش به ویژه برای اسکریپت‌های طولانی و پیچیده‌ای که در مراحل مختلف خطا می‌دهند، بسیار کاربردی است.

مثال: ذخیره خطاهای یک اسکریپت در یک فایل

#!/bin/bash
echo "Starting script..."

# اجرای دستوری که ممکن است خطا دهد
cp /nonexistent_file.txt /somewhere/ > script_output.txt 2> script_error.log

echo "Script finished"

در اینجا:

  • در دستور cp /nonexistent_file.txt /somewhere/ چون فایل وجود ندارد، خطا ایجاد می‌شود.
  • خروجی استاندارد در فایل script_output.txt ذخیره می‌شود.
  • خطاها در فایل script_error.log ذخیره می‌شوند.

جمع بندی

در این بخش یاد گرفتیم که چگونه می‌توان خطاهای استاندارد را در اسکریپت‌های شل و دستورات مختلف هدایت کرد و از آن‌ها برای اشکال‌زدایی استفاده نمود. روش‌های مختلفی برای هدایت خطاها وجود دارد که شامل:

  • استفاده از 2> برای هدایت خطاها به فایل.
  • استفاده از 2>&1 برای هدایت همزمان خروجی استاندارد و خطاها به یک فایل.
  • استفاده از tee برای ذخیره و نمایش همزمان خطاها.
  • هدایت خطاها و خروجی‌های استاندارد به فایل‌های مختلف.

این تکنیک‌ها به شما کمک می‌کنند تا در هنگام کار با شل اسکریپت‌ها، خطاها را مدیریت کرده و مشکلات را به‌راحتی شناسایی و رفع کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از دستورات try-catch شبیه‌سازی شده در شل” subtitle=”توضیحات کامل”]در زبان‌های برنامه‌نویسی مختلف مانند Python یا JavaScript، دستورات try-catch برای مدیریت استثناها و خطاها به کار می‌روند. در شل اسکریپت‌ها به‌طور پیش‌فرض هیچ دستور try-catch وجود ندارد، اما می‌توان این رفتار را با استفاده از برخی دستورات و تکنیک‌ها شبیه‌سازی کرد. این شبیه‌سازی به شما این امکان را می‌دهد که خطاهای احتمالی را مدیریت کرده و کد خود را از شکست‌های غیرمنتظره محافظت کنید.

در این بخش، روش‌هایی برای شبیه‌سازی دستورات try-catch در شل اسکریپت‌ها معرفی خواهیم کرد.

1. استفاده از دستور trap برای مدیریت خطاها

یکی از روش‌های رایج شبیه‌سازی try-catch در شل استفاده از دستور trap است که برای نظارت بر سیگنال‌ها و مدیریت خطاها کاربرد دارد. با استفاده از trap می‌توانیم زمانی که خطای خاصی رخ می‌دهد، یک بخش خاص از کد را اجرا کنیم.

مثال: استفاده از trap برای شبیه‌سازی try-catch

#!/bin/bash

# تابعی برای شبیه‌سازی try-catch
function try_catch {
  trap 'echo "An error occurred. Exiting..."; exit 1;' ERR  # شبیه‌سازی catch
  
  # کدی که ممکن است خطا بدهد (try)
  echo "Trying to copy file..."
  cp /nonexistent_file.txt /some_directory/  # خطا خواهد داد
  echo "This line will not be reached if an error occurs."
  
  trap - ERR  # بازنشانی trap بعد از پایان بلوک try
}

# اجرای تابع
try_catch

در اینجا:

  • دستور trap برای شبیه‌سازی catch استفاده می‌شود تا در صورت بروز خطا، پیامی نمایش داده شود و اسکریپت متوقف گردد.
  • در داخل بلوک try، یک دستور cp قرار داده‌ایم که به دلیل عدم وجود فایل، خطا می‌دهد.
  • با استفاده از trap - ERR بعد از پایان بلوک، تنظیمات trap بازنشانی می‌شوند.

2. استفاده از بررسی کد بازگشتی $?

در شل اسکریپت‌ها، می‌توانیم از کد بازگشتی $? برای بررسی وضعیت اجرای دستور قبلی استفاده کنیم. این کد می‌تواند نشان دهد که آیا دستور قبلی موفقیت‌آمیز بوده است یا خیر. برای شبیه‌سازی رفتار try-catch، می‌توانیم کدهای خطا را بررسی کرده و در صورت بروز خطا، دستورات خاصی را اجرا کنیم.

مثال: استفاده از $? برای شبیه‌سازی try-catch

#!/bin/bash

# تابعی برای شبیه‌سازی try-catch
function try_catch {
  echo "Trying to copy file..."
  
  # اجرای دستور که ممکن است خطا دهد
  cp /nonexistent_file.txt /some_directory/
  
  # بررسی کد بازگشتی برای شبیه‌سازی catch
  if [ $? -ne 0 ]; then
    echo "An error occurred. Handling the error..."
    # می‌توانید دستوراتی را برای پردازش خطا اینجا بنویسید
    exit 1
  fi
  
  echo "File copied successfully"
}

# اجرای تابع
try_catch

در اینجا:

  • دستور cp ممکن است خطا بدهد، بنابراین بعد از اجرای دستور از $? برای بررسی موفقیت یا شکست استفاده می‌کنیم.
  • اگر دستور قبلی موفقیت‌آمیز نبود (کد بازگشتی متفاوت از ۰)، پیام خطا نمایش داده می‌شود و اسکریپت متوقف می‌شود.

3. استفاده از شرط‌ها برای مدیریت خطا

در این روش، می‌توانیم خطاهای احتمالی را با استفاده از دستور if یا && و || مدیریت کنیم. این روش نیز به‌شکل یک شبیه‌سازی از try-catch عمل می‌کند.

مثال: استفاده از if برای شبیه‌سازی try-catch

#!/bin/bash

# تابعی برای شبیه‌سازی try-catch
function try_catch {
  echo "Trying to create a directory..."
  
  # اجرای دستوری که ممکن است خطا بدهد
  mkdir /restricted_directory
  
  # بررسی موفقیت یا شکست دستور
  if [ $? -ne 0 ]; then
    echo "An error occurred during directory creation. Handling the error..."
    # انجام اقدامات برای مدیریت خطا
    exit 1
  fi
  
  echo "Directory created successfully"
}

# اجرای تابع
try_catch

در اینجا:

  • اگر دستور mkdir که سعی در ایجاد یک دایرکتوری در محل محدود شده دارد خطا دهد، پیامی در مورد خطا به نمایش درمی‌آید و اسکریپت متوقف می‌شود.

4. استفاده از دستور && و ||

در شل، می‌توان از ترکیب دستورات با && و || برای شبیه‌سازی رفتارهای try-catch استفاده کرد. دستور && برای اجرای دستورات بعدی در صورتی که دستور قبلی موفقیت‌آمیز باشد و دستور || برای اجرای دستورات بعدی در صورتی که دستور قبلی شکست بخورد استفاده می‌شود.

مثال: استفاده از && و || برای شبیه‌سازی try-catch

#!/bin/bash

echo "Trying to move file..."

# اگر دستور موفق بود، ادامه می‌دهیم، در غیر این صورت خطا می‌دهیم
mv /nonexistent_file.txt /some_directory/ && echo "File moved successfully" || { echo "An error occurred during file move"; exit 1; }

در اینجا:

  • دستور mv سعی در جابجایی فایل می‌کند.
  • اگر دستور mv موفق باشد، پیام موفقیت‌آمیز چاپ می‌شود.
  • در غیر این صورت، بلوک || اجرا شده و خطا مدیریت می‌شود.

جمع بندی

در این بخش یاد گرفتیم که چگونه می‌توانیم رفتار try-catch را در شل اسکریپت‌ها شبیه‌سازی کنیم. چون شل به‌طور پیش‌فرض دستور try-catch را ندارد، از تکنیک‌های مختلفی برای مدیریت خطاها استفاده می‌کنیم:

  1. استفاده از دستور trap برای مدیریت خطاها و اجرای دستورات خاص در صورت بروز خطا.
  2. استفاده از بررسی کد بازگشتی $? برای شبیه‌سازی خطاها.
  3. استفاده از دستورات شرطی برای مدیریت خطا.
  4. استفاده از ترکیب && و || برای شبیه‌سازی رفتار try-catch.

این روش‌ها به شما کمک می‌کنند تا در اسکریپت‌های شل، خطاها را به‌درستی مدیریت کرده و از بروز مشکلات پیش‌بینی‌نشده جلوگیری کنید.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”پاسخ به سوالات فنی کاربران”][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”free” title=”پشتیبانی دائمی و در لحظه” subtitle=”توضیحات کامل”]ما در این دوره تمام تلاش خود را کرده‌ایم تا محتوایی جامع و کاربردی ارائه دهیم که شما را برای ورود به دنیای حرفه‌ای آماده کند. اما اگر در طول دوره یا پس از آن با سوالات فنی، چالش‌ها یا حتی مشکلاتی در اجرای مطالب آموزشی مواجه شدید، نگران نباشید!

  1. پرسش‌های شما، بخش مهمی از دوره است:
    هر سوال یا مشکلی که مطرح کنید، با دقت بررسی شده و پاسخ کامل و کاربردی برای آن ارائه می‌شود. علاوه بر این، سوالات و پاسخ‌های شما به دوره اضافه خواهند شد تا برای سایر کاربران نیز مفید باشد.
  2. پشتیبانی دائمی و در لحظه:
    تیم ما همواره آماده پاسخگویی به سوالات شماست. هدف ما این است که شما با خیالی آسوده بتوانید مهارت‌های خود را به کار بگیرید و پروژه‌های واقعی را با اعتماد به نفس کامل انجام دهید.
  3. آپدیت دائمی دوره:
    این دوره به طور مداوم به‌روزرسانی می‌شود تا همگام با نیازهای جدید و سوالات کاربران تکمیل‌تر و بهتر گردد. هر نکته جدید یا مشکل رایج، در نسخه‌های بعدی دوره قرار خواهد گرفت.

حرف آخر

با ما همراه باشید تا نه تنها به مشکلات شما پاسخ دهیم، بلکه در مسیر یادگیری و پیشرفت حرفه‌ای، شما را پشتیبانی کنیم. هدف ما این است که شما به یک متخصص حرفه‌ای و قابل‌اعتماد تبدیل شوید و بتوانید با اطمینان پروژه‌های واقعی را بپذیرید و انجام دهید.

📩 اگر سوالی دارید یا به مشکلی برخوردید، همین حالا مطرح کنید!
ما در کوتاه‌ترین زمان ممکن پاسخ شما را ارائه خواهیم داد. 🙌[/cdb_course_lesson][/cdb_course_lessons]

نقد و بررسی ها

نقد و بررسی وجود ندارد.

فقط مشتریانی که وارد سیستم شده اند و این محصول را خریداری کرده اند می توانند نظر بدهند.

سبد خرید

سبد خرید شما خالی است.

ورود به سایت