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

کنترل جریان: ایجاد حلقه با while و until در اسکریپت‌نویسی

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

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

در این درس نگاهی به مفهوم تکرار و ایجاد حلقه می‌کنیم که موجب می‌شود بخش‌هایی از برنامه تکرار شوند. شل (Shell) سه گزینه برای ایجاد حلقه به ما داده است که دو مورد از آن‌ها یعنی While و Until را در این درس بررسی کرده و مورد آخر یعنی for را در دروس بعدی بررسی
خواهیم کرد.

ایجاد حلقه و تکرار (Looping)

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

  1. آوردن تخته برش
  2. آوردن چاقو
  3. جلو آوردن کاهو
  4. قرار دادن کاهو بر روی تخته برش
  5. بالا آوردن چاقو
  6. برش کاهو
  7. این کار را تکرار می کنیم

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

حلقه while

بش (Bah) نیز می‌تواند ایده مشابه را بیان کنند. فرض کنید که میخواهید ۵ عدد را در یک توالی ترتیب ۱ تا ۵ نمایش دهید. یک اسکریپت بش را می‌توان به صورت زیر ایجاد کرد:

#!/bin/bash

# while-count: display a series of numbers

count=1

while [ $count -le 5 ]; do
    echo $count
    count=$((count + 1))
done
echo "Finished."

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

[me@linuxbox ~]$ while-count
1
2
3
4
5
Finished.

ساختار دستوری whale نیز به صورت زیر است:

while commands; do commands; done

شبیه if عبارت while نیز وضعیت خروج یک لیست از فرمان‌ها را ارزیابی می‌کند. تا زمانی که وضعیت خروج صفر است. فرمان‌ها درون حلقه اجرا می‌شود. درون اسکریپت بالا متغیر count قبل از حلقه ایجاد و مقداردهی می‌شود مقدار اولیه ۱ است. سپس حلقه while وضعیت خروج را ارزیابی کرده و مقدار صفر را بازمی‌گرداند و دستورات درون حلقه اجرا می‌شود و
هر بار یک مقدار به مقدار count افزوده میشود پس از ٦ تکرار حلقه مقدار count به مقدار ٦ رسیده و دیگر فرمان تست وضعیت خروج صفر را بر نمی‌گرداند چونکه این بار $count کوچکتر از ۵ نیست بلکه ۶ هست. در نتیجه حلقه شکسته می‌شود و ادامه برنامه پس از loop اجرا می‌شود. ما می‌توانیم از یک حلقه while کمک بگیریم تا برنامه read menu را که در درس قبل ایجاد کردیم را توسعه دهیم. درست به صورت زیر:

#!/bin/bash

# while-menu: a menu driven system information program

DELAY=3 # Number of seconds to display results

