Pipe معمولی با علامت |، خروجی استاندارد یک فرمان را به ورودی استاندارد فرمان بعد میرساند؛ پیام خطا بهطور پیشفرض وارد این مسیر نمیشود. دانستن همین تفاوت کمک میکند بفهمید چرا خطا روی صفحه دیده میشود، اما در نتیجهٔ grep یا شمارش wc نیست. مثالهای این راهنما فقط با متن آموزشی کار میکنند و فایل واقعی را تغییر نمیدهند.
۱. سه جریان را بشناسید
| جریان | شماره | کاربرد معمول |
|---|---|---|
stdin |
0 |
دادهای که فرمان از ورودی میخواند |
stdout |
1 |
نتیجهٔ عادی فرمان |
stderr |
2 |
پیام خطا یا تشخیص |
هر فرمان لازم نیست از stdin استفاده کند یا همهٔ پیامهایش را روی stderr بنویسد؛ این قرارداد عمومی است و رفتار ابزار هم مهم است. Pipe معمولی فقط stdout را متصل میکند. مستند Pipelines در Bash این اتصال و وضعیت خروج زنجیره را توضیح میدهد.

۲. یک زنجیرهٔ ساده را قدمبهقدم بخوانید
printf '%s\n' alpha beta alpha | grep -F 'alpha' | wc -l
printf سه خط میسازد. grep دو خط شامل متن ثابت alpha را عبور میدهد و wc -l تعداد نویسههای پایان خط را میشمارد؛ خروجی این نمونه۲ است. ابزارها از چپ به راست به هم متصلاند، اما لازم نیست فرمان اول کاملاً تمام شود تا بعدی شروع شود؛ جریان داده میتواند همزمان منتقل شود.
نکته: این نتیجه مخصوص دادهٔ آموزشی بالاست. wc -l تعداد نویسهٔ newline را میشمارد و روی ورودی بدون newline پایانی ممکن است با برداشت شما از تعداد رکورد فرق داشته باشد.
۳. چرا پیام خطا در شمارش نیست؟
{ printf '%s\n' data; printf '%s\n' issue >&2; } | wc -l
در این مثال، data روی stdout و issue عمداً روی stderr نوشته میشود. wc فقط یک خط دریافت میکند؛ بنابراین عدد۱ میدهد و issue جدا روی صفحه دیده میشود. این خطا واقعیِ یک سرویس نیست؛ دو جریان با دادهٔ آموزشی تولید شدهاند تا رفتارشان قابل مشاهده باشد.
{ printf '%s\n' data; printf '%s\n' issue >&2; } 2>&1 | wc -l
در نمونهٔ دوم، ۲>&۱ خروجی خطا را به مقصد فعلی خروجی استاندارد وصل میکند؛ هر دو خط وارد Pipe میشوند و نتیجه۲ است. عبارت >&۲ در مثال اول جهت عکس دارد: خروجی همان printf را به جریان خطا میفرستد. طبق مستند Redirections در Bash، ترتیب اتصال و redirect مهم است. ترکیب دو جریان برای عیبیابی مفید است، اما اگر خروجی دادهٔ ساختاریافته مثل JSON باشد، ورود متن خطا میتواند آن را خراب کند.
۴. موفقیت فرمان آخر کافی نیست
false | wc -l
printf 'status=%s\n' "$?"
در Bash با تنظیم پیشفرض و pipefail خاموش، wc روی ورودی خالی عدد۰ میدهد و موفق میشود؛ وضعیت کل زنجیره نیز۰ است، حتی با اینکه false شکست خورده است. $? باید بلافاصله پس از زنجیره خوانده شود؛ اجرای یک فرمان دیگر آن را عوض میکند.
set -o pipefail
false | wc -l
printf 'status=%s\n' "$?"
در یک نشست آزمایشی تازهٔ Bash، نمونهٔ دوم status=۱ میدهد. pipefail رفتار وضعیت خروج همهٔ زنجیرههای بعدیِ همان شل را تغییر میدهد؛ آن را بدون بررسی به اسکریپت موجود اضافه نکنید. این گزینه در همهٔ شلها قابل اتکا نیست. مثالها در Bash5.۲.۳۷ با نام اجرایی sh در MSYS اجرا شدهاند، نه در هر پیادهسازی sh.
برای تمرین از شل آزمایشی جدا استفاده کنید؛ پایان آن نشست، تنظیم موقت را به نشست اصلی منتقل نمیکند. هیچ فایل یا تنظیم سرویسی در این مثالها ویرایش نمیشود.
۵. پیش از اتصال فرمانها، خروجی را بشناسید
- هر بخش را با دادهٔ کوچک و غیرحساس جدا اجرا کنید؛ ورودی و خروجی مورد انتظار را بنویسید.
- تفاوت متن نتیجه و پیام تشخیص را روشن کنید. اگر آنها را ترکیب میکنید، دلیل داشته باشید.
- وضعیت خروج زنجیره را بررسی کنید؛ خالیبودن نتیجه الزاماً موفقیت نیست.
- برای فایل و دادهٔ واقعی، ابتدا مسیر و دسترسی را بررسی کنید. این آموزش عمداً از نوشتن با > و حذف فایل استفاده نمیکند.
Pipe فقط یک روش اتصال است؛ معنای داده را تصحیح نمیکند. اگر فیلتر اشتباه باشد، فرمان بعدی میتواند با موفقیت روی دادهٔ اشتباه کار کند. تعداد نهایی را با یک نمونهٔ قابل محاسبه کنترل کنید.
۶. پرسشهای رایج
Pipe فایل میسازد؟
خود علامت | فایل خروجی ایجاد نمیکند؛ اما فرمانهای دو طرف ممکن است اثر جانبی داشته باشند. قبل از ترکیب ابزارهای تغییردهنده باید دامنهٔ اثرشان را بدانید.
چرا خطا را میبینم ولی grep آن را پیدا نمیکند؟
ممکن است خطا روی stderr باشد و grep فقط stdout را دریافت کند. پیش از افزودن ۲>&۱، بررسی کنید ترکیب خطا با داده برای کار بعدی مناسب است یا نه.
۷. مسیر مطالعهٔ مرتبط
- آموزش grep در لینوکس؛ جستوجوی متن و خطا در لاگ
- تحلیل سادهٔ لاگ با sort و uniq و wc؛ شمارش درست رخدادها
۸. منابع و دامنهٔ بررسی
منابع رسمی در ۳ نوامبر ۲۰۲۶ بررسی شدند. نمونهها در Bash ۵.۲.۳۷ و GNU Coreutils ۸.۳۲ در محیط MSYS روی ویندوز اجرا شدند؛ این آزمون، اجرای بومی روی یک توزیع لینوکس نیست. مستند آنلاین GNU میتواند نسخهٔ جدیدتری را شرح دهد؛ فقط گزینههای ذکرشده و بررسیشده مبنای مثالاند.