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

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

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

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

الگوها

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

در خط فرمان شما غالباً از جانشین‌ها(globs) استفاده می‌کنید. جانشین‌ها به طور مساعدی شکل ساده الگوها هستند، که می‌توانند به آسانی برای انطباق با گروهی از فایل‌ها به کار بروند، یا متغیرها را در برابر قواعد ساده بررسی کنند.

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

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


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


الگوهای جانشین(Glob Patterns)

جانشین‌ها(globs) اگر فقط برای راحتی باور نکردنی‌شان باشد هم، مفهوم بسیار مهمی در BASH می‌باشند. درک صحیح globها به طُرق بسیاری برای شما مفید خواهد بود. جانشین‌ها اساساً الگوهایی می‌باشند که می‌توانند برای انطباق با نام فایلها یا سایر رشته‌ها به کار بروند.

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

  • *: بر هر رشته‌ای ازجمله رشته تهی منطبق می‌گردد.

  • ?: بر یک کاراکتر منفرد منطبق می‌شود.

  • [...]: بر هر یک از کاراکترهای محصور در کروشه‌ها منطبق می‌شود.

جانشین‌ها به طور صریح از هر دو طرف مهار می‌گردند. این به آن معناست که یک جانشین بایستی بر تمام رشته( نام فایل یا رشته داده‌ای) منطبق شود. ‎a*‎ با رشته ‎cat منطبق نیست، به علت آنکه فقط بر at، منطبق می‌شود، نه بر تمام رشته. در حالیکه، یک جانشین ca*‎، با رشته cat منطبق می‌گردد.

در اینجا مثالی در مورد اینکه چگونه می‌توانیم از الگوهای جانشین برای بسط نام فایلها استفاده کنیم:

    $ ls
    a  abc  b  c
    $ echo *
    a abc b c
    $ echo a*
    a abc

BASH جانشین را می‌بیند، به عنوان مثال ‎a*‎ را، واین جانشین را از طریق نگاه کردن به دایرکتوری جاری و مطابقت glob با تمام فایلهای موجود در آن، بسط می‌دهد. هر نام فایلی که با الگوی جانشین مطابقت داشته باشد، به شمار آمده و به جای جانشین به کار می‌رود. در نتیجه جمله ‎echo a*‎ با جمله ‎echo a abc‎ تعویض شده و بعد اجرا گردیده است.

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

    $ touch "a b.txt"
    $ ls
    a b.txt
    $ rm *
    $ ls
    $

در اینجا، * به نام یک فایل منفرد ‎ "a b.txt"‎ بسط یافته. این نام فایل به عنوان یک شناسه منفرد به فرمان rm تحویل می‌گردد. مهم است که بدانیم کاربرد جانشین‌ها برای به شمار آوردن نام فایلها همواره از ایده به کارگیری دستور `ls` برای این متظور، بهتر هستند. در اینجا مثالی می‌آوریم با ترکیب پیچیده‌تری که بعداً آنرا پوشش خواهیم داد، اما دلیل مطلب فوق را خیلی خوب تشریح می‌کند:

    $ ls
    a b.txt
    $ for file in `ls`; do rm "$file"; done
    rm: cannot remove `a': No such file or directory
          rm: cannot remove `b.txt': No such file or directory
    $ for file in *; do rm "$file"; done
    $ ls
    $

در اینجا از فرمان for برای پوشش دادن تمام خروجی دستور ls استفاده کرده‌ایم. دستور ls رشته a b.txt را به خروجی می‌دهد. دستور for آن رشته را به کلمات تفکیک می‌کند و به تعداد آن کلمات تکرار را انجام می‌دهد. در نتیجه، for ابتدا برای a، و بعد هم برای b.txt تکرار می‌شود. بدیهی است، این، آنچه ما می‌خواهیم نیست. در حالیکه، glob، به شکل صحیح بسط می‌یابد. و فایل "a b.txt" را نتیجه می‌دهد، که فرمان for آن را به عنوان یک شناسه منفرد دریافت می‌کند.

BASH همچنین از یک ویژگی به نام جانشین‌های توسعه یافته پشتیبانی می‌کند. این جانشین‌ها در ماهیت قدرتمندتر هستند، از لحاظ فنی، آنها معادل عبارتهای معمولی هستند، اگر چه ساختار آنها به ظاهر متفاوت با آنچه اکثریت مردم به کار می‌برند، باشد. این ویژگی به طور پیش‌فرض غیر فعال است، لیکن می‌تواند با دستور shopt، که برای تغییر وضعیت گزینه‌های پوسته به کار می‌رود، فعال شود. این دستور کوته‌نوشتی از عبارت shell options می‌باشد:

    $ shopt -s extglob
  • ‎?(list)‎: صفر یا یک مورد تطابق با الگوی داده شده.

  • ‎*(list)‎: هر یا هیچ مورد انطباق با الگوی مورد اشاره.

  • ‎+(list)‎: یک مورد انطباق با الگو یا بیشتر.

  • ‎@(list)‎: انطباق با یکی از نمونه‌های داده شده.

  • ‎!(list)‎: با هر چیزی غیر از موارد ذکر شده انطباق می‌یابد.

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

    $ ls
    names.txt  tokyo.jpg  california.bmp
    $ echo !(*jpg|*bmp)
    names.txt

