لوله، هدایت خروجی و نقلقول در Bash
در این درس ۵ بخش
فرض کنید مسئول بررسی گزارش روزانهٔ یک برنامه هستید. فایل کامل چهار خط دارد، اما همکار شما فقط هشدارهای شبکه را میخواهد. میتوانید متن را دستی کپی کنید؛ راه تکرارپذیرتر این است که چند فرمان کوچک را به هم وصل کنید و نتیجه را در فایل جداگانه نگه دارید. در پایان این درس میتوانید مسیر حرکت متن را پیشبینی کنید، خروجی را ذخیره کنید و نام فایلهای دارای فاصله را درست بنویسید. مثالها مخصوص Bash در Debian یا Ubuntu هستند. این آزمایش به دسترسی مدیر نیاز ندارد و فقط فایلهای تازهٔ پوشهٔ تمرینی شما را تغییر میدهد.
یک گزارش کوچک و قابل پیشبینی بسازید
در همان پنجرهٔ ترمینال، کادر زیر را خطبهخط اجرا کنید. mktemp پوشهای تازه با پسوند تصادفی در خانهٔ شما میسازد؛ بنابراین آزمایشهای قبلی با این تمرین قاطی نمیشوند. متغیر lab7 مسیر همان پوشه را نگه میدارد. اگر ساخت پوشه یا ورود به آن خطا داد، ادامه ندهید. در خط اول، دو سوی علامت مساوی فاصله نگذارید. نامهای انگلیسی و دادههای کوتاه این مثال عمداً ثابتاند تا بتوانید نتیجهٔ خود را با نتیجهٔ درس مقایسه کنید.
lab7=$(mktemp -d "$HOME/darsavand-flow.XXXXXX")
cd -- "$lab7"
printf '%s\n' 'info breakfast' 'warn disk' 'info backup' 'warn network' > events.txt
printf '%s\n' 'draft' > "daily notes.txt"در حالت موفق چیزی روی صفحه ظاهر نمیشود. این سکوت به معنای ساختهنشدن فایل نیست: علامت > خروجی printf را داخل فایل فرستاده است. قالب %s متن هر آرگومان را مینویسد و \n پس از آن خط تازه میسازد. events.txt اکنون چهار خط دارد؛ daily notes.txt یک خط با متن draft دارد. در نام دوم، فاصله بخشی از نام است و نقلقول دوتایی کمک میکند Bash کل آن را یک آرگومان ببیند.
لوله متن را عبور میدهد؛ هدایت خروجی آن را نگه میدارد
بیشتر فرمانهای متنی ورودی استاندارد میخوانند و نتیجه را روی خروجی استاندارد مینویسند؛ معمولاً این دو به صفحهکلید و ترمینال متصلاند. با | خروجی استاندارد فرمان چپ، ورودی استاندارد فرمان راست میشود. در مثال اول، grep دو خط دارای warn را انتخاب میکند و wc تعداد خطهای همان نتیجه را میشمارد. لوله اسم فایل را جابهجا نمیکند؛ متن را عبور میدهد. خط دوم همان انتخاب را ذخیره میکند. > فایل را ایجاد میکند یا محتوای موجودش را از ابتدا جایگزین میکند؛ >> متن را به انتهای فایل اضافه میکند. پیش از نوشتن > همیشه نام مقصد را دوباره بخوانید.
grep 'warn' events.txt | wc -l
grep 'warn' events.txt > warnings.txt
wc -l < warnings.txt
printf '%s\n' 'review complete' >> warnings.txt
cat -- warnings.txtدو شمارش باید عدد 2 نشان دهند؛ فاصلهٔ کنار عدد ممکن است متفاوت باشد. خروجی نهایی cat سه خط است: warn disk، سپس warn network و سپس review complete. در فرمان wc، علامت < محتوای فایل را به ورودی استاندارد میدهد. فرمانهایی که خروجی را هدایت میکنند پیام موفقیت چاپ نمیکنند. پیام خطا مسیر جداگانهای به نام خطای استاندارد دارد و در این مثال با > به فایل گزارش منتقل نمیشود. هرگز فایل ورودی و مقصد را یکسان نگذارید؛ مثلاً هدایت نتیجه به خود events.txt میتواند آن را پیش از خواندن خالی کند.
نقلقول و ستاره را با قصد روشن به کار ببرید
Bash پیش از اجرای فرمان، خط را تفسیر میکند. نقلقول تکی متن داخل خود را عیناً حفظ میکند؛ نقلقول دوتایی فاصله را حفظ میکند ولی جایگزینی متغیری مثل $topic را اجازه میدهد. برای مسیر متغیرها معمولاً شکل "$lab7" انتخاب مناسبی است. فاصلهٔ بدون نقلقول میتواند آرگومانها را جدا کند؛ حروف بزرگ و کوچک نیز در این محیط یکسان نیستند. برای نمونه events.txt با Events.txt تفاوت دارد. ستارهٔ بدون نقلقول در *.txt الگویی برای نام فایلهاست، نه جستوجوی متن داخل آنها. ابتدا نتیجهٔ الگو را با printf ببینید؛ انتخاب گروهی را با حدس انجام ندهید.
topic='Linux basics'
printf '%s\n' "$topic" '$topic'
cat -- "daily notes.txt"
printf '<%s>\n' *.txt
printf '%s\n' '*.txt'دو خط نخست خروجی Linux basics و خودِ $topic هستند. cat کلمهٔ draft را نشان میدهد. پیشنمایش الگو سه نام daily notes.txt، events.txt و warnings.txt را، هرکدام داخل نشانههای زاویهدار، چاپ میکند؛ ترتیب را ملاک اصلی نگیرید. فرمان آخر فقط .txt را چاپ میکند، چون ستاره داخل نقلقول ویژه نیست. در تنظیم معمول Bash، الگوی بدون تطبیق ممکن است عیناً باقی بماند و نامهای آغازشده با نقطه نیز معمولاً با انتخاب نمیشوند. بنابراین پیشنمایش واقعی از حفظکردن یک قاعدهٔ ناقص مفیدتر است.
تمرین: یک گزارش قابل تحویل بسازید
بدون تغییر events.txt، ابتدا خطهای دارای warn را انتخاب کنید؛ سپس از میان همان نتیجه، فقط خط دارای network را نگه دارید. نتیجه را در فایلی تازه به نام network report.txt ذخیره کنید و در خط آخر آن reviewed را اضافه کنید. پیش از اجرا مشخص کنید کدام بخش باید داخل نقلقول باشد و چرا اینبار برای نوشتن خط دوم از >> استفاده میکنید. سپس فایل را بخوانید. پیشبینی نتیجه پیش از اجرای فرمان، راه خوبی برای تشخیص اشتباه در جهت لوله یا مقصد خروجی است.
grep 'warn' events.txt | grep 'network' > "network report.txt"
printf '%s\n' 'reviewed' >> "network report.txt"
cat -- "network report.txt"پاسخ باید دو خط warn network و reviewed باشد. grep اول دامنهٔ بررسی را به هشدارها محدود میکند و grep دوم فقط هشدار شبکه را عبور میدهد. نقلقول نام مقصد، فاصله را بخشی از یک نام نگه میدارد؛ >> خط موجود را حفظ میکند. اگر در خط دوم > میگذاشتید، فقط reviewed باقی میماند. حالا میتوانید از روی یک خط فرمان توضیح دهید متن از کجا میآید، از چه فیلترهایی میگذرد و کجا ذخیره میشود؛ همین توانایی پایهٔ ساخت گزارشهای بزرگتر و قابل تکرار است.
منابع رسمی و مطالعهٔ تکمیلی
https://manpages.ubuntu.com/manpages/focal/man1/mktemp.1.html
https://www.gnu.org/software/bash/manual/html_node/Pipelines.html
https://www.gnu.org/s/bash/manual/html_node/Redirections.html
https://www.gnu.org/software/bash/manual/html_node/Single-Quotes.html
https://www.gnu.org/s/bash/manual/html_node/Double-Quotes.html
https://www.gnu.org/s/bash/manual/html_node/Filename-Expansion.html
تألیف و مثالهای اختصاصی: تحریریه درسآوند. منابع انگلیسی برای بررسی مفاهیم و مطالعهٔ تکمیلی معرفی شدهاند.
متن درسهای عمومی را بدون ورود بخوانید.