آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

قابلیت تست اسکریپت

BashTesting

چگونگی افزودن قابلیت آزمایش کردن به برنامه‌ها

‎[توسط Jari Aalto] اگر شما در حال توسعه برنامه‌های بزرگتر می‌باشید، قابلیت آزمایش(آنچه برنامه انجام خواهد داد) قبل از استفاده واقعی، می‌تواند در تشخیص مشکلات، پیش از وقوع آنها در عمل، به شما کمک کند. در اینجا ما تابع ‎Run()‎ را تعریف می‌کنیم که برای نمایندگی تمام فرمانها به کار می‌رود. اگر وضعیت TEST فعال باشد، فرمانها به طور واقعی اجرا نمی‌شوند، بلکه فقط برای بازبینی در صفحه نمایش چاپ می‌شوند. حالت آزمایش با گزینه خط فرمان ‎-t‎ برنامه فعال می‌شود که از طریق دستور داخلی getopt پوسته Bash خوانده می‌شود.

قلب نمایش تجربی، تابع ‎Demo()‎ است که در آن می‌بینیم فراخوان‌ها چگونه آزمایش را به کار می‌بندند. دقت به خرج بدهید که موقع وجود هر فوق کاراکتر پوسته در فرمان، چگونه از نقل‌قولها استفاده می‌شود. همچنین توجه نمایید که چگونه به فراخوان ‎ 'Run'‎ در فراخوانی‌های داخل پوسته فرعی نیز نیاز دارید. نمایش فراخوان‌های پوسته فرعی تحت وضعیت آزمایش چنانکه از آخرین خروجی می‌توانید ببینید، محدود است.

