آموزش‌های خط فرمانی

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

آموزش‌های خط فرمانی

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

گروه بندی دستورات

ادامه یادداشت قبل


3. گروه‌بندی دستورات

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

فرض کنید می‌خواهید یک فایل را در صورت وجود کلمه معین "good" در آن و نیز عدم وجود کلمه مشخص "bad" در آن حذف کنید. با استفاده از grep ( فرمانی که ورودی‌اش را برای الگوهای تعیین شده بررسی می‌کند)، این شرایط را به این صورت ترجمه می‌کنیم:

grep -q goodword "$file" #exit status 0 (success) if "$file" contains 'goodword'
! grep -q "badword" "$file" #exit status 0 (success) if "$file" does not contain 'badword'

ما از گزینه ‎-q‎‏(quiet)‏ با فرمان grep استفاده کردیم چون نمی‌خواهیم موارد انطباق را به خروجی ارسال کند، فقط می‌خواهیم کد خروج را تنظیم کند.

علامت ! در جلوی دستور موجب می‌شود Bash وضعیت خروج فرمان را نفی کند. اگر دستور صفر(موفقیت) را برگرداند، کاراکتر ! آن را به عدم موفقیت تبدیل می‌کند، و برعکس، اگر کد غیر صفر(عدم موفقیت) برگرداند، کاراکتر ! آن را به موفقیت تبدیل نماید.

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

    $ grep -q goodword "$file" && ! grep -q badword "$file" && rm "$file"

این بخوبی کار می‌کند( در حقیقت می‌توانیم هر تعداد از &&ها که می‌خواهیم بدون مشکل با هم زنجیر کنیم ). حالا فرض کنید می‌خواهیم در حالتی که حذف فایل ناموفق باشد، یک پیغام خطا نمایش بدهیم:

    $ grep -q goodword "$file" && ! grep -q badword "$file" && rm "$file" || echo "Couldn't delete: $file" >&2

این هم ظاهراً در نگاه اول صحیح است. اگر کد خروج rm برابر 0(موفقیت) نباشد،سپس عملگر || ماشه اجرای دستور بعدی را می‌ کشد و echo پیغام خطا را نمایش می‌دهد(‎>&2‎ در خروجی استاندارد خطا).

اما مشکلی وجود دارد. موقعی که ما یک توالی از دستوراتی که با عملگرهای شرطی از یکدیگر جدا شده‌اند، داریم Bash به ترتیب از چپ به راست به هر یک از آنها نگاه می‌کند. وضعیت خروج آخرین دستور اجرا شده ثابت می‌ماند و پرش از روی دستورات بعدی آن را تغییر نمی‌دهد.

همچنین تصور کنید اولین grep ناموفق است(کد وضعیت یک می‌شود) . Bash حالا && بعدی را می‌بیند، بنابراین به طور کلی دومین grep را نادیده می‌گیرد. بعد یک && دیگر می‌بیند، بنابراین از دستور rm که بعد از آن است نیز عبور می‌کند. عاقبت یک عملگر || می‌بیند. آها! وضعیت خروج ناموفق است، و ما یک عملگر || داریم، پس Bash دستور echo را اجرا می‌کند، و به ما می‌گوید که نمی‌تواند فایل را حذف کند ولواینکه هرگز اقدام به این عمل نکرده است! و این چیزی نیست که ما می‌خواهیم.

وقتی فقط پیغام خطای اشتباهی دریافت می‌کنید انعکاس خیلی بدی ندارد، اما اگر دقیق نباشید، سرانجام در کدهای خطرناک‌تر، این اتفاق خواهد افتاد. شما که نمی‌خواهید به طور تصادفی در اثر نارسایی منطق برنامه خود فایلی را حذف یا رونویسی نمایید!

نقص منطق ما در این واقعیت است که ما می‌خواهیم فرمان‌های rm و echo وابسته به یکدیگر باشند. دستور echo مربوط به rm می‌باشد، نه مربوط به grepها. بنابراین آنچه ما لازم داریم، گروه‌بندی آنها است. گروه‌بندی با استفاده از ابروها انجام می‌گردد:

    $ grep -q goodword "$file" && ! grep -q badword "$file" && { rm "$file" || echo "Couldn't delete: $file" >&2; }

(توجه: فراموش نکنید که قبل ازبستن ابرو یک سمی‌کالن یا سطر جدید لازم است!)

حالا دستورات rm و echo را با هم گروه‌بندی نموده‌ایم. این به طورمؤثر و کارامدی به معنای آنست که گروه به عنوان یک جمله در نظر گرفته می‌شود، نه چند دستور. برگردیم به موقعیتی که اولین دستور grep ما ناموفق بود، حالا BASH به جای اینکه به جمله ‎&& rm "$file"‎ رسیدگی کند، جمله ‎&& { ... }‎ را بررسی می‌کند. چون یک عملگر && مقدم بر این جمله است و آخرین دستور اجرا شده ناموفق بوده(دستور ناموفق grep)، از روی این گروه عبور کرده به پیش می‌رود.

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

    {
        read firstLine
        read secondLine
        while read otherLine; do
            something
        done
    } < file

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

یک مورد استفاده رایج دیگر از گروه‌بندی، مدیریت خطای ساده است:

    cd "$appdir" || { echo "Please create the appdir and try again" >&2; exit 1; }

ادامه دارد ....

عملگرهای کنترلی

ادامه یادداشت قبل



2. عملگرهای کنترلی (&& و ||)

