مرجع سریع Bash - آموزش اسکریپت نویسی
X
تبلیغات
رایتل

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

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

#!/bin/bash

مرجع سریع Bash

BashSheet

مرجع یک برگی Bash ‏[1]

  • ترکیب دستوری

    • [کلمه]‎ ‎[فاصله]‎ ‎[کلمه]

      • فاصله‌ها کلمه‌ها را جدا می‌کنند. در bash، کلمه یک گروه از کاراکترهاست که به یکدیگر وابسته هستند. نمونه‌های آن نام فرمان‌ها و شناسه‌های فرمانها هستند. برای قرار دادن فاصله‌ها داخل یک شناسه(یا کلمه)، آن شناسه را با نقل‌قول منفرد یا دوگانه، نقل‌قولی کنید(نکته بعدی را ببینید) .

    • [سطر جدید][فرمان] ; [فرمان]

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

    • [فرمان] & [فرمان]

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

    • [command] | [command]

      • یک خط عمودی یا علامت لوله، خروجی یک فرمان را به ورودی فرمان بعدی متصل می‌کند. همه کاراکترهایی که توسط فرمان اول روانه stdout گردیده‌اند، توسط فرمان دوم در stdin قابل خواندن هستند.

    • [command] && [command]

      • یک AND شرطی باعث می‌شود فقط در صورتی که فرمان اول خاتمه یابد و به طور موفقیت‌آمیز خارج بشود، فرمان دوم اجرا گردد.

    • [command] || [command]

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

    • ' [رشته نقل‌قولی منفرد] '

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

    • " [رشته نقل‌قولی دوگانه] "

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

      • یادآوری: اهمیت دارد که همواره بسط‌های خود را(‎"$var"‎ یا ‎"$(command)"‎ را در نقل‌قولهای دوگانه بپوشانید. به این ترتیب، به طور ایمن معنای دستوری کاراکترهایی که ممکن است داخل نتیجه بسط قرار گیرند، غیرفعال می‌گردد.

    ساختارهای اساسی

    برای مثالهایی از ترکیب‌های دستوری پایین، بخش مثالهای ساختارهای اصلی را ببینید.

    دستورات مرکب

    دستورات مرکب جمله‌هایی هستند که می‌توانند چندین فرمان را اجرا کنند اما توسط Bash به عنوان یک نوع دستور گروهی در نظر گرفته می‌شوند.

    لیست‌های فرمان
    • { [لیست فرمانها] ;}‎

      • لیست فرمانها را در پوسته جاری همانطور که اگر یک دستور بود، اجرا می‌کند.

      • گروه‌بندی دستورات به خودی خود خیلی سودمند نمی‌باشد. اگر چه، در جایی که ترکیب دستوری Bash تنها یک دستور قبول می‌کند در حالیکه اجرای دستورات چندگانه مورد نیاز شما باشد، به کار می‌آید. به عنوان مثال، ممکن است بخواهید خروجی دستورات چندگانه را از طریق یک لوله به ورودی یک دستور دیگر عبور بدهید:
      • { cmd1; cmd2; } | cmd3

      • یا ممکن است بخواهید بعد از یک عملگر || دستورات چندگانه را اجرا نمایید:

      • rm file || { echo "Removal failed, aborting."; exit 1; }

      • برای بدنه توابع نیز مورد استفاده است. از نظر تکنیکی، می‌تواند برای بدنه حلقه‌ها نیز استفاده شود هرچند این مورد فاقد مستندات، غیرقابل حمل است و به طور معمول ما ‎do ...; done‎ را برای این مورد ترجیح می‌دهیم):

      • ‎‎for digit in 1 9 7; { echo "$digit"; }‎                غیرقابل حمل، مستندسازی نشده، فاقد پشتیبانی
      • for digit in 1 9 7; do echo "$digit"; done‎        ترجیحی
      • توجه: شما قبل از کلیدواژه ‎}‎ برای بستن لیست، یک کاراکتر ; لازم دارید( یا اینکه باید کلیدواژه در یک سطر جدید باشد.)

    • ( [لیست فرمانها] )

      • لیست فرمانها را در یک پوسته فرعی اجرا می‌کند.

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

      • توجه: قبل از بستن ‎)‎ به کاراکتر ; نیاز ندارید.

    عبارت‌ها
    • (( [عبارت محاسباتی] ))

      • عبارت داده شده را در یک زمینه حسابی ارزیابی می‌کند.

      • به معنای آن که، رشته‌ها به عنوان نام متغیرهای عدد صحیح در نظر گرفته می‌شوند، تمام عملگرها نیز به عنوان عملگرهای محاسباتی تلقی می‌گردند( از قبیل ‎++, ==, >, <=,‎ غیره). برای انجام بررسی‌ها بر روی اعداد، همیشه باید از این ترکیب استفاده نمایید!

    • ‎$‎(( [عبارت محاسباتی] ))

      • نتیجه عبارت داده شده را در یک زمینه محاسباتی بسط می‌دهد.

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

      • عبارت داده شده را به عنوان یک عبارت سازگار با test، ارزیابی می‌کند.

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

    حلقه ها

    اگر شما در مورد حلقه ها تازه وارد هستید یا خواهان جزئیات و تشریح بیشتر در باره آنها و یا مثالهای کاربرد آنها می‌باشید، بخش حلقه‌های شرطی از BashGuide را بخوانید.

    • do [لیست فرمانها]; done

      • این ترکیب، یک حلقه واقعی را شکل می‌دهد که توسط چند دستور بعدی استفاده می‌شود.
        لیست فرمانهای بین do و done دستوراتی هستند که در هر بار تکرار حلقه اجرا خواهند شد.

    • for [نام] in [کلمات]

      • حلقهِ بعد از آن، به ازای هریک از کلمات بعد از کلید واژه in اجرا خواهد شد.
        فرمانهای حلقه با مقداردهی متغیر معین شده در نام با هر یک از کلمات، اجرا خواهد شد.

    • for (( [عبارت حسابی]; [عبارت حسابی]; [عبارت حسابی] ))

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

    • while [لیست فرمانها]

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

    • until [لیست فرمانها]

      • حلقهِ بعد از آن، تا موقعی که آخرین فرمان اجرا شده در لیست فرمانها به طور ناموفق خارج می‌شود(شکست می‌خورد)، تکرار خواهد شد.

    • select [نام] in [کلمات]

      • حلقهِ بعد از آن، به طور دائم تکرار می‌شود و به کاربر اجازه می‌دهد یکی از کلمات داده شده را انتخاب نماید.

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

    داخلی‌ها

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

    موهومی ها
    • true (یا :)

    • این فرمانها به هیچ وجه کاری انجام نمی‌دهند.
      • آنها NOP(دستور بدون عملکرد) می‌باشند که همواره با موفقیت مراجعت می‌کنند.

    • false

    • همانند مورد فوق، به غیر از آنکه فرمان همیشه ناموفق است.
      • این دستور یک کد خروج 1 نشان دهنده شکست را برگشت می‌دهد.

    اعلانی
    • alias

    • یک مستعار Bash برقرار می‌کند، یا مستعار bash با نام داده شده را چاپ می‌کند.
      • مستعارها یک کلمه در ابتدای فرمان را بارشته دیگری تعویض می‌کنند. آنها فقط در پوسته‌های محاوره‌ای کار می‌کنند(نه در اسکریپت‌ها).
    • declare (یا typeset)

    • کمیتی را به یک متغیر تخصیص می‌دهند.
      • هر شناسه این دستور یک عبارت تخصیص متغیر جدید است. قسمت قبل از علامت مساوی در هر شناسه، نام متغیر است، و مقدار متغیر بعد از علامت می‌آید. گزینه‌های فرمان declar می‌توانند برای تعیین نوع متغیر(مانند ‎read-only=فقط خواندنی و export= سراسری و integer= عدد صحیح و array= آرایه‌ای‎) به کار بروند.

    • export

    • متغیر نامبرده را به محیط صادر می‌کند به طوری که پردازش‌های فرزند آن را ارث می‌برند.
      • این همانند دستور ‎declare -x‎ است. به خاطر داشته باشید که متغیر برای پردازش فرزند، همان متغیری که شما صادر نموده‌اید نیست. فقط همان داده را نگهداری می‌کند. این به معنای آن است که نمی‌توانید مقدار آن را تغییر داده و انتظار داشته باشید که در پردازش والد نیز تغییر کند.

    • local

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

    • type

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

    ورودی
    • read

    • یک سطر را می‌خواند(مگر اینکه گزینه ‎-d‎ برای تغییر جداکننده از سطرجدید به مورد دیگری، به کار رفته باشد)، و آن را در متغیرهایی قرار می‌دهد که با شناسه‌های فراهم شده برای read مشخص شده‌اند.
      • اگر بیش از یک نام متغیر ارائه شده باشد، سطر خوانده شده با استفاده از کاراکترهای داخل متغیر IFS به عنوان جداکننده‌ها، تجزیه می‌شود. اگر تعداد نامهای داده شده کمتر از تکه‌های جداگانه موجود در سطر باشد، آخرین متغیر تمام داده‌های باقیمانده تجزیه نشده را دریافت می‌کند.

    خروجی
    • echo

    • همه شناسه‌های داده شده به فرمان echo به صورت جداشده با یک فاصله، در یک سطر بیرون داده می‌شوند.
      • اولین شناسه‌ها می‌توانند گزینه‌هایی برای تبدیل وضعیت رفتار خاص باشند(مانند ‎-n‎ اخذ شده از کلمه ‎no newline‎ برای عدم درج سطرجدید در انتها و ‎-e‎ از جمله ‎escape sequences‎ برای ارزیابی رشته‌های eacape).

    • printf

    • اولین شناسه را به عنوان تعیین کننده چگونگی قالب سایر شناسه‌ها به کار می‌برد.
      • فرمان ‎help printf‎ را ببینید.

    • pwd

    • نام مسیر مطلق دایرکتوری کاری فعلی را در خروجی می‌نویسد.
      • می‌توانید برای آنکه pwd از هر لینک نمادین در نام مسیر اجتناب کند، از گزینه ‎-P‎ استفاده نمایید.

    اجرا
    • cd

    • دایرکتوری جاری را به مسیر ارائه شده تغییر می‌دهد.
      • اگر مسیر با علامت / شروع نگردد، نسبت به دایرکتوری جاری نسبی است.
    • command

    • اولین شناسه را به عنوان یک فرمان اجرا می‌کند.
      • این دستور به Bash می‌گوید از جستجو برای یک مستعار، تابع، یا کلمه کلیدی با آن نام چشم‌پوشی کند، و به جای آن فرض کند نام فرمان یک دستور داخلی یا یک برنامه در PATH می‌باشد.

    • . یا source

    • باعث می‌شود Bash فایل ارائه شده به عنوان اولین شناسه را بخواند و محتویات آن را در پوسته جاری اجرا کند.
      • این گونه‌ای مشابه include در سایر زبانها می‌باشد. اگر شناسه‌هایی بیش از نام فایل برای source فراهم شده باشد، آنها به عنوان پارامترهای مکانی در جریان اجرای آن کد منبع، تنظیم می‌شوند. اگر نام فایل برای منبع فاقد / باشد، PATH برای یافتن آن جستجو می‌شود.

    • exec

    • فرمان داده شده به عنوان اولین شناسه را اجرا می‌کند و پوسته جاری را با آن تعویض می‌کند.
      • سایر شناسه‌ها، به عنوان شناسه‌های فرمان عبور داده می‌شوند. اگرشناسه‌ای برای exec ارائه نگردیده است اما شما تغییر مسیرهایی برای فرمان exec تعیین کرده‌اید، تغییر مسیرها بر پوسته جاری اِعمال می‌شوند.

    • exit

    • به اجرای اسکریپت جاری خاتمه می‌دهد.
      • اگر یک شناسه فراهم شده باشد، آن شناسه وضعیت خروج اسکریپت جاری است(یک عدد صحیح بین صفر تا 255).
    • logout

    • اجرای پوسته login را خاتمه می‌دهد.
    • return

    • اجرای تابع جاری را خاتمه می‌دهد.
      • درست مانند دستور داخلی exit، ممکن است یک وضعیت خروج با آن تعیین گردد.

    • ulimit

    • محدودیت‌های منابع پردازش پوسته جاری را اصلاح می‌کند.
      • پردازش‌های فرزند از این محدودیت‌ها ارث می‌برند.

    ‏Jobها و پردازش‌ها‏
    • jobs:

    • jobهای فعال پوسته جاری را لیست می‌کند .
      مترجم: این کلمه تمام فعالیتهای شرکت کننده در تکمیل یک برنامه کامپیوتری از ابتدا تا انتها را شامل می‌شود و در حقیقت یک گروه پردازش با یک سرگروه پردازشی را job می‌نامند. این کلمه به روزهای گذشته‌ای باز می‌گردد، که کامپیوترهای شخصی حضور نداشتند و اشخاص برنامه‌های پانچ شده در کارت‌های پانچ را، برای اجرا به یک مرکز محاسبات دارای mainframe تحویل می‌دادند، که هر یک از این برنامه‌ها یک کار یا وظیفه (job) نامیده می‌شدند.
    • bg

    • job قبلی (یا job مشخص شده به وسیله شناسه داده شده) را برای اجرا به پس‌زمینه ارسال می‌کند.
      • در حالیکه job در حال اجرا است، پوسته به کارش ادامه می‌دهد. ورودی پوسته توسط خودش اداره می‌شود، نه توسط job.
    • fg

    • job قبلی (یا job مشخص شده توسط شناسه فراهم شده) را برای اجرا به پیش‌زمینه ارسال می‌کتد.
      • پوسته برای اتمام job منتظر می‌ماند و job می‌تواند ورودی را از پوسته دریافت کند.
    • kill

    • سیگنالی به یک پردازش یا job ارسال می‌کند.
      • شماره شناسایی پردازش(PID) یا jobspec(مشخصه job) آن job که می‌خواهید سیگنال به آن ارسال گردد را به عنوان شناسه به فرمان بدهید.

    • trap

    • یک سیگنال ارسال شده به پوسته جاری را مدیریت می‌کند.
      • کُدی که در اولین شناسه تعبیه شده است، هنگامی که یکی از سیگنال‌های مشخص شده در هر یک از شناسه‌های دیگرِ trap دریافت گردد، اجرا می‌شود.

    • suspend

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

    • wait

    • اجرای پوسته جاری را تا زمان پایان یافتن jobهای فعال، متوقف می‌کند.
      • در شناسه‌ها می‌توانید jobها (توسط jobspec) یا پردازش‌هایی(به وسیله PID) که باید برای پایان آنها منتظر بماند را مشخص نمایید.

    حلقه‌ها و شرط‌ها
    • break

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

    • continue

    • عبور از باقیمانده کُد در حلقه جاری و شروع یک تکرار جدید از آن حلقه.
      • درست مانند break، شاید یک عدد برای عبور از حلقه‌های بیشتر، به فرمان داده شود.

    شناسه‌های اسکریپت
    • set

    • فرمان set به طور معمول گزینه‌های مختلف پوسته را تنظیم(برقرار) می‌کند، اما پارامترهای مکانی را نیز تنظیم کند.
      • گزینه‌های پوسته آن گزینه‌هایی هستند که می‌توانند به پوسته عبور داده شوند، از قبیل ‎bash -x‎ یا ‎bash -e‎. فرمان set گزینه‌های پوسته را تغییر حالت می‌دهد، مانند این: ‎set -x‎، ‎set +x‎، ‎set -e‎، ... پارامترهای مکانی پارامترهایی هستند که شناسه‌های عبور داده شده به اسکریپت یا پوسته را نگهداری می‌کنند، از قبیل ‎bash myscript -foo /bar‎. فرمان set پارامترهای مکانی را هم تنظیم می‌کند، مانند این: ‎set -- -foo /bar‎.

    • shift

    • مقادیر تمام پارامترهای مکانی را یک پارامتر به عقب حرکت می‌دهد.
      • به این ترتیب، کمیتی که در ‎$1‎ قرار داشت، دور انداخته می‌شود،مقدار متغیر ‎$2‎ در ‎$1‎ قرار می‌گیرد، کمیت ‎$3‎ داخل ‎$2‎ می‌رود، و به همین ترتیب. می‌توانید یک عدد صحیح به عنوان شناسه برای shift تعیین نمایید که مشخص می‌کند این عمل shift چند مرتبه تکرار بشود.

    • getopts

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

        while getopts abc opt
        do
           case $opt in
              a) ...;;
              b) ...;;
              c) ...;;
           esac
        done

        به این طریق همه گزینه‌ها در شناسه‌ها تجزیه می‌شوند و وقتی آنها یکی از موارد ‎-a‏، ‎-b‎ یا ‎-c‎ باشند، کُد مربوطه در جمله case اجرا می‌شود. برای تعیین گزینه‌های چندتایی در شناسه‌هایی که به getopts داده می‌شود، این شیوه کوتاه نیز معتبر است: ‎-ac‎.

    جریان‌ها

    اگر شما برای کار با ورودی و خروجی در bash تازه وارد هستید یا در جستجوی مثالها، جزئیات و یا توضیحات بیشتر می‌باشید، سُراغ خواندن ورودی و خروجی از راهنمای Bash بروید.

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

    توصیف‌گرهای فایل

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

    • 0

    • ورودی استاندارد
      • این توصیف‌گر جایی است که پردازش‌ها به طور معمول اطلاعات را از آن می‌خوانند. به عنوان مثال، پردازش ممکن است نام شما را پرسش کند، پس از اینکه شما آن را تایپ کنید، اطلاعات در FD شماره 0 خواند می‌شود.
    • 1

    • خروجی استاندارد
      • جایی است که پردازشها به طور معمول تمام خروجی خود را در آن می‌نویسند. به عنوان نمونه، پردازش ممکن است شرح بدهد که چه می‌کند، یا نتیجه یک عملیات را بیرون بدهد.
    • 2

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

    تغییر مسیر

    • [command] > [file] و [command] [n]> [file] و [command] 2> [file]

      • تغییر مسیر فایل: عملگر ‎>خروجی استاندارد فرمان (یا ‎FD‎ شماره n) را به فایل نامبرده تغییر مسیر می‌دهد.

      • این به آن معنا می‌باشد که خروجی تولید شده توسط فرمان، در فایل نوشته خواهد شد.
      • به طور اختیاری می‌توانید عددی را جلوی عملگر ‎>‎ مشخص نمایید. اگر مشخص نکنید،عدد 1 پیش‌فرض می‌شود. عدد، نشان می‌دهد خروجی کدام توصیف‌گر فایلِ پردازش تغییر مسیر داده شود.

      • تذکر: فایل قبل از اینکه فرمان شروع بشود، خالی خواهد شد!
        مترجم: برای پی‌بُردن به اهمیت تذکر فوق، این کُد را امتحان کنید:  ‎ls /home/mydir>myfile‎  که در آن mydir نام یک دایرکتوری است که وجود ندارد و myfile نام فایلی است که در دایرکتوری جاری موجود و دارای متن، اما غیر لازم است. پس از اجرای فرمان، محتویات فایل را مشاهده نمایید، متوجه خواهید شد، درحالیکه دستور شما به علت عدم وجود دایرکتوری، اجرا نگردیده، اما محتویات قبلی فایل از بین رفته است.
    • [command] >> [file] و [command] [n]>> [file]

      • تغییر مسیر فایل: عملگر ‎>>خروجی استاندارد فرمان را به file، برای ضمیمه کردن به آن تغییر مسیر می‌دهد .

      • این به معنای آن است که تمام خروجی استاندارد تولید شده توسط فرمان به انتهای فایل افزوده خواهد شد.
      • توجه: فایل از سر کوتاه نمی‌شود. خروجی درست به انتهای آن اضافه می‌شود.
    • [command] < [file] و [command] [n]< [file]

      • تغییر مسیر فایل: عملگر ‎<فایل نامبرده را به ورودی استاندارد فرمان تغییر مسیر می‌دهد.

      • به طور اختیاری می‌توانید در جلوی عملگر ‎<‎ عددی را تعیین نمایید. اگر مشخص نکنید، عدد به پیش‌فرض 0 تنظیم می‌شود. این عدد، آن توصیف‌گر‌فایلِ پردازش، که تغییر مسیر به آن انجام می‌شود را نمایان می‌کند.

    • [command] &> [file]

      • تغییر مسیر فایل: عملگر ‎&>ورودی استاندارد فرمان و خطای استاندارد را به فایل نامبرده، تغیر مسیر می‌دهد.

      • این به آن معنی است که تمام خروجی استاندارد و خطاهای تولید شده توسط فرمان، در فایل نوشته خواهند شد.
    • [command] &>> [file] (Bash 4+)

      • تغییر مسیر فایل: عملگر ‎&>>خروجی استاندارد و خطای استاندارد را برای اضافه شدن به file، به آن تغییر مسیر می‌دهد.

      • به این معنی که تمام خروجی استاندارد و خطاهای تولید شده به وسیله فرمان، به انتهای فایل افزوده خواهند شد.
    • [command] <<< "[سطر داده]"

      • Here-String: یک رشته منفرد از داده‌ها را به ورودی استاندارد فرمان تغییر مسیر می‌دهد.

      • این روش خوبی برای ارسال یک سطر منفرد متن به ورودی یک فرمان است. توجه نمایید که، چون رشته نقل‌قولی شده است، می‌توانید به طور ایمن کاراکتر سطرجدید نیز در آن قرار بدهید و آن را به چند سطر از داده‌ها توسعه بدهید.
    • [command] <<[WORD]
      ‎[سطرهای داده‌ها]‎
      ‎[WORD]‎

      • Here-Document: سطرهای داده‌ها را به ورودی استاندارد فرمان تغییر مسیر می‌دهد.

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

      • توجه: شما می‌توانید کلمه پس از ‎<<‎ را 'نقل‌قولی' نمایید. اگر چنین کنید، هر موردی که در سطرهای داده‌ها مانند بسط‌ها باشد، توسط bash بسط نخواهد یافت.

    لوله‌کشی

    • [فرمان]| [فرمان دیگر]

      • لوله: عملگر | خروجی استاندارد فرمان اول را به ورودی استاندارد فرمان دوم متصل می‌کند.

      • در نتیجه، فرمان دوم داده‌هایش را از خروجی فرمان اول خواهد خواند.
    • ‎[فرمان]‎|& ‎[فرمان دیگر]‎ ‎(Bash 4+ فقط در)‎

      • لوله: عملگر ‎|&خروجی استاندارد و خطای استاندارد فرمان نخست را به ورودی استاندارد فرمان دوم متصل می‌کند.

      • در نتیجه، فرمان دوم داده‌هایش را از خروجی فرمان اول و مخلوط با خطاهای آن خواهد خواند.

    بسط‌ها

    • [command] "$( [command list] )", [command] "` [command list] `"

      • جایگزینی فرمان: خروجی فرمان را ضبط می‌کند و آنرا در جا بسط می‌دهد.

      • ما فقط موقعی از جایگزینی فرمان داخل فرمانهای دیگر استفاده می‌کنیم، که می‌خواهیم خروجی یک فرمان بخشی از یک دستور دیگر بشود. یک ترکیب جایگزین کهنه و نابخردانه برای جایگزینی فرمان، نقل‌قول-وارونه است: ‎`command`‎. این ترکیب همان نتیجه را دارد، اما پوشش مناسبی نیست و به آسانی هم با نقل‌قول‌ها اشتباه می‌شود‎( نقل‌قول-وارونه، هیچ ارتباطی به نقل‌قول کردن ندارد!). از این ترکیب اجتناب نمایید و موقعی که با آن مواجه می‌شوید، آن را با ترکیب ‎$(command)‎ تعویض کنید.

      • این مانند اجرای فرمان دوم، گرفتن خروجی آن، و درج آن خروجی در جایی که شما ‎$(...)‎ را گذاشته بودید، است.

    • ‎[command]‎<([command list])

      • جایگزینی پردازش: عملگر ‎<(...)‎ به یک فایل جدید تولید شده توسط bash که محتوی خروجی ‎command list‎ است، بسط می‌یابد.

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

      • توجه: این مورد را با تغییر مسیر فایل اشتباه نکنید. در اینجا ‎<‎ به معنی تغییر مسیر فایل نیست. این فقط یک علامت است که جزئی از عملگر ‎<(...)‎ می‌باشد! این عملگر هیچ تغییر مسیری انجام نمی‌دهد. این عملگر صِرفاً به مسیری به یک فایل بسط می‌یابد.

    • ‎[command]‎>([command list])

      • جایگزینی پردازش: عملگر ‎>(...)‎ به یک فایل جدید تولید شده توسط bashبسط می‌یابد، این فایل داده‌هایی که شما در آن می‌نویسید را به ورودی استاندارد فرمان دوم ارسال می‌کند.

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

    ترکیبات رایج

    • ‎[command]‎ <<([command list])

      • تغییر مسیر فایل و جایگزینی پردازش: قسمت ‎<(...)‎ با یک فایل تولید شده توسط bash تعویض می‌گردد، و عملگر ‎<‎ آن فایل جدید را می‌گیرد و به ورودی استاندارد فرمان تغییر مسیر می‌دهد.

      • این مورد تقریباً با لوله‌کشی فرمان دوم به فرمان اول یکسان است ‎(secondcommand | firstcommand)‎، اما فرمان اول آنطور که در یک لوله انجام می‌شود، در پوسته فرعی اجرا نمی‌شود. این ترکیب اکثراً موقعی که نیاز داریم فرمان اول محیط پوسته را ویرایش کند(که اگر فرمان در پوسته فرعی قرار گیرد، غیر ممکن می‌شود)، به کار می‌رود. برای مثال، خواندن در یک متغیر: ‎read var < <(grep foo file)‎. این کُد کار نمی‌کند: ‎grep foo file | read var‎، زیرا var فقط در پوسته فرعی کم دوام، تخصیص خواهد یافت، و به محض اینکه لوله انجام می‌شود، ناپدید خواهد شد.

      • توجه: فضای سفید میان عملگر ‎<‎ و عملگر ‎<(...)‎ را فراموش نکنید. اگر آن فاصله را فراموش کنید و آن را به ‎<<(...)‎ تبدیل نمایید، به خطا منجر خواهد گردید!

      • توجه: این ترکیب یک فایل موقت مختصِ اجرا (معمولاً یک FIFO) ایجاد می‌کند(و پاک می‌کند) که خروجی فرمان دوم را به اولی هدایت می‌کند.
    • ‎[command]‎<<< "$([command list])"

      • Here-String و جایگزینی فرمان: بخش ‎$(...)‎ با خروجی فرمان دوم تعویض می‌گردد، و عملگر ‎<<<‎ آن رشته را به ورودی استاندارد فرمان اول ارسال می‌کند.

      • این تقریباً همان فرمان فوق، با اثر جانبی کوچکی است که ‎$()‎ تمام سطرهای جدید دنباله را از خروجی حذف می‌کند و ‎<<<‎ یکی به انتهای آن اضافه می‌کند.

      • توجه: این ترکیب ابتدا تمام خروجی دستور دوم را با ذخیره در حافظه می‌خواند . موقعی که دستور دوم تکمیل گردید، فرمان اول با آن خروجی فراخوانی می‌شود. نسبت به مقدار خروجی، این ترکیب می‌تواند بیشتر مصرف کننده حافظه باشد.

    تست‌ها

    اگر در bash تازه وارد هستید، و کاملاً درک نمی‌کنید که فرمان‌ها و کُدهای خروج چه هستند یا خواهان برخی جزئیات، توضیح و یا مثالهای بررسی‌ها در آزمایش فرمانها، رشته‌ها یا فایلها می‌باشید، سراغ خواندن بخش بررسی‌ها و شرطی‌ها در راهنمای Bash بروید.

    کُدهای خروج

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

    بررسی کد خروج
    • if [command list]; then [command list]; elif [command list]; then [command list]; else [command list]; fi

      • فرمان if بررسی می‌کند که آیا آخرین فرمان از اولین لیست‌فرمان دارای یک کد خروج 0 بوده است.
        اگر چنین باشد، لیست‌فرمانی را که به دنبال کلمه then می‌آید اجرا می‌کند. اگر نه، elif بعدی به همان حالت امتحان می‌شود. اگر هیچ elif وجود نداشته باشد، لیست‌فرمان بعد از else اجرا می‌شود، مگر اینکه جمله else وجود نداشته باشد. به طور خلاصه، if یک لیست از فرمانها را اجرا می‌کند. کد خروج را بررسی می‌کند.در صورت موفقیت، فرمانهای then اجرا می‌شوند. elif و else بخشهای اختیاری هستند. قسمت fi به کل بلوک if خاتمه می‌دهد(آن را فراموش نکنید!).

    • while ‎[command list]‎ و ‎until [command list]‎

      • تکرار بعدی را بر اساس کد خروج آخرین فرمان از لیست‌فرمان اجرا می‌کند.
        اینها را قبلاً بحث کرده‌ایم، اما تکرار آنها در این بخش با ارزش است، چون در واقع آنها(while و until) همان کار دستورif را انجام می‌دهند، به استثنای آن که یک حلقه را تا وقتی که کد خروج بررسی شده به ترتیب 0 یا غیر-0 باشد، تکرار می‌کنند.

    الگوها

    Bash دو نوع از الگوها را می‌شناسد. الگوهای Glob مهمترین، پر استفاده‌ترین، و قابل خواندن‌ترین مورد هستند. نگارش‌های اخیر Bash از عبارتهای منظم "باب روز" نیز پشتیبانی می‌کنند. به هر حال، استفاده از عبارتهای منظم در اسکریپت‌ها غیرعاقلانه است، مگراینکه مطلقاً انتخاب دیگری نداشته باشید، یا آنکه مزایای کاربرد آنها به مراتب بیشتر از به کار بردن globها باشد. به طور کلی، اگر شما به عبارت منظم احتیاح دارید به جای Bash در حال استفاده از ‎awk(1)‎، ‎sed(1)‎، یا ‎grep(1)‎ خواهید بود.

    اگر در bash تازه وارد هستید یا برخی جزئیات، توضیحات و یا مثالهای از انطباق الگو را می‌خواهید، بخش الگوها در BashGuide را بخوانید.

    Glob ترکیب دستوری
    • ?

    • یک علامت سؤال بر هر کاراکتری منطبق می‌شود.
      • یعنی یک کاراکتر منفرد است.
    • *

    • ستاره با هر تعداد از همه کاراکترها مطابقت می‌کند.
      • یعنی هیچ یا بیشتر از هر چه کاراکتر هست.
    • [...]

    • با یکی از کاراکترهای داخل براکت‌ها مطابقت می‌کند.
      • به معنی یک کاراکتر ذکر شده در داخل کروشه‌ها است.
        • [abc]

        • با یکی از موارد a، یا b، یا c مطابقت می‌کند اما با رشته abc خیر.
        • [a-c]:

        • خط تیره به Bash می‌گوید از یک محدوده استفاده کند.
          • بر هر کاراکتر میان(مشمول) a تا c منطبق می‌گردد. بنابراین درست مانند مثال فوق است.

        • [!a-c]‎ یا ‎[^a-c]

        • کاراکتر ! یا ^ در ابتدا، به Bash می‌گوید انطباق را برعکس نماید.
          • بر هر کاراکتری که a، یا b یا c نیست، منطبق می‌شود. به معنی هر حرف دیگر، بلکه همچنین یک عدد، یک نقطه، کاما، یا هر کاراکتر دیگری که فکر کنید، می‌باشد.

        • [[:digit:]]: [:کلاس:]

        • این ترکیب به Bash می‌گوید از یک کلاس کاراکتر استفاده کند.
          • کلاس‌های کاراکتری، گروهی از کاراکترها هستند که برای راحتی پیش‌تعریف شده و نامگذاری شده‌اند. می‌توانید از کلاس‌های زیر استفاده کنید:

            alnum, alpha, ascii, blank, cntrl, digit, graph, lower, print, punct, space, upper, word, xdigit

    آزمایش
    • case [string] in [glob الگوی]) [command list];; [glob الگوی]) [command list];; esac

      • اگر می‌خواهید یک رشته معین را که می‌تواند با یکی از چند الگوی جانشین(glob) مختلف منطبق گردد بررسی نمایید، استفاده از case سودمند است.
        لیست فرمان(command list) که به دنبال اولین الگوی جانشین(الگوی glob) منطبق شده با string شما می‌آید، اجرا خواهد شد. شما می‌توانید هر تعداد گروهِ الگوی جانشین و لیست فرمان که لازم دارید، تعیین نمایید.

    • [[ [string] = "[string]" ]]‎ و ‎[[ [string] = [glob الگوی]]]‎، یا ‎[[ [string] =~ [عبارت منظم] ]]‎:

    • بررسی آنکه آیا STRING طرف چپ با STRING (اگر نقل‌قولی باشد)، GLOB (اگر نقل‌قولی نباشد و از = استفاده شده باشد) یا REGEX (اگر غیر نقل‌قولی باشد و از ‎=~‎ استفاده شود) سمت راست مطابقت می‌کند.
      [‎ و test فرمانهایی هستند که غالباً در اسکریپت‌های sh برای انجام دادن این بررسی‌ها می‌بینید. ‎[[‎ تمام این موارد را می‌تواند انجام بدهد(بلکه بهتر و مطمئن‌تر) وعلاوه براین انطباق الگو را برای شما فراهم می‌کند.

      از ‎[‎ یا test در کد bash استفاده نکنید. همواره به جای آن، ‎[[‎‎ را به کار ببرید. دارای سودمندی‌های بسیار و بی کم و کاست است.
      از ‎[[‎ برای انجام تست‌ها بر روی فرمانها یا عملیات عددی استفاده نکنید. برای اولی، از if و برای دومی از ‎‎((‎ استفاده کنید.
      [[‎یک گروه دیگر از تست‌ها را می‌تواند انجام بدهد، ازقبیل بررسی فایلها. ‎help test‎ را برای تمام انواع بررسی‌هایی که می‌تواند برایتان انجام بدهد، ببینید.

    • (( [عبارت محاسباتی] ))‎:

      • این کلمه‌کلیدی مخصوص انجام عملیات و بررسی‌های عددی است.
        عبارت محاسباتی را ببینید

    پارامترها

    آنچه Bash برای ذخیره داده‌های اسکریپت شما در آنها به کار می‌برد، پارامترها هستند. پارامترهای خاص و متغیرها وجود دارند.

    هر پارامتری که شما ایجاد می‌کنید، متغیر خواهند بود، چون پارامترهای خاص، پارامترهای فقطخواندنی هستند که توسط Bash مدیریت می‌شوند. یادآوری می‌شود، شما از نامهای با حروف کوچک برای پارامترهای خود استفاده کنید به طوری که آنها با نامهای تماماً با حروف بزرگ که توسط Bash برای متغیرهای داخلی و متغیرهای محیط به کار می‌برد، اشتباه نشوند. همچنین یادآوری می‌گردد، شما از نام‌های پاکیزه و شفاف برای متغیرهایتان استفاده کنید. از x، یا i، یا t، tmp، foo، وغیره اجتناب نمایید. در عوض، نام متغیری به کار ببرید که نوع داده‌ای را که انتظار می‌رود متغیر نگهداری کند وصف نماید.

    اهمیت دارد که شما ضرورت نقل‌قول کردن را درک نمایید. به بیان کلی، هر وقت شما یک پارامتر به کار می‌برید، باید آن را اینطور نقل‌قولی کنید: ‎echo "The file is in: $filePath"‎. اگر نکنید، bash محتویات پارامتر شما را به پاره‌هایی چاک می‌دهد، فضاهای سفید را از آن حذف می‌کند، و پاره‌ها را به عنوان شناسه به فرمان تغذیه می‌کند. بله، Bash به طور پیش فرض بسط های پارامتر شما را معیوب می‌کند - این کار تفکیک کلمه نامیده می‌شود - بنابراین برای پیش‌گیری از آن، نقل‌قول‌ها را به کار ببرید.
    کلیدواژه‌ها و تخصیص استثنا هستند. بعد از ‎myvar=‎ و داخل ‎[[‎، و case، و غیره، به نقل‌قول‌ها نیاز ندارید، اما زیانی هم نخواهند داشت - بنابراین اگر اطمینان ندارید: نقل‌قولی کنید!

    آخرین اما نه کوچکترین: به یاد داشته باشید که در bash پارامترها ساختارهای داده هستند. آنها داده‌های برنامه شما را نگاه می‌دارند. آنها نباید برای نگهداری منطق برنامه شما به کار بروند. بنابراین در حالیکه بسیاری اسکریپت‌های به تفصیل نوشته شده زیان‌آور، ممکن است مواردی مانند ‎GREP=/usr/bin/grep‎، یا ‎command='mplayer -vo x11 -ao alsa'‎ را به کار ببرند، شما نباید آن را انجام دهید. استدلال اصلی آن است که احتمالاً شما نمی‌توانید آن را به طور کاملاً صحیح و ایمن و قابل خواندن و نگهداری، انجام بدهید.
    اگر می‌خواهید از تایپ مجدد همان فرمان در چندین نوبت، پرهیز کنید، یا مدیریت سطرفرمان دستورتان را یک مرحله‌ای کنید، به جای آن از یک تابع استفاده کنید. نه از پارامترها.

    پارامترهای خاص

    اگر در استفاده از bash تازه وارد هستید یا خواهان تفصیل و توضیح، ویا مثالهایی از پارامترها می‌باشید به خواندن بخش پارامترهای خاص در راهنمای BashGuide بپردازید.

    • 1, 2, ...

    • پارامترهای مکانی شناسه‌هایی هستند که به اسکریپت یا تابع شما عبور داده شده‌اند.
      • موقعی که اسکریپت شما به صورت ‎./script foo bar اجرا گردد، ‎"$1"‎‎، می‌شود "foo" و ‎"$2"‎ نیز "bar" خواهد شد. یک اسکریپت اجرا شده به صورت ‎./script "foo bar" hubble‎ پارامتر ‎"$1"‎ را به ‎"foo bar"‎ و ‎"$2"‎ را به "hubble" بسط می‌دهد.

    • *

    • وقتی بسط داده می‌شود، معادل یک رشته منفرد است که تمام پارامترهای مکانی را با استفاده از اولین کاراکتر متغیر IFS(که به طور پیش فرض کاراکتر فاصله است) برای جداکردن آنها، به یکدیگر زنجیر می‌کند.
      • اجمالاً، ‎"$*"‎ همان ‎"$1x$2x$3x$4x..."‎ است که در آن x اولین کاراکتر محتوای متغیر IFS است.
        با یک IFS پیش فرض، آن عبارت، به صورت ‎"$1 $2 $3 $4 ..."‎ ساده خواهد شد.

    • @

    • این پارامتر به چندین شناسه بسط خواهد یافت: هر پارامتر مکانی موجود، به عنوان یک شناسه منفرد.
      • بنابراین اساساً، "$@" همانند ‎"$1" "$2" "$3" ...‎ است که همگی به طور جداگانه نقل‌قولی شده‌اند.
        توجه: شما همواره باید از ‎"$@"‎ بیشتر از ‎"$*"‎، استفاده کنید به علت آنکه ‎"$@"‎، واقعیت آنکه هر شناسه یک هویت جداگانه است را حفظ می‌کند. با ‎"$*"‎، شما این سوابق را از دست می‌دهید! ‎"$*"‎ در حقیقت تنها در صورتی سودمند است که شما بخواهید شناسه‌ها را با کاراکتری غیر از فاصله، به عنوان نمونه یک کاما، جدا کنید:
        (IFS=,; echo "You ran the script with the arguments: $*")‎ -- تمام شناسه‌های شما را به صورت جدا شده با کاراکترهای کاما بیرون می‌دهد.

    • #

    • این پارامتر به عددی که نشان دهنده تعداد پارامترهای مکانی موجود است، بسط می‌یابد.
      • در یک اسکریپت اجرا شده با ۵ شناسه، پارامتر ‎"$#"‎ به 5 بسط می‌یابد. معمولاً این پارامتر فقط برای بررسی آنکه آیا شناسه‌هایی برای اسکریپت فراهم شده است، سودمند است:
        if (( ! $# )); then echo "No arguments were passed." >&2; exit 1; fi

    • ?

    • به کد خروج فرمان قبلی تکمیل شده در پیش‌زمینه بسط می‌یابد.
      • ما از ‎$?‎ اکثراً موقعی استفاده می‌کنیم که بخواهیم کد خروج یک فرمان را در چند محل به کار ببریم، یا از آن برای بررسی در برابر چندین کمیت ممکن در یک جمله case استفاده کنیم.

    • -

    • پارامتر خط تیره به گزینه-پرچم هایی که در حال حاضر برای پردازش Bash تنظیم گردید‌اند، بسط می‌یابد.
      • برای یک توضیح در مورد اینکه گزینه-پرچم ها چیستند، کدام موجود می‌باشند، و چه معنی می‌دهند، set را ببینید.

    • $

    • پارامتر علامت دلار به ID پردازش فرایند Bash بسط می‌یابد.
      • اکثراً برای ایجاد یک فایل PID جهت پردازش bash شما قابل استفاده است ‎(echo "$$" > /var/run/foo.pid)‎، به این ترتیب، به عنوان مثال به آسانی می‌توانید آن را از پردازش bash دیگری خاتمه بدهید.

    • !

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

        foo ./bar & pid=$!; sleep 10; kill "$pid"; wait "$pid"

    • _

    • بسط کاراکتر خط زیر(underscore) آخرین شناسه آخرین فرمانی که اجرا کرده‌اید را به شما می‌دهد.
      • این یکی اکثراً در پوسته‌های محاوره‌ای جهت کمی کوتاه نمودن تایپ، به کار می‌رود:

        mkdir -p /foo/bar && mv myfile "$_"

    عملیات پارامتر

    اگر در استفاده از bash تازه وارد هستید یا خواهان تفصیل و توضیح، ویا مثالهایی از عملیات پارامتر می‌باشید به خواندن بخش بسط پارامتر راهنمای BashGuide و پرسش و پاسخ شماره73 بپردازید.

    • "$var" و "${var}"

      • به کمیت قرار گرفته در داخل پارامتر var بسط می‌یابد. ترکیب بسط پارامتر با محتویات متغیر تعویض می‌گردد.

    • "${var:-Default Expanded Value}"

      • به کمیت داخل پارامتر var یا اگر رشته var تهی باشد به ‎Default Expanded Value(کمیت پیش‌فرض بسط)‎ بسط می‌یابد . برای بسط به یک کمیت پیش‌فرض در حالتی که محتوای پارامتر تهی باشد (تنظیم نشده یا محتوی هیچ کاراکتری نباشد)، از این بسط استفاده کنید.

    • "${var:=Default Expanded And Assigned Value}"

      • به کمیت احاطه شده در داخل پارامتر var بسط می‌یابد، اما اگر پارامتر تهی باشد، ابتدا ‎قسمت «کمیت پیش‌فرض بسط و تخصیص»‎(Default Expanded And Assigned Value)‎ را به پارامتر تخصیص می‌دهد. این ترکیب دستوری غالباً با فرمان کولن ‎(:)‎ به کار می‌رود: ‎: "${name:=$USER}"‎، اما تخصیص عبارت منظم نیز با مورد فوق به خوبی کار می‌کند: ‎name="${name:-$USER}"‎.

    • "${var:?Error Message If Unset}", "${name:?Error: name is required.}"

      • به کمیت داخل پارامتر name بسط می‌یابد، یا اگر این پارامتر تهی باشد پیغام خطای بعد از ? را نمایش می‌دهد. اسکریپت(یا اگر در یک پوسته محاوره‌ای باشد، تابع) لغو می‌گردد.

    • ${name:+Replacement Value} و ${name:+--name "$name"}

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

    • "${line:5}" و "${line:5:10}" و "${line:offset:length}"

      • یک زیر رشته از کمیت نگهداری شده در داخل پارامتر line را بسط می‌دهد. زیر رشته از کاراکتر شماره 5 (یا عدد نگهداری شده در داخل پارامتر offset، در مثال سوم) شروع می‌شود و طولی برابر 10 کاراکتر(یا عدد نگهداری شده در داخل پارامتر length) دارد. offset از 0 شمارش می‌شود. اگر طول از قلم افتاده باشد، زیررشته تا انتهای کمیت پارامتر امتداد می‌یابد.

    • "${@:5}" و ‎"${@:2:4}" و "${array:start:count}"

      • عناصر یک آرایه را باشروع از یک شاخص start و تمام یا یک تعداد معلوم count از عناصر بسط می‌دهد. تمام عناصر به صورت شناسه‌های جداگانه بسط داده می‌شوند. اگر از @ به عنوان نام پارامتر استفاده نمایید، به علت وجود نقل‌قول‌ها عناصر از پارامترهای مکانی اخذ می‌شوند (در دومین نمونه، شناسه‌های اسکریپت شما عبارت می‌شوند از: ‎"$2" "$3" "$4" "$5"‎).

    • "${!var}"

      • کمیت پارامتر نامبرده در محتوای پارامتر var را بسط می‌دهد. این تکنیک نامناسبی است! این بسط، کد شما را در آینده بسیار غیرشفاف و غیرقابل پیش‌بینی، می‌سازد. احتمالاً شما به جای آن یک آرایه انجمنی لازم دارید.

    • "${#var}" و "${#myarray[@]}"

      • به طول کمیت داخل پارامتر var بسط می‌یابد. نمونه دوم به تعداد عناصر آرایه‌ای به نام myarray بسط می‌یابد.

    • "${var#A Prefix}" و "${PWD#*/}" و "${PWD##*/}"

      • به کمیت نگهداری شده در داخل پارامتر var پس از حذف رشته ‎A Prefix‎ از ابتدای آن، بسط می‌یابد. اگر کمیت شامل prefix(پیشوند) داده شده نباشد، به خود کمیت، بسط می‌یابد. پیشوند می‌تواند الگوی glob نیز باشد، که در آن حالت رشته‌ای که با الگو تطبیق نماید، ازابتدای کمیت حذف می‌شود. می‌توانید علامت # را برای حریص نمودن الگوی انطباق، دوتایی کنید.

    • "${var%A Suffix}" و "${PWD%/*}" و "${PWD%%/*}"

      • به کمیت نگهداری شده در داخل پارامتر var پس از حذف رشته ‎A Suffix‎ از انتهای آن، بسط می‌یابد. درست مانند عمل کوتاه سازی پیشوند، کار می‌کند، فقط از انتها جدا می‌کند.

    • "${var/pattern/replacement}" و "${HOME/$USER/bob}" و "${PATH//:/ }"

      • به کمیت نگهداری شده داخل پارامتر var پس از تعویض الگوی معین(pattern) با رشته جایگزین تعیین شده(replacment) بسط می‌یابد. الگو یک glob است که برای جستجوی رشته به منظور تعویض کمیت داخل var به کار می‌رود. اولین مورد تطابق، با رشته جایگزین تعویض می‌گردد. می‌توانید کاراکتر / نخست را برای تعویض تمام موارد انطباق، دوتایی کنید: نمونه سوم معادل محتوای PATH است که تمام کاراکترهای کولن در داخل آن با فاصله تعویض گردیده باشد.

    • ‎‎"${var^}" و "${var^^}" و "${var^^[ac]}"‎‎

      • کمیت نگهداری شده در پارامتر var را بعد از تبدیل تمام کاراکترهای منطبق با الگو به حروف بزرگ، بسط می‌دهد. الگو باید با یک کاراکتر منفرد مطابقت کند و اگر الگو از قلم افتاده باشد، الگوی ‎?‎ (هر کاراکتر منفرد) استفاده می‌شود. مثال اول، نخستین کاراکتر از کمیت var را به حرف بزرگ تبدیل می‌کند، نمونه دوم تمام کاراکترها راتبدیل می‌کند. نمونه سوم تمام کاراکترهای a یا c را به حرف بزرگ تبدیل می‌کند.

    • "${var,}" و "${var,,}" و "${var,,[AC]}"

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

    آرایه‌ها

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

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

    ایجاد آرایه‌ها
    • myarray=( foo bar quux )

      • یک آرایه به نام myarray که شامل سه عضو است ایجاد می‌کند. آرایه‌ها با استفاده از ترکیب ‎x=(y)‎ ایجاد می‌گردند وعناصر آرایه با فضای سفید از یکدیگر جدا می‌شوند.

    • myarray=( "foo bar" quux )

      • آرایه myarray را که شامل دو عضو است ایجاد می‌کند. به منظور قرار دادن عناصر دارای فضای سفید در یک آرایه، برای نشان دادن به bash که متن نقل‌قولی شده با هم متعلق به یک عضو آرایه است، اطراف آنها را با نقل‌قول ها بپوشانید.

    • myfiles=( *.txt )

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

    • myfiles+=( *.html )

      • تمام فایلهای HTML از دایرکتوری جاری را به آرایه myfiles اضافه می‌کند. ترکیب دستوری ‎x+=(y)‎ به همان روش تخصیص معمولی آرایه می‌تواند به کار برود، اما عناصر را به انتهای آرایه الحاق می‌کند.

    • names[5]="Big John" و names[n + 1]="Long John"

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

    • read -ra myarray

      • یک سطر را به فیلدها می‌شکند و فیلدها را در یک آرایه به نام myarray ذخیره می‌کند. فرمان read یک سطر را از stdin می‌خواند و از هر کاراکتر درون متغیر IFS به عنوان یک جداکننده برای تجزیه آن سطر به فیلدها، استفاده می‌کند.

    • IFS=, read -ra names <<< "John,Lucas,Smith,Yolanda"

      • یک سطر را با استفاده از , به عنوان جداکننده، به فیلدها می‌شکند و فیلدها را در آرایه‌ای به نام names ذخیره می‌کند. ما از عملگر ‎<<<‎ برای تغذیه یک رشته به stdin فرمان read استفاده می‌کنیم. تنظیم متغیر IFS برای مدت اجرای فرمان read به , باعث می‌شود، این فرمان سطر ورودی را به فیلدهای جدا شده با کاما تجزیه کند. هر فیلد به عنوان یک عضو در آرایه names ذخیره می‌گردد.

    • IFS=$'\n' read -d '' -ra lines

      • تمام سطرها را از stdin به داخل عناصر آرایه‌ای به نام lines می‌خواند. ما از گزینه ‎-d ''‎ فرمان read برای گفتن آن که بعد از خواندن سطر اول متوقف نشود استفاده می‌کنیم، که باعث خواندن تمام سطرها از stdin می‌گردد. آنوقت تنظیم متغیر IFS به کاراکتر سطر جدید موجب می‌شود فرمان read ورودی را از محل شروع سطر جدید به فیلدها جدا کند.

    • files=(); while IFS= read -d '' -r file; do files+=("$file"); done < < (find . -name '*.txt' -print0)

      • به طور مطمئن تمام فایلهای TXT محتوای دایرکتوری جاری را به صورت بازگشتی در آرایه‌ای به نام files می‌خواند.
        ما با ایجاد یک آرایه خالی به نام files آغاز می‌کنیم. سپس یک حلقه while را شروع می‌کنیم که یک دستور read برای خواندن یک نام فایل از stdin، اجرا می‌کند و سپس آن نام فایل (نگهداری شده در متغیر file) را به آرایه files می‌افزاید. برای دستور read متغیر IFS را به مقدار تهی تنظیم می‌کنیم که از رفتار read در زدودن فضای سفید جدا کننده سطرها از ورودی اجتناب گردد و ‎-d ''‎ راتنظیم می‌کنیم که به فرمان read بگوییم تا رسیدن به یک بایت NUL به خواندن ادامه بدهد ( نام فایل می‌تواند در چند سطر گسترده باشد، بنابراین ما نمی‌خواهیم با خواندن یک سطر، خواندن نام فایل را متوقف کنیم!). برای ورودی، فرمان find را به stdin فرمان while پیوست می‌کنیم. فرمان find از گزینه ‎ -print0‎ برای بیرون دادن نام‌های فایل با جدا کردن آنها توسط بایت‌های NUL استفاده می‌کند ( ‎-d ''‎ در فرمان read را ببینید). توجه: این تنها روش حقیقتاً مطمئن ایجاد یک آرایه از نام فایلها بواسطه خروجی یک فرمان است! شما باید نام فایلهای خود را با بایت‌های NUL جدا کنید، زیرا این تنها بایتی است که واقعاً نمی‌تواند داخل یک نام فایل ظاهر گردد! هرگز از ls برای بر شمردن نام فایلها استفاده نکنید! ابتدا استفاده از glob مثال فوق را امتحان کنید، آنها همانطور که مطمئن هستند(نیاز به یک فرمان خارجی نیست)، بسیار ساده‌تر و سریع‌تر می‌باشند.

    • declare -A homedirs=( ["Peter"]=~pete ["Johan"]=~jo ["Robert"]=~rob )

      • یک آرایه انجمنی با مسیردهی نامها به دایرکتوری خانگی کاربران، ایجاد می‌کند. بر خلاف آرایه‌های معمولی، شاخص‌های آرایه‌های انجمنی، رشته هستند(درست مانند مقادیر). توجه: شما هنگام ایجاد یک آرایه انجمنی برای اشاره کردن به bash که این شاخص‌ها رشته‌ای هستند نه اعداد صحیح، باید از ‎declare -A‎ استفاده نمایید.

    • homedirs["John"]=~john

      • یک عنصر را به آرایه انجمنی اضافه می‌کند، کلید "John" به دایرکتوری خانگی john مسیردهی شده است.

    کاربرد آرایه‌ها
    • echo "${names[5]}" و echo "${names[n + 1]}"

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

    • echo "${names[@]}"

      • هر عضو آرایه را به عنوان یک شناسه جداگانه بسط می‌دهد. برای بسط آرایه‌ها این روش ارجح است. هر عضو آرایه همان طور که اگر به عنوان یک شناسه جدیدِ نقل‌قولی شدهِ صحیح عبور داده می‌شد، بسط می‌یابد.

    • cp "${myfiles[@]}" /destinationdir/

      • تمام فایلهای مورد اشاره توسط نام فایلهای داخل آرایه myfiles را به ‎/destinationdir/‎(دایرکتوری مقصد)، کپی می‌کند. بسط یک آرایه با استفاده از ترکیب دستوری ‎"${array[@]}"‎ صورت می‌گیرد. این نمونه به طور کارآمدی آن ترکیب بسط را با لیستی از تمام عناصر نگهداری شده در آرایه، به صورت نقل‌قولی شدهِ صحیح، به عنوان شناسه‌های جداگانه، تعویض می‌کند.

    • rm "./${myfiles[@]}"

      • تمام فایلهای مورد اشاره به وسیله نام فایلهای داخل آرایه myfiles را حذف می‌کند. به طور کلی پیوست نمودن رشته‌ها به یک ترکیب بسط آرایه، ایده‌ای نامساعد است. آنچه رخ می‌دهد: رشته فقط به عضو اولِ بسط یافته از آرایه پیشوند می‌شود( یااگر شما رشته را به انتهای ترکیب بسط آرایه پیوست کرده باشید، به آخرین عضو، پسوند می‌گردد). اگر myfiles محتوی عناصر ‎-foo.txt‎ و ‎bar-.html‎ باشد، این فرمان به ‎rm "./-foo.txt" "bar-.html"‎ بسط خواهد یافت. توجه نمایید فقط عضو اول با ‎./‎ پیشوند می‌شود. در این نمونه خاص، این مطلب مفید است به علت اینکه اگر نام فایل نخست با یک خط تیره شروع بشود، فرمان rm ناموفق می‌گردد. اما اکنون با نقطه شروع می‌شود.

    • (IFS=,; echo "${names[*]}")

      • آرایه names را به یک رشته منفرد شامل تمام عناصر آرایه، به صورت ادغام شده و جداسازی با یک کاما ‎(,) بسط می‌دهد.‎ ترکیب ‎"${array[*]}"‎ خیلی به ندرت سودمند است. معمولاً موقعی که آن را در یک اسکریپت می‌بینید، یک باگ است. یک مورد استفاده آن، ادغام تمام عناصر یک آرایه به داخل یک رشته منفرد جهت نمایش برای کاربر است. توجه نمایید که ما دستور را در ‎(پرانتزها)‎ قرار دادیم، برای ایجاد پوسته فرعی: این پوسته فرعی، تخصیص IFS را در بر می‌گیرد، که پس از اتمام پوسته فرعی به حالت اول برگردانده می‌شود.

    • for file in "${myfiles[@]}"; do read -p "Delete $file? " && [[ $REPLY = y ]] &&  rm "$file"; done

      • تکرار روی تمام عناصر آرایه myfiles پس از بسط آنها به داخل جمله for انجام می‌شود. آنوقت برای هر فایل، از کاربر سؤال می کند که آیا می‌خواهد فایل را حذف کند.

    • for index in "${!myfiles[@]}"; do echo "File number $index  is ${myfiles[index]}"; done

      • تکرار روی تمام شاخص‌های آرایه myfiles پس از بسط آنها به درون جمله for انجام می‌شود. ترکیب ‎"${!array[@]}"‎ (به ! توجه کنید) به لیستی از شاخص‌های آرایه بسط می‌یابد، نه به محتوای آنها. کلیدهای آرایه‌های معمولی اعداد صحیح هستند و از 0 شروع می‌شوند. ترکیب دستوری برای به دست آوردن عنصر معینی در داخل آرایه، ‎"${array[index]}"‎ است، که در آن index کلید(شاخص) عضوی است که می‌خواهید به دست آورید.

    • names=(John Pete Robert); echo "${names[@]/#/Long }"

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

    • names=(John Pete Robert); echo "${names[@]:start:length}"; echo "${names[@]:1:2}"

      • به تعداد length عنصر آرایه را با شروع از شاخص start بسط می‌دهد. مشابه بسط ‎"${names[@]}"‎ اما بخشی از آرایه را بسط می‌دهد. اگر length از قلم افتاده باشد، مابقی عناصر آرایه بسط داده می‌شوند.

    • printf '%s\n' "${names[@]}"

      • هر عضو آرایه را در یک سطر جدید بیرون می‌دهد. این دستور printf تکنیک بسیار مفیدی برای بیرون دادن عناصر آرایه به یک روش متعارف است(در این مورد، پیوست کردن سطر جدید به هر یک). قالب دهنده رشته فراهم شده برای printf بر هر عضو اِعمال می‌گردد( البته، جز اینکه چند ‎%s‎ در آن ظاهر شود).

    • for name in "${!homedirs[@]}"; do echo "$name lives in ${homedirs[$name]}"; done

      • تکرار روی تمام عناصر آرایه homedirs بعد از بسط آنها به داخل جمله for، انجام می‌شود. ترکیب دستوری برای به دست آوردن کلیدهای آرایه‌های انجمنی همانند آن ترکیب برای آرایه‌های معمولی است. به جای اعداد با شروع از 0، اکنون کلیدهایی را به دست می‌آوریم که برای کمیت‌های آرایه انجمنی تعیین کرده‌ایم. بعداً می‌توانیم از این کلیدها برای مراجعه به کمیت‌های داخل آرایه استفاده کنیم، درست مانند آرایه‌های معمولی.

    • printf '%s\n' "${#names[@]}"

      • تعداد عناصر آرایه را بیرون می‌دهد. در این دستور printf، نتیجه بسط صرفنظر از تعداد عناصر آرایه، تنها یک شناسه خواهد بود. شناسه بسط یافته، یک عدد بیانگرِ تعداد عناصر آرایه names می‌باشد.

    مثالها: ساختارهای اصلی

    دستورات مرکب

    لیست‌های فرمان
    • [[ $1 ]] || { echo "You need to specify an argument!" >&2; exit 1; }

      • ما در اینجا یک فرمان گروهی به کار می‌بریم زیرا عملگر || فقط یک فرمان می‌پذیرد.
        ما می‌خواهیم هر دو فرمان echo و exit در صورت تهی بودن ‎$1‎ اجرا گردند.

    • (IFS=','; echo "The array contains these elements: ${array[*]}")

      • در اینجا از پرانتزها برای راه‌اندازی یک پوسته فرعی استفاده می‌کنیم.
        ما می‌خواهیم متغیر ‎IFS‎ را تنظیم کنیم، به این طریق IFS فقط در پوسته فرعی تغییر خواهد نمود نه در اسکریپت اصلی . این امر ما را از لزوم تنظیم مجدد آن به مقدار پیش فرض، بعد از بسط در دستور echo معاف می‌کند (که در غیر اینصورت مجبور می‌شدیم برای اجتناب از رفتار غیر منتظره بعدی، این کار را انجام بدهیم).

    • (cd "$1" && tar -cvjpf archive.tbz2 .)

      • در اینجا برای تغییر موقتی دایرکتوری کاری به آنچه در ‎$1‎ قرار دارد، از یک پوسته فرعی استفاده می‌کنیم.
        بعد از انجام عملیات tar (موقعی که پوسته فرعی به پایان می‌رسد)، به جایی که قبل از فرمان cd بودیم، باز می‌گردیم زیرا دایرکتوری کاری اسکریپت اصلی هرگز تغییر نمی‌کند.

    عبارت‌ها
    • ((completion = current * 100 / total))

      • توجه نمایید که زمینه محاسباتی، نسبت به دستورات عادی bash از قواعد تجزیه کاملاً متفاوتی پیروی می‌کند.

    • [[ $foo = /* ]] && echo "foo contains an absolute pathname."

      • می‌توانیم از کلیدواژه ‎[[‎ برای انجام تمام تست‌هایی که فرمان ‎test(1)‎ قادر به انجام است، استفاده کنیم.
        اما به طوری که در مثال نشان داده شده، این فرمان موارد بیشتری همچون مطابقت الگوی جانشین، انطباق عبارت منظم، تست گروهی و غیره را می‌تواند انجام بدهد.

    حلقه ها
    • for file in *.mp3; do openssl md5 "$file"; done > mysongs.md5

      • حلقه for روی تمام شناسه‌های بعد از کلمه کلیدی in تکرار می‌شود.
        هر شناسه به تنهایی در متغیری به نام file قرار گرفته و بدنه حلقه اجرا می‌شود.

        خروجی یک فرمان را کورکورانه به for عبور ندهید!
        for روی کلماتی از خروجی دستور تکرار خواهد شد، که تقریباً هرگز آنچه واقعاً می‌خواهید، نیست!

    • for file; do cp "$file" /backup/; done

      • این نگارش فشرده حلقه for با پارامترهای مکانی تکرار می‌شود.
        مورد فوق در اصل معادل ‎for file in "$@"‎ است.

    • for (( i = 0; i < 50; i++ )); do printf "%02d," "$i"; done

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

    • while read _ line; do echo "$line"; done < file

      • این حلقه while تا موقعی که فرمان read موفق است، ادامه می‌یابد.
        (یعنی،تا موقعی که سطرها می‌توانند از فایل خوانده شوند). اساساً این مثال، ستون اول داده‌های فایل را دور انداخته، بقیه را چاپ می‌کند.

    • until myserver; do echo "My Server crashed with exit code: $?;  restarting it in 2 seconds .."; sleep 2; done

      • این حلقه، هر دفعه که myserver با یک کد خروج عدم موفقیت خارج می‌شود آن را دوباره راه‌اندازی (restart) می‌کند.
        فرض می‌کند وقتی myserver با کد خروج ناموفق، خارج می‌شود، در اثر خرابی است و لازم است راه‌اندازی مجدد بشود، و اگر با یک کد خروج موفقیت خارج شود، شما فرمان خاموشی(shutdown) به آن داده‌اید و نباید مجدداً راه‌اندازی گردد.

    • select fruit in Apple Pear Grape Banana Strawberry; do  (( credit -= 2, health += 5 )); echo "You purchased some $fruit.  Enjoy!"; done

      • برنامه ساده‌ای که امتیازها را به تندرستی تبدیل می‌کند.
        سرگرمی.

    داخلی ها

    موهومی‌ها
    • while true; do ssh lhunath@lyndir.com; done

      • اتصال مجدد در صورت خرابی.

    اعلانی
    • alias l='ls -al'

      • یک مستعار به نام l می‌سازد که با ‎ls -al‎ جایگزین می‌گردد.
        مفید برای به سرعت دیدن محتویات دایرکتوری با جزئیات.

    • declare -i myNumber=5

      • تعریف یک متغیر صحیح myNumber با ارزش‌گذاری آن به مقدار 5.

    • export AUTOSSH_PORT=0

      • صادر کردن متغیری به نام AUTOSSH_PORT در محیط پردازش bash که به هر پردازش فراخوانی شده توسط این پردازش bash به ارث می‌رسد.

    • foo() { local bar=fooBar; echo "Inside foo(), bar is $bar"; }; echo "Setting  bar to 'normalBar'"; bar=normalBar; foo; echo "Outside foo(), bar is $bar"

      • یک تمرین در حوزه متغیر.

    • if ! type -P ssh >/dev/null; then echo "Please install OpenSSH." >&2; exit 1; fi

      • کنترل برای دیدن آن که ssh در دسترس است.
        در صورتیکه نیست، پیشنهاد نصب OpenSSH به کاربر و خروج.

    ورودی
    • read firstName lastName phoneNumber address

      • خواندن داده‌ها از یک سطر منفرد با چهار فیلد به درون چهار متغیر نامبرده.

    خروجی
    • echo "I really don't like $nick.  He can be such a prick."

      • بیرون دادن یک رشته ساده در خروجی استاندارد.

    • printf "I really don't like %s.  He can be such a prick." "$nick"

      • همان کار با استفاده از printf به جای echo، تفکیک متن و داده به طور مطلوب.

    اجرا
    • cd ~lhunath

      • تغییر دایرکتوری جاری به شاخه خانگی lhunath.

    • cd() { command cd "$@" && echo "$PWD"; }

      • داخل تابع، فرمان داخلی cd اجرا می‌گردد، نه تابع(که باعث بازگشت نا محدود خواهد شد) و اگر موفق شود، دایرکتوری کاری جدید را به خارج echo می‌کند.

    • source bashlib; source ./.foorc

      • تمام کدهای bash داخلِ فایلی به نام bashlib که در جایی از PATH وجود دارد را اجرا می‌کند، سپس همان کار را با فایل ‎.foorc‎ در دایرکتوری جاری انجام می‌دهد.

    • exec 2>/var/log/foo.log

      • از این پس تمام خروجی خطای استاندارد را به یک فایل ثبت رخداد ارسال می‌کند.

    • echo "Fatal error occurred!  Terminating!"; exit 1

      • یک پیغام خطا نمایش داده و از اسکریپت خارج می‌شود.


    CategoryShell

  • BashSheet (آخرین ویرایش ‎2013-09-13 18:33:07‎ توسط Lhunath)


    1. مترجم: برخی اشخاص، sheet را برگه تقلب ترجمه نموده‌اند، که به گمان من چندان مناسب نمی‌باشد. (بازگشت)