ساخت فانکشن در بچ اسکریپت
در زبانهای برنامه نویسی فانکشن به مجموعه از کدها گفته میشود که برای انجام یک عمل مشخص سازماندهی شده اند. از مهمترین مزیت های Function میتوان به استفاده مجدد از کدهای نوشته شده اشاره نمود. در بچ اسکریپت هم شما میتوانید با استفاده از ویژگی Function بخشی از دستورات را برای انجام یک هدف مشخص استفاده کنید. یعنی تعدادی دستور پشت سر هم بنویسید که با فراخوانی آن یک عمل مشخص انجام شود. در ادامه با آموزش ساخت فانکشن در بچ اسکریپت همراه با نووا بلاگ باشید
ساخت فانکشن در بچ اسکریپت
برای ساخت فانکشن در بچ اسکریپت باید از ویژگی Label استفاده کنید. یعنی دقیقا همان بخش بندی فایل Batch با استفاده از علامت Colon برای مثال به اسکریپت زیر توجه کنید:
@ECHO OFF :FIRSTFUNC ECHO IT’S A SILMPE FUNCTION YOU CAN USE IT SOME-COMMANDS.EXE EXIT /B
در اسکریپت بالا یک Function ساده تعریف شده که نام آن FIRSTFUNC میباشد و در آن سه دستور مختلف اجرا میشود. به اسکریپت بعدی توجه کنید:
@ECHO OFF TITLE CALL A FUNCTION GOTO :MAIN :FIRSTFUNC ECHO IT’S A SIMPLE FUNCTION! EXIT /B 0 :MAIN ECHO YOU CAN CALL A FUNCTION WITH CALL COMMAND CALL :FIRSTFUNC PAUSE
اسکریپت بالا از دو بخش MAIN و FIRSTFUNC تشکیل شده که بخش FIRSTFUNC آن در واقع یک تابع محسوب میشود و این تابع توسط دستور Call در بخش Main فراخوانی شده است.
فراخوانی تابع ها با دستور Call
اگر فصل قبل را بیاد آورید شما میتوانید بخشهای مختلف یک فایل Batch را با استفاده از دستور Call فراخوانی کنید که البته دیگر به آن نمیتوان بخش گفت بلکه باید به آن Function یا تابع گفت. همچنین میتوانید Function ها را به همراه Argument فراخوانی کنید. یعنی یک تابع را با آنچه که نیاز دارید اجرا کنید. برای درک بهتر این موضوع به اسکریپت زیر توجه کنید:
@ECHO OFF TITLE CALL FUNCTION WITH ARGUMENTS GOTO :MAIN EXIT :FUNC1 ECHO THE FIRST ARGUMENT WAS %~1 ECHO THE SECOND ARGUMENT WAS %~2 ECHO THE THIRD ARGUMENT WAS %~3 GOTO :EOF :MAIN ECHO YOU CAN CALL A FUNCTION WITH SOME ARGUMENT ECHO FOR EXAMPLE: CALL :FUNC1 ARG1 ARG2 ARG3 EXIT /B 0
همانطور که در اسکریپت بالا مشاهده میکنید تابع FUNC1 به همراه سه Argument فراخوانی شده است که این Argument ها در بخش FUNC1 توسط دستور ECHO مورد نمایش قرار میگیرند.
نکته: همیشه برای خروج از توابع یا از دستور GOTO :EOF استفاده کنید یا از دستور EXIT /B تا اسکریپت بدون مشکل از تابع خارج شود. در صورتی که از دستور EXIT بدون پارامتر /B استفاده کنید کار اسکریپت شما نا تمام خواهد ماند چرا که دستور EXIT به طور کامل فایل Batch را متوقف میکند.
فراخوانی توابع با مقدار برگشتی
شما میتوانید یک Function را صدا بزنید تا مقدارهای را از آن دریافت کنید. مثلا یک اسکریپت بسازید که در آن با استفاده از دستور Call محتوای چندین Variable را از یک Function دریافت میکند. برای درک بهتر این موضوع به اسکریپت زیر توجه کنید:
@ECHO OFF TITLE CALL FUNCTION WITH RETURN VALUES GOTO :MAIN :FIRSTFUNC ECHO GETTING VLAUES FOR ARGS SET %~1=ITS BE A FIRST VALUE SET %~2=ITS BE A SECOND VALUE SET %~3=ITS BE A THIRD VALUE EXIT /B 0 :MAIN CALL :FIRSTFUNC VALUE1 VALUE2 VALUE3 ECHO %VALUE1% %VALUE2% %VALUE3%
در اسکریپت بالا ابتدا دستور Call تابع FIRSTFUNC را به همراه سه Argument فراخوانی میکند سپس در تابع FIRSTFUNC سه متغیر ساخته میشود که نام این متغیر ها همان Argument های اول تا سوم میباشند (VALUE 1 – VALUE2 – VALUE3) در آخر کار تابع FIRSTFUNC به پایان میرسد و دستور ECHO در بخش MAIN محتوای متغیر های ساخته شده را نمایش میدهد.
تغییر محتوای متغیر ها با استفاده از توابع
یکی از کارهای که میتوان با استفاده از توابع در Batch Script انجام داد تغییر محتوای متغیر ها میباشد. یعنی مثلا شما میتوانید یک تابع درست کنید که مقدار متغیر ها را دو برابر کند یا اینکه محتوای آنها را کاملا تغییر دهد. برای انجام چنین کاری کافیست در تابع متغیرهای را با نام همان متغیر های که میخواهید محتوای آنها را تغییر دهید بسازید سپس محتوای جدیدی به آنها بدهید. برای درک بهتر این موضوع به اسکریپت زیر توجه کنید:
@ECHO OFF TITLE USE FUNCTIONS GOTO :MAIN :FIRSTFUNC SET /A X+=%X% SET /A Y+=%Y% SET /A Z+=%Z% SET /A TOTAL=%X%+%Y%+%Z% ECHO. ECHO MUTIPLE ALL NUMBER X2... EXIT /B 0 :MAIN SET /A X=2 SET /A Y=3 SET /A Z=5 SET /A TOTAL=%X%+%Y%+%Z% ECHO THE NUMBER OF X AND Y AND Z EQULE TO: %X%+%Y%+%Z%=%TOTAL% CALL :FIRSTFUNC ECHO. ECHO AFTER CALL FIRSTFUNC THE NUMBERS CHANGE TO: %X%+%Y%+%Z%=%TOTAL%
در اسکریپت بالا ابتدا دستور Goto اسکریپت را از بخش Main اجرا میکند همانطور که در بخش Main مشاهده میکنید سه متغیر ساخته شده که مقدار آنها به ترتیب 2 و 3 و 5 میباشد سپس یک متغیر دیگر ساخته شده که محتوای آن جمع سه متغیر قبل است یعنی عدد ده، پس از آن دستور Echo مقدار متغیر ها را نمایش میدهد و دستور Call تابع FIRSTFUNC را فراخوانی میکند در تابع FIRSTFUNC به مقدار متغیر ها به اندازه مقدار خودشان اضافه میشود. در آخر دستور ECHO نتایج جدید متغیر ها را به نمایش میگذارد.
متغیر های محلی در توابع
شما میتوانید از دستور SETLOACL برای محلی نمودن متغیر ها در توابع استفاده کنید تا متغیر های که در یک تابع درست میکنید با متغیر های دیگر توابع تداخل ایجاد نکنند. برای انجام چنین کاری کافیست در توابع از دستورات SETLOCAL و ENDLOCAL استفاده کنید. به اسکریپت زیر توجه کنید:
@ECHO OFF TITLE LOCAL VARIABLE IN FUCNTIONS GOTO :MAIN :FIRSTFUNC SETLOCAL ECHO CHANGING THE NUMBERS... SET /A FIRST_N=99 SET /A SECO_N=88 SET /A THIRD_N=77 ECHO THE F NUMBER IS: %FIRST_N% THE S NUMBER IS: %SECO_N% AND THE TH NUMBER IS: %THIRD_N% GOTO :EOF :MAIN CLS SET /A FIRST_N=10 SET /A SECO_N=12 SET /A THIRD_N=8 CALL :FIRSTFUNC ECHO THE FUNCTION CALLED BUT NONE OF THE VARIABLE WAS CHANGED: ECHO THE F NUMBER IS: %FIRST_N% THE S NUMBER IS: %SECO_N% AND THE TH NUMBER IS: %THIRD_N% نتایج اجرای اسکریپت بالا: CHANGING THE NUMBERS... THE F NUMBER IS: 99 THE S NUMBER IS: 88 AND THE TH NUMBER IS: 77 THE FUNCTION CALLED BUT NONE OF THE VARIABLE WAS CHANGED: THE F NUMBER IS: 10 THE S NUMBER IS: 12 AND THE TH NUMBER IS: 8
همانطور که در نتایج اسکریپت بالا مشاهده میکنید پس از فراخوانی شدن تابع FIRSTFUNC از بخش MAIN محتوای متغیر های آن با دستور ECHO نمایش داده میشوند سپس بعد از بازگشت به بخش MAIN محتوای متغیر های تابع FIRSTFUNC با متغیر های بخش MAIN جایگزین نشده اند چرا که در تابع FIRSTFUNC از دستور SETLOCAL برای محلی نمودن متغیر ها استفاده شده و در آخر آن دستور GOTO :EOF اجرا شده که به معنای پایان عملکرد تابع است به همین دلیل کلیه متغیر های ساخته شده در بخش تابع از بین میروند.
دریافت محتوای متغیر ها پس از دستور ENDLOCAL
همانطور که میدانید تا زمانیکه دستور SET به طور کامل اجرا نشود محتوای متغیر ساخته شده توسط آن نیز قابل استفاده نیست مگر اینکه در اسکریپت از دستور SETLOCAL ENABLEDELAYEDEXPANSION استفاده شود. در آن صورت کافیست دستور خوانده شده تا بتوان از محتوای آن نیز استفاده نمود. به اسکریپت زیر توجه کنید:
@ECHO OFF TITLE SET COMMAND SET VAR1=IT IS A TEST VARIABLE & ECHO %VAR1% SET VAR2=IT IS JUST A TEST VARIABLE ECHO %VAR2% PAUSE نتایج اجرای اسکریپت بالا: ECHO is off. IT IS JUST A TEST VARIABLE
همانطور که در نتایج اسکریپت بالا مشاهده میکنید محتوای متغیر VAR1 نمایش داده نمیشود به این خاطر که دستور SET هنوز توسط Shell تفسیر نشده است تا به نمایش گذاشته شود. شما میتوانید با استفاده از همین ویژگی بعد از دستور ENDLOCAL محتوای متغیر های ساخته شده در تابع را به خارج از تابع منتقل کنید. برای درک بهتر این موضوع به اسکریپت زیر توجه کنید:
@ECHO OFF TITLE ENDLOCAL IN FUNCTIONS GOTO :MAIN :FIRSTFUNC SETLOCAL ECHO ADDING NUMBER TO CURRENT VARIABLE ENDLOCAL & SET /A X+=9 & SET /A Y*=5 & SET /A Z+=7 & GOTO :EOF :MAIN SET X=1 SET Y=2 SET Z=3 ECHO THE NUMBER OF X AND Y AND Z WAS: %X% %Y% %Z% CALL :FIRSTFUNC ECHO. ECHO THE NUMBER CHANGE TO: %X% %Y% %Z%
در اسکریپت بالا پس از فراخوانی شدن تابع FIRSTFUNC با وجود دستورات SETLOCAL و ENDLOCAL در تابع، مقدار متغیر ها در بخش MAIN تغییر نموده اند به این خاطر که بعد از دستور ENDLOCAL علامت & گذاشته شده و بعد از آن متغیر ها در همان سطر ENDLOCAL ساخته شده اند.
مثال اول: فراخوانی توابع با Argument
در این اسکریپت Function به همراه Argument فراخوانی میشود. و مقدارهای را باز میگرداند.
@ECHO OFF TITLE USET ARGUMENT WITH FUNCTION COLOR 0A MODE CON COLS=80 LINES=25 GOTO :MAIN :BOOK_CENTER ECHO ______________________________________________________________ ECHO SENDING BOOKS TO YOUR INVENTORY... SET /A %~1+=100 GOTO :EOF :MAIN SET /A STUDENT_NUMBER=50 SET /A BOOK_INVENTORY=0 SET /A CLASS_NUMBER=5 ECHO WE HAVE %STUDENT_NUMBER% STUDENTS ECHO EVERY STUDENT NEED TWO BOOKS ECHO EVERY TEN STUDENTS NEED ONE CLASSROOM SET /A REQUIRE_BOOK=%STUDENT_NUMBER%*2 ECHO ITS MEAN WE NEED %REQUIRE_BOOK% BOOKS FOR ALL OF OUR STUDENTS :CHECK_BOOKS IF %REQUIRE_BOOK% LEQ %BOOK_INVENTORY% ( ECHO WE HAVE ENOUGH BOOKS PER STUDENTS )ELSE ( ECHO WE HAVENT ENOUGH BOOKS FOR ALL OF OUR STUDENTS PAUSE >NUL CALL :BOOK_CENTER BOOK_INVENTORY ECHO RE CHECK BOOK INVENTORYS TIMEOUT /T 10 >NUL GOTO :CHECK_BOOKS ) PAUSE