حال که می‌دانیم کدهای خروج چیستند، و یک کد خروج صفر به معنای اجرای موفق یک دستور می‌باشد، استفاده از این اطلاعات را خواهیم آموخت. ساده‌ترین روش انجام یک عمل معین بر اساس موفقیت دستور قبلی از راه به کارگیری عملگرهای کنترلی می‌باشد. این عملگرها && و || می‌باشند، که به ترتیب یک AND و یک OR منطقی را نمایندگی می‌کنند. این عملگرها بین دو دستور به کار می‌روند، و برای کنترل آنکه آیا دستور دوم بر مبنای موفقیت دستور اول اجرا بشود، استفاده می‌شوند. این مفهوم اجرای شرطی نامیده می‌شود.

بیایید این مطلب را در عمل به کار ببریم:

$ mkdir d && cd d

این مثال ساده دو دستور دارد، mkdir d و cd  d. می‌توانستید از یک سمی‌کالن در آنجا برای جدا کردن دستورهاو اجرای ترتیبی آنها استفاده کنید، اما ما چیزی بیش از آن می‌خواهیم. در مثال فوق، BASH فرمان mkdir d را اجرا می‌کند، سپس && نتیجه برنامه mkdir پس از اتمامش را بررسی می‌کند. اگر برنامه mkdir موفق بود(کد خروج صفر)، بعد Bash دستور بعدی cd d را اجرا می‌کند. اگر mkdir d ناموفق باشد، و یک کد خروج غیر صفر برگرداند، Bash از اجرای دستور بعدی صرفنظر می‌کند، و در دایرکتوری جاری خواهد ماند.

مثالی دیگر:

$ rm /etc/some_file.conf || echo "I couldn't remove the file" rm: cannot remove `/etc/some_file.conf': No such file or directory I couldn't remove the file

|| خیلی مشابه && می‌باشد، امادقیقاً مخالف آن عمل می‌کند. فقط موقعی دستور بعدی اجرا می‌شود که دستور اول ناموفق شود. به این ترتیب، پیغام فقط در صورتی که فرمان rm ناموفق باشد، نمایش داده می‌شود.

به طور کلی، متصل کردن چند دستور کنترلی در یک جمله منفرد ایده خوبی نیست(ما این مطلب را در بخش بعدی باز خواهیم کرد). && و || در حالت‌های ساده کاملاً سودمند می‌باشند، اما در وضعیت‌های پیچیده اینطور نیست. در چند بخش بعدی برخی ابزارها که می‌توانید در تصمیم سازی به کار ببرید رانشان خواهیم داد.


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



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


ادامه دارد ....

شرط‌ها و بررسی

شرط‌ها و بررسی فصل پنجم راهنمای BashGuide


شرط‌ها و بررسی‌ها

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


1. وضعیت خروج

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

به عنوان مثال، دستور ping بسته‌های ICMP را در شبکه برای یک میزبان معین ارسال می‌کند. به طور معمول آن میزبان، با برگشت دادن دقیق همان بسته پاسخ می‌دهد. به این طریق می‌توانیم کنترل کنیم که آیا می‌توانیم یک ارتباط با میزبان راه دور برقرار کنیم. دستورping دامنه‌ای از کدهای خروج دارد که اگر مشکلی باشد، می‌تواند به ما بگوید، چه چیز نادرست است:

از مستندات ping لینوکس:

  • اگر ping هیچ بسته بازگشتی دریافت نکند، با کد 1 خارج خواهد شد. اگر یک شماره بسته و یک محدوده زمانی تعیین شده باشد، و شمارش بسته‌های دریافتی در زمان تعیین شده با عدد کمتری اعلام شود نیز با کد 1 خارج می‌شود. در سایر موارد خطا با کد 2 خارج می‌شود. در غیر اینصورت با کد صفر خارج می‌شود. و استفاده از کد خروج امکان آن را فراهم می‌کند که ببینیم میزبان فعال می‌باشد یا خیر.

پارامتر ویژه ? کد خروج آخرین پردازش پیش‌زمینه خاتمه یافته را به ما می‌دهد. اجازه دهید برای دیدن کدهای خروج فرمان ping مثال‌هایی بزنیم:

    $ ping God
    ping: unknown host God
    $ echo $?
    2
    $ ping -c 1 -W 1 1.1.1.1
    PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
    --- 1.1.1.1 ping statistics ---
    1 packets transmitted, 0 received, 100% packet loss, time 0ms
    $ echo $?
    1


  • تکرارمفید:
    همواره باید مطمئن شوید که اسکریپت شما در صورت وقوع رخداد ناخواسته در جریان اجرایش، کد خروج غیر صفر برمی‌گرداند. می‌توانید با استفاده از دستور داخلی exit این کار را عملی کنید:

         rm file || { echo 'Could not delete file!' >&2; exit 1; }



  • کد خروج / وضعیت خروج: هنگامی که یک دستور خاتمه می‌یابد به والدش( در موقعیت ما همیشه پوسته‌ای می‌شود که شروع کرده‌ایم) ، وضعیت خروج خود را گزارش می‌کند. این وضعیت با یک عدد از صفر تا ۲۵۵ نمایانده می‌شود. این کد اشاره‌ای به موفقیت اجرای دستور است.


ادامه دارد ....

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

ادامه یادداشت قبل


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

عبارت‌های منظم(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، را ملاحظه نمایید.




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


ادامه دارد ....

Glob Patterns

ادامه یادداشت قبل


الگوهای جانشین(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 ): یک جانشین رشته‌ایست که می‌تواند با نام فایلها یا رشته‌های معینی منطبق گردد.


ادامه دارد ....