جستجو برای:
سبد خرید 0
  • صفحه اصلی
  • دوره‌های آموزشی
  • وبلاگ
  • درباره ما
  • قوانین و مقررات
  • همکاری با ما
  • تماس با ما
محتوای باز
ورود
[suncode_otp_login_form]
گذرواژه خود را فراموش کرده اید؟
عضویت
[suncode_otp_registration_form]
  • خانه
  • کتاب آنلاین
  • درباره سایت
  • درباره لوگو
  • تماس با ما
محتوای باز
  • صفحه اصلی
  • دوره‌های آموزشی
  • وبلاگ
  • درباره ما
  • قوانین و مقررات
  • همکاری با ما
  • تماس با ما
شروع کنید
آخرین اطلاعیه ها
لطفا برای نمایش اطلاعیه ها وارد شوید
0
[wcas-search-form]

طراحی بالا به پایین (top-down design) در اسکریپت‌نویسی

2 بهمن 1403
ارسال شده توسط فرشید نوتاش حقیقت
خط فرمان، گنو/لینوکس

همانطور که برنامه‌‌ها بزرگ‌تر و پیچیده‌تر میشوند، طراحی، کدنویسی و نگهداری آن نیز دشوارتر می‌شود. درست مثل هر پروژه بزرگ دیگری ایده خوبی است که وظایف بزرگ و پیچیده را به یکسری وظایف ساده و کوچک تر تقسیم کنیم.

فرض کنید که می‌خواهیم یک وظیفه روزمره مثل رفتن به سوپرمارکت و خرید مواد غذایی را توصیف کنیم میتوانیم کل پروسه را به صورت وظایف زیر توصیف کنیم :
1- وارد ماشین می‌شویم.

2- به سمت سوپر مارکت رانندگی می‌کنیم.

3- ماشین را پارک می‌کنیم.

4- وارد فروشگاه می‌شویم.

5- مواد غذایی را خریداری می‌کنیم.

6- به ماشین بازمی‌گردیم.

7- به سمت خانه رانندگی می کنیم.

8- ماشین را پارک می‌کنیم.

9- وارد خانه میشویم.

هر چند می‌توانیم هر وظیفه را با جزئیات بیشتری توضیح دهیم و به این منظور هر وظیفه را به چند زیر وظیفه دیگر بسط می‌دهیم مثلا وظیفه پارک کردن ماشین را می‌توان به گام های زیر تقسیم کرد:
1- پیدا کردن فضای پارک

2- رانندگی ماشین به فضای پارک.

3- خاموش کردن موتور ماشین.

4- کشیدن ترمز و از ماشین خارج شدن.

5- قفل کردن ماشین.

به تبع آن میتوان زیر وظیفه خاموش کردن موتور ماشین را به دو گام خاموش کردن موتور و برداشتن سوییچ تقسیم کرد و .. و همینطور پروسه ها را شکست تا این وظیفه کلی رفتن به سوپر مارکت به صورت کامل تعریف شود.
این پروسه شناسایی گام‌های سطح بالا و توسعه افزایشی جزئیات نمایش گام‌ها را طراحی از بالا به پایین می‌نامند. این تکنیک به ما اجازه می‌دهد تا وظایف پیچیده را به وظایف کوچک و ساده تر تبدیل کنیم طراحی از بالا به پایین (Top Down Design) یک متد رایج طراحی برنامه‌ ها و گزینه‌ای است که بویژه برای برنامه‌نویسی در شل (Shell) مناسب است.

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

توابع شل (Shell Functions)

اسکریپت ما هم اکنون گام‌های زیر را برای ایجاد سند HTML دنبال می‌کند:

1- باز کردن صفحه.

2- باز کردن هدر صفحه.

3- تنظیم عنوان صفحه.

4- بستن هدر صفحه.

5- باز کردن بدنه صفحه.

6- خروجی تگ H1 صفحه.

7- خروجی برچسب زمانی.

8- بستن بدنه صفحه.

9- بستن صفحه.