در اینجا الگوی جانشین(list) به هر چیزی که بر ‎*jpg‎ یا ‎*bmp‎ منطبق نمی‌شود بسط داده می‌شود. فقط فایلهای متن همان طور که بسط یافته‌اند به دستور تحویل شده‌اند.

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

    $ filename="somefile.jpg"
    $ if [[ $filename = *.jpg ]]; then
    > echo "$filename is a jpeg"
    > fi
    somefile.jpg is a jpeg

کلمه کلیدی ‎[[‎ و دستور داخلی case ( که بعداً با تفصیل بیشتری شرح داده می‌شوند ) هر دو فرصت بررسی یک رشته در برابر جانشین معمولی --و یا جانشین توسعه یافته در صورتی‌که فعال شده باشد-- را فراهم می‌کنند.

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

    $ echo th{e,a}n
    then than
    $ echo {/home/*,/root}/.*profile
    /home/axxo/.bash_profile /home/lhunath/.profile /root/.bash_profile /root/.profile
    $ echo {1..9}
    1 2 3 4 5 6 7 8 9
    $ echo {0,1}{0..9}
    00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19


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




  • جانشین( glob ): یک جانشین رشته‌ایست که می‌تواند با نام فایلها یا رشته‌های معینی منطبق گردد.


عبارت‌های منظم

عبارت‌های منظم(regex) مشابه الگوهای جانشین هستند، اما در BASH نمی توانند برای انطباق با نام فایل به کار بروند. از نگارش 3.0، BASH عملگر ‎=~‎ در کلمه کلیدی ‎[[‎ را پشتیبانی می‌کند. این عملگر رشته‌ای را که قبل از آن می‌آید با الگوی regex که بعد از آن می‌آید، مطابقت می‌دهد. موقعی که رشته با الگو منطبق گردد، کلمه‌کلیدی ‎[[‎ یک کد خروج 0 (true) بر می‌گرداند. اگر رشته با الگو مطابقت نداشته باشد، یک کد خروج 1 (false) باز گردانده می‌شود. در صورتیکه ترکیب دستوری الگو معتبر نباشد، ‎[[‎ از عملیات صرفنطر نموده و یک کد خروج 2 صادر می‌کند.

BASH از عبارت منظم توسعه یافته (ERE) نیز استفاده می‌کند. ما در این راهنما regexها را به طور گسترده پوشش نمی‌دهیم، اما اگر این مفهوم برای شما جالب است، لطفاً به عبارت منظم، یا Extended Regular Expressions مراجعه نمایید.

الگوهای عبارت منظم که برای گرفتن گروه‌ها(پرانتزها)به کار می‌روند، رشته‌های گرفته شده‌شان را برای بازیابی بعدی، به متغیر BASH_REMATCH، تخصیص خواهند داد.

اجازه دهید، تشریح کنم که regex در BASHچگونه کار می‌کند:

$ langRegex='(..)_(..)'
$ if [[ $LANG =~ $langRegex ]]
> then
> echo "Your country code (ISO 3166-1-alpha-2) is  ${BASH_REMATCH[2]}."
> echo "Your language code (ISO 639-1) is ${BASH_REMATCH[1]}."
> else
> echo "Your locale was not recognised"
> fi

آگاه باشید که تفکیک کلمه regex در BASH از نگارش 3.1 به 3.2 تغییر کرده است. قبل از نگارش 3.2 محصور نمودن الگوی regex در نقل‌قول، صحیح بود، که این در نگارش 3.2 تغییر کرده است. پس بنابراین، regex همیشه باید غیر نقل‌قولی باشد. شما باید هر کاراکتر ویژه را با کاربرد کاراکتر \ محافظت کنید. بهترین روش برای سازگاری همیشگی، قرار دادن regex در یک متغیر و بسط آن متغیر در ‎ [[‎ بدون استفاده از نقل‌قول‌ها می‌باشد.


  • تکرار مفید:
    از آن جهت که روش regex مورد استفاده در 3.2 در نگارش 3.1 نیز معتبر می‌باشد، ما قویاً پیشنهاد می‌کنیم هرگز عبارت منظم خودتان را نقل‌قولی نکنید. به خاطر داشته باشید که کاراکترهای ویژه را به طور صحیح با کاراکتر گریز پوشش دهید!

  • برای سازگاری سراسری ( اجتناب از الزام به پوشش کاراکترهای خاص ) از یک متغیر برای ذخیره عبارت منظم خود استفاده کنید، مانند. ‎re='^\*( >| *Applying |.*\.diff|.*\.patch)'; [[ $var =~ $re ]] این خیلی آسانتر از آن است که شما فقط ترکیب دستوری ERE را بنویسید و از لزوم پوشش، به همان خوبی اجتناب کنید که با تمام نگارش‌های ‎ 3.x ‎ از BASH سازگار باشد.

  • همچنین، بخش E14 از Chet Ramey's Bash FAQ، را ملاحظه نمایید.




  • عبارت منظم: یک عبارت منظم، الگوی پبچیده‌تری است که می‌تواند برای انطباق با رشته‌های معین به کار برود( اما بر خلاف جانشین‌ها نمی‌تواند به نام فایل‌ها بسط داده شود ).

نظرات 0 + ارسال نظر
ایمیل شما بعد از ثبت نمایش داده نخواهد شد