ریدایرکت در لینوکس: هدایت ورودی و خروجی فرمانها
آموزش ریدایرکت stdout و stderr، الحاق، here-doc و تفاوت با لوله در شل لینوکس با مثال واقعی.
Founder & product engineer

لوله فرمان را به فرمان وصل میکند؛ ریدایرکت فرمان را به فایل، دستگاه، یا توصیفگر دیگر وصل میکند. نمادهای >، >>، < و ترکیبهایی مثل 2>&1 از پرکاربردترین قراردادهای شلاند و اشتباه در آنها یا لاگ را میبلعد یا دیسک را با خروجی بینهایت پر میکند.
اگر مقالهٔ لوله را خواندهاید، اینجا قطعهٔ دوم همان مدل ذهنی stdin/stdout/stderr است — با تمرکز روی فایل و توصیفگرها.

پاسخ کوتاه
`cmd > out.txt` خروجی استاندارد را مینویسد (بازنویسی). `cmd >> out.txt` الحاق میکند. `cmd 2> err.txt` خطا را جدا میکند. `cmd > all.txt 2>&1` هر دو را در یک فایل جمع میکند — ترتیب مهم است. `cmd < in.txt` ورودی را از فایل میخواند. برای دور ریختن: `>/dev/null`. برای بلوک چندخطی ورودی: heredoc با `<<`.
ترتیب ریدایرکتها معنی دارد؛ کپی کردن طوطیوار 2>&1 بدون فهم، باگ خاموش میسازد.
بازنویسی در برابر الحاق
bash
echo first > /tmp/demo.txt echo second > /tmp/demo.txt cat /tmp/demo.txt echo first > /tmp/demo.txt echo second >> /tmp/demo.txt cat /tmp/demo.txt
یک > فایل را از نو میسازد/خالی میکند؛ >> اضافه میکند. در cron و لاگ اپ، انتخاب بین چرخش فایل و >> دائمی سیاست دیسک است.
جدا کردن stdout و stderr
bash
ls /etc/hosts /no/such 1> /tmp/out.txt 2> /tmp/err.txt cat /tmp/out.txt cat /tmp/err.txt
۱ همان stdout است و معمولاً قابل حذف: `>file` معادل `1>file`. جدا کردن برای پردازش بعدی مفید است: داده تمیز در out، تشخیص در err.
ادغام خطا در خروجی: ترتیب
bash
# درست برای جمع در یک فایل: cmd > /tmp/all.txt 2>&1 # یا شکل جدیدتر bash: cmd &> /tmp/all.txt
توضیح کلاسیک: `>file 2>&1` یعنی اول stdout به file، بعد stderr به همان جایی که الان stdout اشاره میکند. اگر `2>&1 >file` بنویسید، اغلب stderr هنوز به ترمینال میرود. این جزئیات منبع دههها سردرگمی است — همان ترتیب اول را حفظ کنید مگر بدانید چه میکنید.
ورود از فایل و here-string
bash
wc -l < /etc/hosts grep root < /etc/passwd # here-string در bash: grep r <<< $'root\nbin\ndaemon'
بسیاری فرمانها هم آرگومان فایل میگیرند هم stdin؛ ریدایرکت وقتی مفید است که فقط stdin میپذیرند یا میخواهید الگوی یکسانی با لوله داشته باشید.
Heredoc برای پیکربندی و اسکریپت
bash
cat > /tmp/hello.sh << 'EOF' #!/bin/bash echo "hello $USER" EOF chmod +x /tmp/hello.sh
اگر EOF را در تکنقلقول بگذارید، متغیر داخل بدنه همان لحظه باز نمیشود — برای تولید اسکریپت امنتر است. بدون نقلقول، شل متغیرها را الان باز میکند.
/dev/null و سکوت آگاهانه
bash
cmd >/dev/null 2>&1 cmd 2>/dev/null grep -q pattern file && echo found
دور ریختن همه چیز عیبیابی را سخت میکند؛ در cronهای پرسروصدا گاهی stderr را به فایل جدا بفرستید نه null. -q در grep برای سکوت ساختاریافته بهتر از پرتاب به null است وقتی فقط کد خروج میخواهید.
ریدایرکت و لوله با هم
bash
grep -i error < /var/log/app.log | tee /tmp/errors.txt | wc -l command 2>&1 | tee /tmp/session.log | tail
الگوی رایج جلسهٔ SSH: هم ببینید هم ذخیره کنید. مقالهٔ لوله tee را عمیقتر میگوید.
noclobber و جلوگیری از بازنویسی تصادفی
bash
set -o noclobber echo x > /tmp/demo.txt # اگر وجود داشته باشد در این حالت خطا echo x >| /tmp/demo.txt # اجبار در bash
در شل تعاملی محتاط، noclobber جلوی خراب کردن فایل با > تنها را میگیرد. در اسکریپت باید سیاست را صریح کنید.
توصیفگرهای سفارشی (نگاه کاربردی)
bash
exec 3> /tmp/extra.log echo 'note' >&3 exec 3>&-
برای اکثر کار روزمره لازم نیست؛ در اسکریپتهای پیچیده برای جدا کردن کانال لاگ از stdout مفید است. اگر به اینجا رسیدید، مستند bash Redirections را بخوانید.
جدول میانبر
| نوشتار | معنی |
|---|---|
| > file | stdout بازنویسی |
| >> file | stdout الحاق |
| 2> file | stderr به فایل |
| 2>> file | stderr الحاق |
| > file 2>&1 | هر دو به فایل |
| &> file | هر دو (bash) |
| < file | stdin از فایل |
| >/dev/null | دور ریختن stdout |
اشتباههای رایج
- خالی کردن فایل مهم با > بهجای >>.
- ترتیب غلط 2>&1.
- فرستادن همه چیز به /dev/null و تعجب از «چیزی نمیبینم».
- heredoc بدون نقلقول و نشت متغیر ناخواسته.
- ریدایرکت داخل حلقه بدون فهم باز/بسته شدن مکرر فایل (کارایی).
کرون و لاگ
bash
# مثال مفهومی crontab: # */5 * * * * /usr/local/bin/job.sh >>/var/log/job.log 2>&1
بدون ریدایرکت، خروجی cron اغلب به ایمیل محلی یا دور ریخته میشود بسته به تنظیمات. صریح بودن بهتر از اتکا به پیشفرض است.
امنیت جزئی: مجوز فایل خروجی
اگر با sudo ریدایرکت میکنید، بدانید `sudo cmd > /root/out` را شل شما قبل از sudo باز میکند و ممکن است مجوز نداشته باشید. الگوی درست اغلب `cmd | sudo tee /root/out` است.
bash
echo secret | sudo tee /root/out >/dev/null
ریدایرکت داخل حلقه
باز کردن فایل با >> داخل حلقه برای هر تکرار هزینه دارد. برای نوشتنهای زیاد، بهتر است حلقه را در یک ریدایرکت بیرونی بپیچید یا از awk/sed یکگذری استفاده کنید.
bash
# کمبهینه: # for i in $(seq 1 1000); do echo $i >> /tmp/n.txt; done # بهتر: for i in $(seq 1 1000); do echo $i; done > /tmp/n.txt
تشخیص فایل در برابر ترمینال
bash
if [ -t 1 ]; then echo 'stdout is a tty'; else echo 'stdout redirected'; fi
اسکریپتهای خوب وقتی خروجی لوله شده، رنگ و جدولبندی تعاملی را کم میکنند تا مصرفکننده دادهٔ تمیز بگیرد.
ترکیب با sudo و فایل محافظتشده
یادآوری عملی: شل ریدایرکت را پیش از sudo انجام میدهد. برای نوشتن در مسیر root از tee استفاده کنید و مجوز نهایی فایل را چک کنید تا world-readable تصادفی نماند.
bash
umask 077 echo 'content' | sudo tee /root/private.cfg >/dev/null sudo chmod 600 /root/private.cfg
ریدایرکت و چرخش لاگ
اگر فرایند را با >> به فایل باز نگه میدارید، پس از rotate ممکن است هنوز به اینود قدیمی بنویسد. سرویسهای درست سیگنال reopen دارند یا از journal استفاده میکنند. برای اسکریپتهای خودتان، پس از rotate یا فایل را از نو باز کنید یا از logger استفاده کنید.
باز کردن فایل با اندازهٔ صفر توسط > وقتی rotate بد پیکربندی شده باشد میتواند لاگ را پاک کند؛ روی production با احتیاط و مستند ابزار rotate پیش بروید.
bash
# الگوی مفهومی: نوشتن از طریق logger به journal/syslog logger -t myjob 'finished ok'
خلاصه
ریدایرکت کنترل میکند دادهٔ فرمان از کجا بیاید و به کجا برود. > و >>، جداسازی stderr، ادغام با 2>&1 با ترتیب درست، heredoc برای ورودی چندخطی، و احتیاط با /dev/null مجموعهٔ حداقل حرفهای است. با لوله ترکیبش کنید تا هم ذخیره کنید هم فیلتر.
سوالات متداول
تفاوت &> و 2>&1 چیست؟
&> کوتاهنوشت bash برای هدایت هر دو است؛ شکل >file 2>&1 قابلحملتر در مستندهای سنتی است.
چطور فقط stderr را لوله کنم؟
در bash میتوان stderr را جدا کرد؛ الگوی رایج `cmd 2>&1 >/dev/null | filter` برای فقط خطا، یا استفاده از توصیفگرها. برای کار ساده، هر دو را ادغام و بعد فیلتر کنید.
چرا فایل خروجی خالی است ولی خطا روی صفحه بود؟
احتمالاً فقط stdout را ریدایرکت کردهاید و پیام روی stderr مانده. 2>&1 را اضافه کنید.
منابع و مراجع
- Bash Reference Manual — Redirections: https://www.gnu.org/software/bash/manual/html_node/Redirections.html
- bash(1) Linux man page: https://man7.org/linux/man-pages/man1/bash.1.html
- Advanced Bash-Scripting Guide — I/O Redirection (TLDP): https://tldp.org/LDP/abs/html/io-redirection.html
Author
Soheil Ebrahimpour is the founder of FutureForge. He works on product design, architecture, and getting custom software into production.
Related notes
If you are unsure about architecture or the build path, we can talk about the project.
Describe the problem and the constraints. If there is a fit, we will schedule a conversation.