برای مرحله بعدی توسعه ما برخی وظایف را بین گام‌های هفت و هشت اضافه خواهیم کرد شامل:

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

اگر که ما فرمانی برای هر کدام از این وظایف داشتیم بایستی آن‌ها را به سادگی به اسکریپت خود اضافه می‌کردیم:

#!/bin/bash

# Program to output a system information page

TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME=$(date +"%x %r %Z")
TIME_STAMP="Generated $CURRENT_TIME, by $USER"

cat << _EOF_
<HTML>
    <HEAD>
        <TITLE>$TITLE</TITLE>
    </HEAD>
    <BODY>
        <H1>$TITLE</H1>
        <P>$TIME_STAMP</P>
        $(report_uptime)
        $(report_disk_space)
        $(report_home_space)
    </BODY>
</HTML>
_EOF_

ما می‌توانیم این فرمان‌های اضافی را به دو شیوه ایجاد کنیم. می‌توانیم این سه فرمان اضافی را در فایل‌های اسکربیت جداگانه بنویسیم و آن‌ها را درون پوشه‌ای که درون مسیر PATH ما هستند قرار دهیم. یا اینکه می‌توانیم این اسکریپت‌ها به عنوان توابع
شل (Shall Function) درون برنامه خود قرار دهیم.

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

function name {
    commands
    return
}

که در این شکل name نام تابع ماست و commands یکسری از فرمان‌هایی است که درون تابع قرار داده شده اند. شکل دوم آنها به صورت زیر است:

name () {
    commands
    return
}

هر دو شکل با هم برابر هستند و ممکن است به جای یکدیگر استفاده شوند. در زیر یک اسکریپتی را می‌بینیم که استفاده از یک
تابع شل (Shell Function) را نمایش می‌دهد:

1	#!/bin/bash
2	
3	# Shell function demo
4
5	function funct {
6		echo "Step 2"
7		return
8	}
9	
10	# Main program starts here
11	
12	echo "Step 1"
13	funct
14	echo "Step 3"

زمانی که شل (Shadi) اسکریپت را میخواند خطوط ابتدایی را رد میکند تا به اجرای برنامه اصلی در خط ۱۲ برسد. در خط ۱۳ تابع funct فراخوانی می‌شود و شل (Shell) تابع را درست مثل هر فرمانی دیگر اجرا می‌کنند. سپس کنترل برنامه به خط ٦ باز می‌گردد echo موجود در گام دوم اجرا می شود. سپس خط ۷ اجرا می‌شود که دستور return هست. دستور return تابع را پایان می‌دهد و کنترل برنامه را به خط ١٤ باز میگرداند و در نهایت آخرین Echo که گام سوم است اجرا می شود. توجه داشته باشید برای اینکه فراخوانی یک تابع انجام شود تابع بایستی قبل از فراخوانی تعریف شود یعنی در ابتدای اسکریپت. خوب اکنون که نحوه تعریف توابع را آموختیم کمی توابع ساده را به اسکریپت خود اضافه می‌کنیم:

#!/bin/bash

# Program to output a system information page

TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME=$(date +"%x %r %Z")
TIME_STAMP="Generated $CURRENT_TIME, by $USER"

report_uptime () {
    return
}

report_disk_space () {
    return
}

report_home_space () {
    return
}

cat << _EOF_
<HTML>
    <HEAD>
        <TITLE>$TITLE</TITLE>
    </HEAD>
    <BODY>
        <H1>$TITLE</H1>
        <P>$TIME_STAMP</P>
        $(report_uptime)
        $(report_disk_space)
        $(report_home_space)
    </BODY>
</HTML>
_EOF_