while [[ $REPLY != 0 ]]; do
    clear
    cat <<- _EOF_
        Please Select:

        1. Display System Information
        2. Display Disk Space
        3. Display Home Space Utilization
        0. Quit
    _EOF_
    read -p "Enter selection [0-3] > "

    if [[ $REPLY =~ ^[0-3]$ ]]; then
        if [[ $REPLY == 1 ]]; then
            echo "Hostname: $HOSTNAME"
            uptime
            sleep $DELAY
        fi
        if [[ $REPLY == 2 ]]; then
            df -h
            sleep $DELAY
        fi
        if [[ $REPLY == 3 ]]; then
            if [[ $(id -u) -eq 0 ]]; then
                echo "Home Space Utilization (All Users)"
                du -sh /home/*
            else
                echo "Home Space Utilization ($USER)"
                du -sh $HOME
            fi
            sleep $DELAY
        fi
    else
        echo "Invalid entry."
        sleep $DELAY
    fi
done
echo "Program terminated."

با محصور کردن این منو درون حلقه loop قادر هستیم تا برنامه نمایش منو را پس از هر انتخاب تکرار کنیم . loop ادامه پیدا می‌کند تا زمانیکه REPLAY برابر صفر نباشد و منو دوباره نمایش داده می‌شود و این باعث می‌شود که این فرصت به کاربر داده شود تا یک بار دیگر منو را انتخاب کند. در پایان هر حرکت یک فرمان sleep اجرا می‌شود که باعث می‌شود برنامه برای چند ثانیه متوقف شود تا اجازه دهد نتایج انتخاب قبل از پاک شدن از روی صفحه نمایش دیده شود و سپس مجدد منو نمایش داده شود.

شکستن و خارج شدن از یک حلقه

بش (bash) دو فرمان درون‌ساخت را فراهم می‌کنند که می‌توان از آن‌ها برای کنترل جریان برنامه درون حلقه استفاده کرد. دستور break بلافاصله یک loop را می‌شکند و کنترل برنامه به عبارت بعدی پس از حلقه بازمی‌گردد. فرمان continue موجب می‌شود که باقیمانده حلقه رد شود و کنترل برنامه به تکرار بعدی حلقه بازگردد. در اینجا یک نسخه از برنامه while menu را می‌بینیم که فرمان‌های break و continue در آن به کار رفته‌اند.

#!/bin/bash

# while-menu2: a menu driven system information program

DELAY=3 # Number of seconds to display results

while true; do
    clear
    cat <<- _EOF_
        Please Select:

        1. Display System Information
        2. Display Disk Space
        3. Display Home Space Utilization
        0. Quit
    _EOF_
    read -p "Enter selection [0-3] > "

if [[ $REPLY =~ ^[0-3]$ ]]; then
    if [[ $REPLY == 1 ]]; then
        echo "Hostname: $HOSTNAME"
        uptime
        sleep $DELAY
        continue
    fi
    if [[ $REPLY == 2 ]]; then
        df -h
        sleep $DELAY
        continue
    fi
    if [[ $REPLY == 3 ]]; then
        if [[ $(id -u) -eq 0 ]]; then
            echo "Home Space Utilization (All Users)"
            du -sh /home/*
        else
            echo "Home Space Utilization ($USER)"
            du -sh $HOME
        fi
            sleep $DELAY
            continue
        fi
        if [[ $REPLY == 0 ]]; then
            break
        fi
    else
        echo "Invalid entry."
        sleep $DELAY
    fi
done
echo "Program terminated."

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

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

در این اسکریپت فرمان break زمانی به منظور خروج از حلقه استفاده میشود که انتخاب صفر باشد. فرمان continue در پایان دیگر انتخاب‌های اسکریپت قرار داده شده است تا اجرای بهتر را ممکن سازد.

با استفاده از continue اسکربیت زمانی که یک انتخاب شناسایی می‌شود از کدی که به آن نیازی نیست عبور می‌کند. برای مثال اگر انتخاب ۱ انتخاب شده و شناسایی شده باشد. دیگر دلیلی برای تست برای دیگر انتخاب‌ها نیست.

حلقه Until (تا زمانیکه)

فرمان until بسیار شبیه while می‌باشد. به جز اینکه until زمانیکه با وضعیت خروج غیر صفر مواجه شد به جای خروج از یک حلقه درست برعکس عمل می‌کند. یک حلقه until ادامه پیدا میکند تا زمانیکه وضعیت خروج صفر را دریافت کند و زمانیکه وضعیت خروج صفر را دریافت کرد از حلقه خارج می‌شود. در اسکریپت while count ما حلقه را ادامه می‌دادیم تا زمانیکه مقدار متغیر count کمتر یا برابر باشد. می‌توانیم همین نتیجه را با استفاده از حلقه until در اسکریپت زیر بدست آوریم:

#!/bin/bash

# until-count: display a series of numbers

count=1

until [ $count -gt 5 ]; do
    echo $count
    count=$((count + 1))
done
echo "Finished."

با تغییر عبارت تست به  $count -gt حلقه until در زمان صحیح خارج خواهد شد.

تصمیم به استفاده از while یا until بستگی به این دارد که کدام یک می‌تواند واضح ترین ساختار تست را برای شما ایجاد کند.

خواندن فایل‌ها با حلقه‌ها

while و until می توانند ورودی استاندارد را پردازش کنند. این ویژگی به فایل‌ها اجازه می‌دهد تا با حلقه‌های while و until پردازش شوند. در مثال زیر ما محتویات فایل distros.txt را که در درس‌های اولیه ایجاد کرده‌ایم نشان می‌دهیم:

#!/bin/bash

# while-read: read lines from a file

while read distro version release; do
    printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
        $distro \
        $version \
        $release
done < distros.txt

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

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

#!/bin/bash

# while-read2: read lines from a file

sort -k 1,1 -k 2n distros.txt | while read distro version release; do
    printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
        $distro \
        $version \
        $release
done

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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