|
اینها پاسخهایی هستند به پرسشهایی که به طور مکرر درکانال #bash روی IRC شبکه freenode مطرح گردیدهاند. این پاسخها با همکاری اعضای ثابت کانال(originally heiner، و سپس دیگران شامل greycat و r00t)، و کاربرانی مانند شما، تنظیم شدهاند. اگر شما مورد غیردقیق یا واقعاً ناصحیحی یافتید، با خیال راحت آنرا اصلاح کنید!
تمام اطلاعات موجود در اینجا بدون ضمانت و تضمین صحت میباشد. با مسئولیت خودتان به کار ببرید. وقتی تردید دارید، لطفاً صفحات man یا info گنو را به عنوان منابع تصدیقشده، کاوش کنید.
BASH پوسته سازگار با BourneShell است، که ویژگیهای بسیاری به نیای خود افزوده است. اکثر آنها در KornShell، نیز معتبر هستند. جوابهای ارائه شده در این پرسش و پاسخها ممکن است به طرف Bash یا کوچکترین مخرج مشترک پوسته بورن گرایش داشته باشند، نسبت به آن که چه کسی آن پاسخ را نوشته باشد. در اکثر حالتها، کوششی برای ارائه هردو پاسخ، قابل حمل(بورن)، و کارآمد(Bash، در جای مقتضی) به عمل آمده است. اگر پرسشی به طور دقیق مخصوص پوسته نیست، اماتا اندازهای مربوط به یونیکس است، شاید پاسخ آن در UnixFaq باشد.
این پرسش و پاسخ سطح معینی از آشنایی با دستور زبان اسکریپتنویسی شل رافرض مینماید. اگر شما به طور کامل در Bash یا پوستههای خانواده Bourne تازهوارد میباشید، شاید مایل باشید با BashGuide شروع به یادگیری نمایید.
اگر نمیتوانید پاسخ پرسشی که در جستجوی آن هستید را در اینجا پیدا کنید، BashPitfalls را بررسی نمایید. اگر میخواهید کمک کنید، میتوانید به یک پرسش جدید در اینجا پاسخ بدهید، یاجوابگویی به یکی ازاینها( BashOpenQuestions) را امتحان کنید.
Bash FAQ رسمی Chet Ramey تکنیکهای بسیاری دارد که در اینجا پوشش داده نشدهاند.
استفاده از "for" را امتحان نکنید . از یک حلقه while و فرمان read استفاده کنید:
خوب، بستگی دارد به اینکه آیا میخواهید خروجی فرمان را ذخیره کنید(هر یک از stdout یا stdout + stderr) یا وضعیت خروج آن(0 تا 255، به طور نوعی در ازای 0 به معنی موفقیت).
راه حل اغوا کننده، استفاده از ls برای برونداد نام فایلهای ذخیره شده، و اخذ اولین نیتجه، میباشد. به طور عادی رویکرد ls نمیتواند مناسب باشد و هرگز نباید در اسکریپتها به خاطر احتمال برخورد با کارکترهای اختیاری(شامل سطر جدید) موجود در نام فایلها، به کار برود. بنابراین، به شیوههای دیگری برای سنجش فوق دادههای(metadata) فایل، نیاز داریم.
در Bash، میتوانید این کار را به طور مطمئن و به آسانی با گزینههای nullglob و dotglob (که رفتار globbing را تغییر میدهند) و یک آرایه انجام دهید:
این پاسخ فرض بر این دارد که شما در درجه اول، دارای درک اساسی از اینکه آرایهها چه میباشند، هستید. اگر شما در این نوع برنامهنویسی، تازه وارد هستید،شاید بهتر باشد با توضیح راهنما شروع نمایید. صفحه کامل و با جزئیات بیشتری است.
این یک صفحه مختلط میباشد، به علت آنکه موضوع آن پیچیده است. به طور کلی به سه بخش تقسیم شده است: آرایههای انجمنی، ارزیابی متغیرهای غیر مستقیم، و اختصاص متغیرهای غیر مستقیم. در سرتاسر آن مباحث موضوعات برنامهنویسی و مفاهیم پراکنده وجود دارد.
سریعترین روش، نیازی به برنامههای خارجی ندارد(اما در پوسته بورن قابل استفاده نمیباشد):
90% اوقات، تمام آنچه لازم دارید یکی از اینهاست:
اکثر فرمانهای استاندارد یونیکس وقتی به طور غیر محاورهای به کارمیروند، خروجی را در حافظه میانجی قرار میدهند. بدین معنی که بلافاصله، هر کاراکتر(یا حتی هر سطر) را نمینویسند، بلکه به جای آن، تعداد زیادی از کاراکترها (اغلب 4 کیلو بایت) را قبل از آنکه ابداً چیزی چاپ نمایند، جمعآوری میکنند. در حالت فوق، فرمان grep خروجیاش را میانگیری میکند، و بنابراین awk ورودیاش را فقط در قطعات بزرگ دریافت میکند.
با برنامه cpio :
یک روش زمخت(بلکه غیر سریع)این است:
در شل عملگری(صریح) برای الحاق نمودن رشتهها (لفظی یا بدون ارجاع به متغیر) وجود ندارد، فقط میتوانید آنها را در مجاورت هم بنویسید:
تغییر مسیر یک فرمان منفرد به همین آسانی است:
غالباً یک فرمان تعدادی فایل را به عنوان شناسه میپذیرد، به عنوان مثال
"Glob"ها الگوهای سادهای هستند که میتوانند برای مطابقت نام فایلها و رشتهها به کار بروند. به طور معمول آنها خیلی قدرتمند نمیباشند. اگر قدرت بیشتری لازم دارید، چند گزینه در دسترس است.
روش قابل حمل(POSIX یا Bourne) استفاده از چندین فرمانtest (یا [) است:
به طور معمول، چند روش برای حل مشکل موجود است، هریک با مزایا و معایب خاص خود.
برخی سیستمهای یونیکس برنامه سودمند split را برای این منظور فراهم میکنند:
اول و پیش از همه برای درک آنکه چرا مشکل دارید، مبحث شناسهها را بخوانید، تا خوب دریابید، پوسته جملاتی را که به آن میدهید چطور میفهمد. اگر میخواهید هر کاری با شل انجام بدهید، واجب است که شما درک خوبی از این موضوع کسب نمایید.
یک تعداد ابزار برای این مورد در دسترس است. که استفاده از هریک به عوامل زیادی بستگی دارد، مهمترین آنها البته آن است که چه چیزی را ویرایش میکنیم.
فقط یک فایل شروع اولیه(start-up) متفاوت تعیین کنید:
در اکثر پوستهها، هر یک از فرمانهای یک لوله در پوسته فرعی جداگانهای اجرا میگردد. نه در پوسته کاری:
به جای $10 از ${10} استفاده کنید. این در BASH و KornShell کار میکند، اما در پیادهسازیهای قدیمی BourneShell کار نمیکند. یک روش دیگر برای دستیابی به پارامترهای مکانی بعد از $9 استفاده از for است، به عنوان مثال, برای به دست آوردن آخرین پارامتر:
یک راهکاری برای تصادفی نمودن سطرها در اینجا هست. این روش تولید یک عدد تصادفی است که پیشوند هر سطر میشود ، سپس سطرهای حاصل، مرتب میگردند و اعداد حذف میشوند.
دو فرآیند نا مرتبط نمیتوانند از شناسهها، محیط یا stdin/stdout برای مراوده استفاده کنند، برخی اشکال ارتباط درون فرآیندی(IPC) لازم است.
این موضوع به طور مکرر طرح میشود. این پاسخ فقط عبارت به کار رفته فوق («فایلهای پیکربندی») را پوشش نمیدهد، بلکه چند حالت مختلف را شامل میشود. اگر شما به اینجا هدایت شدهاید، لطفاً قبل از ترک کردن آن، تمام پاسخ را بخوانید.
فرمان غیر استاندارد خارجی readlink(1) میتواند برای نمایش مقصد لینک نمادین استفاده شود:
برخی توزیعهای گنو-لینوکس دارای فرمان rename(1) هستند، که میتوانید برای این کار استفاده کنید، به هرحال نحوه ترکیب دستوری(syntax) آن از یک توزیع به دیگری تفاوت دارد، بنابراین پاسخ قابل حملی نیست....
[(فرمان test) و [[ (فرمان جدید test) برای ارزیابی عبارتها به کار میروند. [[ فقط در پوسته Bash و Korn کار میکند، و قدرتمندتر میباشد، [ و test در پوستههای POSIX معتبر هستند. چند مثال در اینجا هست:
کلمه کلیدی time در پوسته Bash نیرنگ خاصی را به کار میبرد، به طوری که میتوانید مواردی مانند این را انجام دهید
به طور معمول به پردازش با استفاده از شماره شناسایی پردازش(PID) رجوع میشود، و فرمان ps(1) میتواند اطلاعات هر پردازشی با شماره شناسایی ID داده شده را نمایش بدهد، به عنوان مثال
مطمئناً!
خوب، تا اندازه بسیاری بستگی به آن دارد که با آنها چه کار میخواهید انجام بدهید. چندین راهکار موجود است، ، هرکدام باضعف و قوتهای خود.
از فرمان comm(1) استفاده کنید:
با رشتههای escape کدهای ANSI در برنامه خود انجام ندهید! فرمان tput به شما اجازه میدهد به یک روش سالم با بانک اطلاعات ترمینال خود محاوره کنید:
در اینجا یک نمونه هست:
فرمان kill برای ارسال سیگنالها به پردازش در حال اجرا به کار میرود. به عنوان یک عمل راحت، سیگنال "0" که موجود نیست میتواند برای پی بردن به در حال اجرا بودن یک پردازش به کار برود:
در بسیاری از نگارشهای crontab، با علامت (%) به طور ویژهای رفتار میشود، و بنابراین باید با کاراکتر گریز \ پوشش داده شود:
آسانترین روش افزودن نوار پیشرفت به اسکریپت خودتان، استفاده از dialog --gauge است. در اینجا مثالی هست که متکی به ویژگیهای BASH میباشد:
برخی وسائل ممانعت دوجانبه لازم داریم. یک روش، استفاده از "lock" است: هر تعداد از پردازشها میتوانند به طور همزمان برای بدست آوردن قفل تلاش نمایند، اما فقط یکی از آنها موفق میشود.
اگر پرسش واقعی شما چطور میتوانم بررسی کنم که آیا یکی ازپارامترهایم -v است؟ میباشد، پس لطفاً FAQ #35 را ملاحظه کنید.در غیر اینصورت، خواندن را ادامه دهید....
یک لوله فقط میتواند خروجی استاندارد (stdout) برنامه را حمل کند. برای عبور دادن خروجی استاندارد خطا (stderr) از میان لوله، لازم است stderr را به همان مقصد stdout تغییر مسیر بدهید. به طور اختیاری برای دریافت stderr تنها، میتوانید stdout را ببندید یا به /dev/null تغییر مسیر بدهید. چند نمونه کُد:
فرمان eval برای سوءاستفاده به شدت قدرتمند و بینهایت آسان است.
tail -f رشد یک فایل ثبت وقایع را به شما نشان میدهد. در بعضی سیستمها(برای مثال OpenBSD)، این به طور خودکار تبدیل یک فایل لاگ به فایل جدیدی با همان نام را دنبال میکند(که به طور معمول همانست که شما میخواهید). برای حاصل نمودن همین توانایی در سیستمهای گنو به جای آن tail -F را به کار ببرید.
برخی اشخاص کوشش میکنند چیزی مانند این را انجام بدهند:
# مثالی که کار نمیکند args="-s 'The subject' $address" mail $args < $body
فقط سطرهای زیر را در فایل /etc/inputrc یا فایل ~/.inputrc خود اضافه کنید:
کاراکترهای رفتن سر سطر (CRs) در برخی سیستمها برای علامت زدن انتهای سطر به کار میروند. سه نوع مختلف انتهای سطر رایج است:
شما باید \[ and \] را در اطراف هر یک از رشتههای escape غیرقابل چاپ در اعلان خود قرار بدهید. از این قرار:
اول، شما باید معین کنید مفهوم شما از «عدد» چیست. در اکثر حالتهای رایج که مردم این مورد را سؤال میکنند، به نظر میرسد منظور «یک عدد صحیح غیر منفی، بدون علامت + » است. یا به بیان دیگر رشتهای از تمام ارقام. سایر اوقات، افراد میخواهند یک ورودی ممیز شناور با علامت و نقطه اعشار اختیاری را تعیین اعتبار نمایند.
تمام پردازشهای Bash به ترتیب از چپ به راست تغییر مسیر داده میشوند. و ترتیب معنا دار است. انحراف از آن در یک فرمان ممکن است نتایج آن فرمان را تغییر بدهد.
چون فرمان tar در اصل طوری طراحی شده بود که از دستگاههای نوار گردان مغناطیسی بخواند یا در آن بنویسد(کلمهtar از
چنان که شخصی بخواهد این را تبدیل کند:
به طور اساسی، پاسخ خیر است....
اول از همه -- و این با اهمیت است -- لطفاً این فرمان را اجرا نکنید . من در حقیقت ماشه پرسش فوق را از قلم انداختهام، و فقط آن بخش که تابع را تنظیم میکند، باقی گذاشتهام.
این را ملاحظه نمایید:
#!/bin/sh cd /tmp
در اینجا پیوندهایی به مستندات رسمی Bash آمده است:
پرسش شایسته. بعداً کامل میشود. (اشارات موقتی: tempfile قابل حمل نیست. mktemp به طور وسیعتری وجود دارد، اما برای ایجاد فایل از قبل، ممکن است مستلزم گزینه -c باشد، یا ممکن است به طور پیشفرض فایل را ایجاد کند و اگر -c فراهم شده باشد، آن را رها کند. برخی سیستمها هیچ یک از دو فرمان را ندارند(سولاریس و POSIX). ظاهراً فرمان منفردی که واقعاً در هر جایی کار کند وجود ندارد)
کُد زیر آنچه انتظار دارید را انجام نخواهد داد:
ssh me@remotehost 'sleep 120 &' # Client hangs for 120 seconds
شاید هیچ کس جواب را نداند( یا افرادی که میدانند مشغول هستند). شاید شما توضیح کافی در باره مشکل ندادهاید، یا شما مشکل را به طور شفاف بیان نکردهاید. شاید سؤالی که پرسیدهاید در این FAQ پاسخ داده شده است، یا در تلههای Bash، یا در راهنمای BashGuide.
کُد زیر را برای انتظار تا فشردن کلید اینتر توسط کاربر به کار ببرید:
چاره کار استفاده از case میباشد:
برای انجام این کار چند راه وجود دارد. بعضی ترفندهای خاصی را در بر میگیرند که فقط با فضای سفید کار میکنند. برخی دیگر بیشتر عمومیت دارند، و میتوانند برای جدا کردن صفرها به کار بروند، و غیره.
نحست بررسی کنید آیا به فرمانی که اجرا میکنید به طور مستقیم میتواند گفته شود، زمان مورد نظر به پایان رسید. روشهای تشریح شده در اینجا فرافکنی hack مانندی برای مجبور نمودن دستور، به خاتمه یافتن پس از سپری شدن یک زمان معین میباشند. پیکربندی فرمان شما به طور صحیح، همواره نسبت به جایگزینهای ذیل ارجحیت دارد.
ایست!
تنها روش سالم مدیریت مقادیر زمان در داخل یک برنامه، تبدیل آنها به مقیاس خطی است. شما نمیتوانید"January 17, 2005 at 5:37 PM" را در متغیر ذخیره کنید و انتظار انجام کاری را با آن داشته باشید....
اگر شما یک مقدار معین هگزادسیمال یا اُکتال دارید(در زمان نوشتن اسکریپت)، دقیقاً میتوانید printf را به کار ببرید:
اگر یک پوسته یا اسکریپت شل، فراخواننده دستورات پوسته، به طور محاورهای به خوبی اجرا شود، اماموقعی که به طور غیر محاورهای اجرا میشود در اثر پیکربندی محیط شکست بخورد(به فرض: یک $PATH پیچیده)، لزوماً نیاز خواهید داشت که محیط شما به طور صحیح پیکربندی بشود.
برای آموزش دستکاری رشته FAQ شماره 100 را ببینید، این صفحه مقداری از همان اطلاعات را شامل میشود، اما به شکلی فشردهتر.
اکثر بسط پارامترهای توسعه یافته، در پوسته قدیمیتر BourneShell کار نمیکنند. اگر لازم است کُد شما به خوبی قابل حمل به آن شل باشد، اغلب sed و expr میتوانند استفاده شوند.
بخش کاربرد Find را ملاحظه کنید.
این سؤال و تمام پرسشهای مشابه آن با یک AWK یک سطری پاسخ داده میشوند.
اگر شما یک کاربر پوسته هستید که میخواهد فعالیتهای خود را ضبط نماید، FAQ #88 را ملاحظه کنید. اگر شما یک مدیر سیستم میباشید که میخواهد بداند چطور میتواندکشف کند، یک کاربر موقعی که تاریخچه پوستهاش را به /dev/null فرستاده یا آن را غیر فعال نموده، چه چیز اجرا کرده است، چند مشکل برای این مورد وجود دارد....
خوب، اول از همه، من میدانم ممکن است افردای نیز هم اکنون درحال خواندن این مطلب باشند که حتی پرسش را متوجه نشدهاند. اینجا، این کار نمیکند:
{ echo oldpass; echo newpass; echo newpass; } | passwd # !این کار نمیکند
این در واقع سه پرسش مختلف است، بنابراین ما پاسخ را به سه قسمت تفکیک کردهایم.
نمی توانید. مستعارها در bash بینهایت ابتدایی هستند، و در حقیقت برای هیچ مقصود جدی مناسب نمیباشند. حتی صفحه مستندات bash به طور صریح میگوید:
POSIX فرمان داخلی به نام command تعیین میکند، که میتواند برای این منظور به کار برود:
به چند دلیل:
چند روش برای تعیین آنکه آیا متغیر تعریف شدهای مقدار غیر تهی دارد، موجود است. اینجا رایجترین آنها، به ترتیب از بیشترین تا کمترین قابلیت حمل آمده است:
توابع در Bash (همچنین سایر پوستههای هم خانواده شل Bourne) مانند فرمانها کار میکنند: یعنی، آنها فقط یک وضعیت خروج برمیگردانند، که منحصر به اعداد صحیح از 0 تا 255 است. این به منظور استفاده در علامتدهی خطاها میباشد، نه برای بازگرداندن نتایج محاسبات یا سایر دادهها.
در یک حالت کلی، یک توصیفگرفایل (FD) جدید باز میکنید که به fifo اشاره کند، و از طریق آن مینویسید. برای موقعیتهای ساده، شاید پرش از این مرحله امکان پذیر باشد.
گاهی اوقات صرف نظر کردن از مستعارها (و توابع، از جمله توایع داخلی پوسته) سودمند است. به عنوان مثال، شاید در سیستم خود این تنظیم را داشته باشید:
تعدادی روش اختیاری وجود دارد، اکثر آنهااختصاصی سیستم هستند. همچنین دقیقاً بستگی به آن دارند که چرا اطلاعات را میخواهید، در اکثر حالتها، روشهای دیگری برای انجام هدف واقعی شما وجود دارد. اگر یک روش امکان پذیر برای اجتناب از انجام آن موجود باشد، شما نمیخواهید خروجی ls را تفکیک نمایید .
این روش برای آن طراحی شده تا به شما امکان بدهدثبت وقایع دوستانه کاملی از تمام فرمانهای اجرا شده توسط کاربر را ذخیره کنید، مقصود از آن حسابرسی امن فرمانها نمیباشد -بخش امنیت bash در برابر پاکسازی تاریخچه را ببینید.
موقع خواندن سطر به سطر فایل، اگر یک دستور در داخل حلقه نیز stdin را بخواند، میتواند فایل ورودی را تمام کند، برای مثال:
نمیتوانید آنرا به تنهایی با تغییر مسیر bash انجام دهید، برعکس>> وجود ندارد....
در شلهای محاورهای COLUMNS و LINES فقط توسط BASH تنظیم میشوند، آنها در اسکریپت عمل نمیکنند. به جای آن میتوانید از اینها استفاده کنید:
همواره شرایطی ماورای کنترل ما وجود دارد، که ما را به سمت انجام مواردی میراند، که اگر به عهده خودمان بود هرگز انجام آنها را انتخاب نمیکردیم. این مدخل FAQ یکی از آن موقعیتها را تشریح میکند.
اگر ترمینالی دارید که رشتههای escape سازگار با xterm را میفهمد، و شما دقیقاً میخواهید یکباره عنوان آن را تنظیم کنید، میتوانید از چنین تابعی استفاده کنید:
متأسفانه، تجزیه خروجی فرمان df واقعاً معتبرترین روش تعیین پر شدن کامل دیسک در اکثر سیستمعاملها میباشد. به هر حال، لطفاً توجه نمایید که این کم ضررترین پاسخ است، نه بهترین جواب. تجزیه خروجی هر ابزار گزارش خط فرمانی هرگز آراسته نمیباشد. مقصود از این FAQ کوششی است برای تشریح تمام مشکلات شناخته شده رویارویی با این موارد، و عبور موقت از آنها.
ابتدا، بیایید برخی موضوعات زمینهای را بازبینی کنیم. موقعی که یک پردازش میخواهد پردازش دیگری را اجرا کند، یک فرزند fork()(منشعب) میکند، و پردازش فرزند یکی از فراخوانهای سیستمی خانواده exec* (مانندexecve())، را با دادن نام یا مسیر فایل برنامه پردازش جدید، نام پردازش جدید، لیست شناسهها برای پردازش جدید، و در بعضی حالتها، مجموعهای از متغیرهای محیط، فراخوانی میکند. از این قرار:
ssh رفتار فرمان راه دور(rsh یا remsh)یونیکس، شامل این باگ، را شبیهسازی میکند. چند روش برای عبور موقت موجود است، و به طور دقیق وابسته آنست که شما چه چیز لازم دارید.
مستندات در این مورد مبهم است، اما میتوانید به نوعی با دستورات داخلی پوسته آن را انجام دهید:
جستجوی مثالهای چگونگی افزایش محلیسازی ساده اسکریپتهای bash، وچگونکی بررسی آن؟ احتمالاً آنچه شما میخواهید این است....
پاسخ ls -t | head -1 که فوراً به ذهن میرسد، اشتباه است، به علت آنکه تجزیه خروجی ls نا امن است، در عوض، باید حلقهای ایجاد نموده و نشانههای زمان را مقایسه کنید:
Bash میتواند عملیات با رشتهها را انجام دهد. عملیات رشتهای فراوان. این یک مقدمه برای دستکاریهای رشته در bash و شگردهای مربوطه میباشد. با پرسشهای بسط پارامتر همپوشانی دارد، اما اطلاعاتی که در اینجا ارائه شده است، یک حالت مبتدی پسندتری دارد(امیدواریم).
(اگر شما در جستجوی گزینه پردازش بودهاید، پرسش BashFAQ/035 را ملاحظه کنید.) در مورد توابع ذیل بارها در #bash سؤال شده است، بنابراین امیدواریم آنها برایتان مفید باشد.
بهترین کار آنست که در سراسر کُد خود با نشانههای زمان (timestamps) کار کنید، و سپس برای خروجی، این نشانهها را به شکل قابل خواندن انسانی تبدیل نمایید. اگر شما با ورودی قابل خواندن انسانی سر و کار دارید، پس به چیزی که بتواند آنها را تجزیه کند نیاز دارید.
انجام محاسبات مبتنی بر تاریخ در Bash دشوار است، زیرا Bash ساختار داخلی برای محاسبه با تاریخ یا دریافت فوق دادههایی مانند زمان ویرایش فایلها ندارد.
این تله است، و باید به ترتیب دقیقی توجه شود که، تفکیک کنندهBash هر مرحله را انجام میدهد.
دستور set -e کوششی برای افزودن تشخیص خطای خودکار به پوسته بود. هدف آن بود که موجب گردد هرگاه هر خطایی رخ داد، پوسته لغو بشود، بنابراین شما نباید || exit 1 را بعد از هر دستور مهم قرار بدهید.
این مورد نیازمند برخی دستکاریهای مهارتآمیز توصیفگرفایل ، و یکی از لوله دارای نام یا جایگزینی پردازش پوسته Bash میباشد. ما میخواهیم بر ترکیب دستوری Bashتمرکز نماییم.
روشهای بیشماری برای انجام این کار هست، اما تمام آنها یا به ابزارهای در دسترس محدود میشوند، یا کند هستند. ما چند نمونه را نشان خواهیم داد.
برای انجام این کار روشهای بیشماری موجود است، اما تمام آنها محدود به ابزارهای در دسترس هستند. من به چاره کارهای زیر رسیدم .
به طور معمول موقعی که اشخاص این پرسش را مطرح میکنند، به دلیل آنست که میخواهند خطاهای کاربر را تشخیص داده و پیغام مناسبی برای آن تهیه کنند. یک نظریهای هست که میگوید نباید کاربر یونیکس را به این طریق نازپرورده نمود، و اگر کاربری حقیقتاً بخواهد در عوض منبع کردن اسکریپت شما، آن را اجرا کند،شما نباید برای این کار او را نکوهش کنید. حال از این که بگذریم، ما میتوانیم پرسش را به نحو دیگری که در واقع باید پرسیده شود، بیان کنیم:
Bashهیچ روش درونی برای استفاده از قالب ها( templates) ندارد.
پرسش و پاسخهای Bash (آخرین ویرایش 2010-10-26 16:22:21 توسط GreyCat)