نام‌های توابع شل (Shell Function همان قوانین متغیرها را شامل می‌شود یک تابع بایستی حداقل دارای یک فرمان باشد که ما
در اینجا فقط فرمان return (که تابع را پایان می‌دهد) را قرار داده‌ایم.

متغیرهای محلی (Local Variables)

در اسکریپتی که تاکنون نوشتیم همه متغیرها شامل ثابت‌ها متغیرهای سراسری بودند. متغیرهای سراسری موجودیت خود را در طول برنامه حفظ می‌کنند. این ویژگی برای بسیاری از وظایف مناسب است. ولی گاهی میتواند استفاده از توابع شل را پیچیده کند. درون توابع شل (Shell Functions) . اغلب خوب است که متغیرهای محلی را داشته باشیم. متغیرهای محلی فقط درون توایمی که درون آن تعریف شده اند قابل دسترسی هستند و پس از آنکه تابع بسته شد موجودیت آن‌ها نیز از بین می‌‎رود.
داشتن متغیرهای محلی به برنامه‌نویس این اجازه را می‌دهد تا متغیرها را با اسامی که هم اکنون در برنامه موجود هستند و استفاده شده‌اند نام‌گذاری کنند چه درون اسکریپت و چه به صورت سراسری درون دیگر توابع شل بدون اینکه نگران این باشد. که نام متغیرها با هم تلاقی و تضاد پیدا کند. این یک مثال از اسکریپتی است که نحوه تعریف و استفاده از متغیرهای محلی را توضیح می‌دهد:

#!/bin/bash

# local-vars: script to demonstrate local variables

foo=0 	# global variable foo

funct_1 () {

    local foo 	# variable foo local to funct_1

    foo=1
    echo "funct_1: foo = $foo"
}

funct_2 () {
    local foo 	# variable foo local to funct_2
foo=2
echo "funct_2: foo = $foo"
}

echo "global: foo = $foo"
funct_1
echo "global: foo = $foo"
funct_2
echo "global: foo = $foo"

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

[me@linuxbox ~]$ local-vars
global: foo = 0
funct_1: foo = 1
global: foo = 0
funct_2: foo = 2
global: foo = 0

می‌بینیم که اختصاص مقادیر به متغیر محلی foo درون توابع شل هیچ تاثیری بر روی مقدار foo تعریف شده در خارج از این توابع ندارد. این ویژگی به توابع شل (Shell Functions) اجازه میدهد تا به نحوی نوشته شوند که مستقل از دیگر اسکرییت‌ها پدیدار شوند. این ویژگی بسیار ارزشمند است چون که به یک بخش از برنامه کمک می‌کند تا از تضاد و ناسازگاری با دیگر برنامه‌ها جلوگیری کند. همچنین این ویژگی به توابع شل (Shell Functions) اجازه می‌دهد تا به نحوی نوشته شوند که پرتابل باشند. به این صورت است که می‌توان آنها را از یک اسکریپت کپی کرد و به اسکریپتی دیگر انتقال داد.

اسکریپت‌ها را در حالت اجرا نگه داریم

در حالیکه برنامه خود را توسعه می‌دهیم ایده خوبی است که برنامه خود را در یک وضعیت اجرا نگه داریم. با انجام این کار و تست متناوب، می‌توانیم خطاهای موجود در فرایند توسعه را تشخیص دهیم. این کار دیباگ مشکلات را بسیار آسان‌تر می‌کند. برای مثال، اگر که ما برنامه را اجرا کنیم و یک تغییر جزئی ایجاد کنیم. دوباره برنامه را اجرا کنیم و مشکل را پیدا کنیم کاملا مشخص است که تغییر اخیر ما منبع مشکل بوده است. با اضافه کردن توابع خالی که در زبان برنامه‌نویسی (stub خوانده می‌شوند) میتوانیم جریان منطقی برنامه خود را در مرحله کنونی تصدیق کنیم. زمانی که یک stub ایجاد می‌کنیم. ایده خوبی است که چیزی را قرار دهیم که برای برنامه‌نویس فیدیکی ارسال کند که نشان دهد جریان منطقی به پیش رفته است. اگر که به خروجی اسکریپت خود نگاهی بیندازیم. می‌بینیم که برخی خطوط خالی پس از برچسب زمانی وجود دارد ولی نمی‌توانیم از دلیل بوجود آمدن آن‌ها اطمینان پیدا کنیم:

[me@linuxbox ~]$ sys_info_page
<HTML>
    <HEAD>
        <TITLE>System Information Report For twin2</TITLE>
    </HEAD>
    <BODY>
        <H1>System Information Report For linuxbox</H1>
        <P>Generated 03/19/2012 04:02:10 PM EDT, by me</P>
    </BODY>
</HTML>

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

report_uptime () {
    echo "Function report_uptime executed."
    return
}

report_disk_space () {
    echo "Function report_disk_space executed."
    return
}

report_home_space () {
    echo "Function report_home_space executed."
    return
}

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

[me@linuxbox ~]$ sys_info_page
<HTML>
    <HEAD>
        <TITLE>System Information Report For linuxbox</TITLE>
    </HEAD>
    <BODY>
        <H1>System Information Report For linuxbox</H1>
        <P>Generated 03/20/2012 05:17:26 AM EDT, by me</P>
        Function report_uptime executed.
        Function report_disk_space executed.
        Function report_home_space executed.
    </BODY>
</HTML>

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

report_uptime () {
    cat <<- _EOF_
        <H2>System Uptime</H2>
        <PRE>$(uptime)</PRE>
        EOF_
    return
}

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

report_disk_space () {
    cat <<- _EOF_
        <H2>Disk Space Utilization</H2>
        <PRE>$(df -h)</PRE>
        _EOF_
    return
}

این تابع از فرمان df -h که برای تشخیص میزان فضای موجود در دیسک استفاده کرد. در نهایت تابع report_home_space، را به صورت زیر ایجاد می‌کنیم:

report_home_space () {
    cat <<- _EOF_
        <H2>Home Space Utilization</H2>
        <PRE>$(du -sh /home/*)</PRE>
        _EOF_
    return
}

در اینجا از دفرمان du به همراه گزینه‌های -sh برای انجام این وظیفه استفاده کردیم. هر چند یک راهکار کامل برای این مشکل نیست. در حالیکه این دستور بر روی برخی سیستم‌ها مثل اوبونتو کار می‌کند ولی بر روی دیگر سیستم‌ها کار نمی‌کند. دلیل آن هم این است که بسیاری از سیستم‌ها مجوزهای دایرکتوری‌های خانگی را به صورتی تنظیم میکنند تا مانع از خواندن آن‌ها توسط دیگران (World) شوند که یک راهکار امنیتی مناسب به شمار می‌رود. بر روی این سیستم ها تابع report_home_space فقط در صورتی کار می‌کنند که اسکریپت ما با مجوزهای کاربر ارشد اجرا شود. یک راهکار بهتر این است که اسکریپت را به گونه ای تنظیم کنیم تا بر طبق مجوزهای کاربر رفتار کنند. به این موضوع در دروس بعدی می‌پردازیم.

درباره فرشید نوتاش حقیقت

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

نوشته‌های بیشتر از فرشید نوتاش حقیقت
قبلی آغاز یک پروژه در اسکریپت‌نویسی
بعدی کنترل جریان با if در اسکریپت‌نویسی

دیدگاهتان را بنویسید لغو پاسخ

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

جستجو
جستجو برای:
دسته‌بندی موضوعی مقالات
  • برنامه‌نویسی
    • پایتون
    • دواپس
  • پایگاه‌داده
    • MariaDB
    • MySQL
  • تجارت الکترونیک
    • بازاریابی اینترنتی
    • دیجیتال مارکتینگ
    • شبکه‌های اجتماعی
  • جامعه کاربری
    • لاگ
  • دسته‌بندی نشده
  • شبکه و امنیت
  • طراحی وب
    • سئو
    • سیستم مدیریت محتوا
      • وردپرس
  • فناوری‌های نوظهور
    • اینترنت اشیاء
    • رایانش ابری
      • OpenStack
    • کلان‌داده‌ها
  • گنو/لینوکس
    • توزیع
      • CentOS
      • اوبونتو
      • دبیان
      • فدورا
    • چیست
    • خط فرمان
  • مهاجرت به آزاد/متن‌باز
  • نرم‌افزار
    • اداری
      • لیبره آفیس
        • ایمپرس
        • بیس
        • دراو
        • رایتر
        • کالک
    • کاربردی
    • گرافیک و انیمیشن
      • بلندر
      • گیمپ
نماد الکترونیکی (اینماد)
پرداخت‌یار

محتوای باز؛ مرجع آموزشی نرم‌افزارهای آزاد/ متن‌باز

از اینکه قصد همکاری با رسانه «محتوای باز» را دارید بسیار خرسندیم و این مایه مباهات ماست.

نحوه همکاری با ما چندان پیچیده نیست و شرایط آن در ادامه، ارائه گردیده است.

دستمزد مدرسین

پیش از بیان شرایط ضبط ویدئو شایان ذکر است اشاره‌ای به دستمزد مدرسین سایت داشته باشیم.

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

صرف نظر از هر حالت ممکنه، می‌بایست شرایطی که در ادامه ذکر شده‌اند را رعایت کرده باشید.

در حالت اول (رایگان) رسانه محتوای باز (Open Content)، نه وجهی از شما برای نشر ویدئو می‌گیرد و نه وجهی به شما پرداخت می‌نماید و دوره آموزشی شما را به رایگان منتشر می‌کند.

اما در حالت بعدی طریقه همکاری به روش درآمد از فروش خواهد بود، به گونه‌ای که 70 درصد از کل مبلغ فروش دوره آموزشی متعلق به مدرس دوره بوده و 30 درصد مابقی به رسانه محتوای باز تعلق می‌گیرد.

شرایط کلی ضبط دوره آموزشی

دوره آموزشی مربوطه، صرف نظر از هر محتوایی که دارد می‌بایست در یکی از توزیعات گنو/لینوکسی ضبط شده باشد. (به‌عنوان مثال دوره دروپال در اوبونتو، دوره آموزشی کار با آردوینو در دبیان و امثالهم). اگر دوره آموزشی شما در محیط ویندوز و یا هر پلتفرم/سیستم‌عامل دیگری ضبط شده باشد از همکاری با شما معذوریم.

پیشنهاد می‌گردد برای ضبط دوره آموزشی در توزیع گنو/لینوکس از ابزار قدرتمند OBS استفاده نمایید. البته این صرفا یک پیشنهاد است و شما می‌توانید از هر ابزار مناسب دیگری برای این کار بهره ببرید.

برای آشنایی یا تسلط بیشتر می‌توانید دوره رایگان آموزش OBS محمد عابدینی را ببینید:

مشاهده دوره آموزش OBS
شرایط کیفی ضبط دوره آموزشی

کیفیت صدا از اهمیت ویژه‌ای برخوردار می‌باشد و می‌بایست فاقد هر گونه نویز یا صدای اضافی دیگری (صدای محیط پیرامون) باشد.

دوره آموزشی تهیه شده صرفا باید برای رسانه محتوای باز تدوین شده باشد و در هیچ سایت مشابه دیگری قرار نگرفته باشد.

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

دوره آموزشی ضبط شده می‌باید فاقد هر گونه لوگو یا آدرس سایت دیگری (در گوشه تصویر یا بک‌گراند صفحه دسکتاپ و هر جای دیگری) باشد.

در حین دوره، مدرس نباید به برند خاصی اشاره کند که جز رقبای ما به‌شمار می‌آیند.

مدرس باید در ابتدا در اواسط و در انتهای دوره به برند ما یعنی رسانه محتوای باز (Open Content) بصورت کلامی اشاره نماید.

مدرس، هنگام تدریس نباید تپق زده، سرفه یا عطسه کند یا صدای قورت دادن بزاقش شنیده شود و بایستی با صدای رسا، دوستانه و پرانرژی به تدریس بپردازد.

قبل از تدوین دوره آموزشی حتما با ما در تماس باشید و یک ویدیوی چنددقیقه‌ای (ترجیحا 5 الی 10 دقیقه)، بصورت نمونه‌کار برای ما بفرستید.

از همکاری با شما سپاسگزاریم.

فراخوان همکاری