می‌توانید راهکار آزمایش مشابهی به برنامه خودتان اضافه کنید، به وسیله: ‎ (1‎کپی ‎Run()‎ ‏ ‎(2‎ به کار گرفتن متغیر TEST‎ ‏‎(3‎ ویرایش تمام فراخونی‌های فرمان پوسته برای انجام ‎Run()‎. در عمل، قرار دادن برنامه پوسته به طور کامل تحت وضعیت آزمایش کردن خالص بسیار دشوار ست، زیرا ممکن است برنامه‌ها ساختارهای خیلی پیچیده‌ای از پوسته را استفاده کنند و وابسته به خروجی‌هایی باشند که توسط دستورات قبلی تولید می‌شوند. بازهم، امکان پیشرفت قابلیت آزمایش کردن بهتر از هیچ است و شانس بهتری برای بازبینی اجرای برنامه قبل از انجام آن در عمل، می‌باشد.

  • تابع Run به طوری که در اینجا نشان داده شده بی خطر کار نمی‌کند. به عنوان مثال

    •   griffon:/tmp$ Run touch "foo bar"
        griffon:/tmp$ ls -ld foo* bar*
        -rw-r--r-- 1 greg greg 0 2009-08-29 12:19 bar
        -rw-r--r-- 1 greg greg 0 2009-08-29 12:19 foo

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

    •   local cmd
        printf -v cmd "%q " "$@"

    اما با | به جای عملگر لوله، به عنوان داده رفتار می‌کند. ولی شما شخصی هستید که می‌خواست با eval ور برود، بنابراین راه تصحیح آن را بیابید! - GreyCat

خروجی:

$ bash test-demo.sh -t

test-demo.sh -- ‏نمایش آنکه چطور ویژگی آزمایش کردن می‌تواند در یک برنامه اضافه گردد
# DEMO: یک فرمان‎
ls -l

# DEMO: یک فرمان با لوله‎
ls -l | sort

# DEMO: فرمان با لوله و تغییر مسیر‎
ls -l | sort > /tmp/jaalto.1396-ls.lst

# DEMO: فرمان با لوله وتغییر مسیر و کاربرد نقل‌قولها‎
ls -l | sort > "/tmp/jaalto.1396-ls.lst"

# DEMO: فرمان با فراخوانی پوسته فرعی‎
echo ls -l

#
# test-demo.sh --‏نمایش آنکه چطور ویژگی آزمایش کردن می‌تواند در یک برنامه اضافه گردد
#
#       Copyright (C) 2009 Jari Aalto <jari.aalto@cante.net>
#
#                                                      مجوز برنامه ‎‎
#‎
#         این برنامه نرم‌افزار آزاد است، شما می‌توانید آنرا تحت شرایط‎
#         گنو نگارش 2 یا(به انتخاب خود) هر نگارش پس از آن  GPL مجوز ‎
#         چنانکه توسط بنیاد نرم‌افزار آزاد منتشر گردیده است، توزیع و‎
#                                                . یا ویرایش نمایید‎
#
#         این برنامه به این امید که مفید خواهد بود، اما بدون هرگونه‎
#          تضمین، حتی التزام تلویحی قابل استناد یا صلاحیت برای مقاصد ‎
#         .گنو را ببینید GPL خاص توزیع می‌گرد. برای توضیح بیشتر مجوز‎
#
#          گنو را با برنامه دریافت کنید GPL شما باید یک کپی از مجوز‎
#             .وگرنه با بنیاد نرم‌افزار آزاد به آدرس زیر مکاتبه کنید‎
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
#       02110-1301, USA.
#
#       Visit <http://www.gnu.org/copyleft/gpl.html>
#
#                                                           توضیحات‎
#
#        برای فعال سازی اشکالزدایی و امکانات آزمایش کردن در اسکریپت‌های ‎
#        را اضافه نموده و از آن برای پروکسی تمام  Run() پوسته، تابع ‎
#                                             .فرمانها استفاده کنید‎
#
#                                                           نکته ها‎
#
#    توابع در برنامه «قبل از کاربرد تعریف شده» هستند. فراخوانی تابع‎
#       .(فرمان)فقط در صورتی ممکن است که موجود باشد(تعریف شده باشد)‎
#
#   آشکار وجود دارد. این امر از ‎Main()‎ جایی که برنامه شروع می‌شود یک‎
#   ،برنامه‌نویسی به سبک خوب پیروی می‌کند. با قرار دادن کُد داخل توابع‎
#    همچنین تصوری از پیمانه‌ای بودن و اجزاء متشکله قابل استفاده مجدد‎
#                                                      .ایجاد می‌کند

DESC="$0 -- نمایش آنکه چطور ویژگی آزمایش کردن می‌تواند در یک برنامه اضافه گردد"‎
TEMPDIR=${TEMPDIR:-/tmp}
TEMPPATH=$TEMPDIR/${LOGNAME:-foo}.$$

# یا هر چیز دیگر ‎TEST=""‎ این متغیر باید تعریف نشده باشد، نه به صورت‎
unset TEST

Help ()
{
    echo "\
$DESC

:گزینه‌های معتبر‎

-d      Debug. قبل از اجرای فرمان آن را نمایش می‌دهد‎
-t      Test mode. دستورات را نمایش می‌دهد، به طور واقعی اجرا نمی‌کند‎

 تقدم دارد ‎-d‎ نسبت به گزینه ‎-t‎ گزینه"‎

    exit ${1:-0}
}

Run ()
{
    if [ "$TEST" ]; then
        echo "$*"
        return 0
    fi

    eval "$@"
}

Echo ()
{
    echo "# DEMO: $*"
}

Demo ()
{
    Echo "یک فرمان"‎
    Run ls -l

    Echo "یک فرمان با لوله"‎
    Run "ls -l | sort"

    Echo "یک فرمان با لوله و تغییر مسیر"‎
    Run "ls -l | sort > $TEMPPATH-ls.lst"

    Echo "فرمان با لوله وتغییر مسیر با استفاده از نقل‌قولها"‎
    Run "ls -l | sort > \"$TEMPPATH-ls.lst\""

    #   را داخل پوسته فرعی نیز قرار بدهید،  ‎Run()‎ لازم است فراخوان‎
    #     .وگر نه به طور واقعی اجرا می‌شود و وضعیت آزمایش خنثی می‌گردد‎

    Echo "یک فرمان و یک پوسته فرعی"‎
    Run "echo $( Run ls -l )"
}

Main ()
{
    echo "$DESC"

    OPTIND=1
    local arg

    while getopts "hdt" arg "$@"
    do
        case "$arg" in
            h)  Help
                ;;
            t)  TEST="test"
                ;;
        esac
    done

    #   .حذف گزینه‌های پیدا شده از شناسه‌های سطر فرمان‎
    shift $(($OPTIND - 1))

    #   اجرای نمایش‎
    Demo
}

Main "$@"

# پایان فایل


BashTesting (آخرین ویرایش ‎2010-07-30 07:14:54‎ توسط Lhunath)