Linux: التدفقات القياسية وإعادة التوجيه

لينكس يعامل كل برنامج كـ"مرشح" — يستقبل الإدخال من مكان ما، يعالجه، ويُخرج النتائج. قنوات الإدخال والإخراج هي التدفقات القياسية.

📋 المتطلبات المسبقة: يجب إكمال

1. ما ستتعلمه


2. قصة شاشة مليئة بالأخطاء

(1) الألم: مخرجات مختلطة تصعب إيجاد ما تحتاجه

شغّل شياو مينغ apt update، فاختلطت رسائل النجاح مع رسائل الخطأ الحمراء على الشاشة. أراد فقط حفظ النتائج الناجحة وعرض الأخطاء منفصلة.

(2) فصل المخرجات بإعادة التوجيه

علّمه بوب استخدام إعادة التوجيه:

BASH
# حفظ رسائل النجاح في success.log، والأخطاء في error.log
sudo apt update > success.log 2> error.log

# عرض الأخطاء
cat error.log

(3) الفائدة: تحكم دقيق في المخرجات

تعلّم شياو مينغ توجيه مخرجات مختلفة إلى تدفقات منفصلة — ملفات السجل تسجل النجاحات فقط، والطرفية تعرض المعلومات المهمة فقط، والأخطاء محفوظة منفصلة لاستكشافها.


3. نقاط المعرفة

(1) التدفقات القياسية الثلاثة

عند بدء برنامج لينكس، يستقبل تلقائيًا ثلاثة واصفات ملفات:

واصف الملف الاسم الاتصال الافتراضي الغرض
0 stdin لوحة المفاتيح إدخال البرنامج
1 stdout شاشة الطرفية مخرج البرنامج العادي
2 stderr شاشة الطرفية مخرج أخطاء البرنامج
TEXT

          ┌──────────┐
stdin ──→│          │──→ stdout
(keyboard)│  Program │    (screen)
          │          │──→ stderr
          └──────────┘    (screen)

(2) معاملات إعادة التوجيه

المعامل المعنى مثال
> كتابة stdout إلى ملف (كتابة فوق) ls > files.txt
>> إلحاق stdout بملف echo "done" >> log.txt
< قراءة stdin من ملف sort < list.txt
2> كتابة stderr إلى ملف cmd 2> error.log
2>> إلحاق stderr بملف cmd 2>> error.log
&> كتابة stdout وstderr معًا إلى ملف cmd &> all.log
&>> إلحاق stdout وstderr معًا بملف cmd &>> all.log
2>&1 دمج stderr في stdout cmd > log.txt 2>&1

ℹ️ ملاحظة: > يكتب فوق (محتوى الملف الموجود يُمحى)، بينما >> يُلحق (يضيف في نهاية الملف). استخدم >> عندما تحتاج حفظ السجلات التاريخية؛ واستخدم > عندما تحتاج حالة نظيفة. استخدام > بالخطأ قد يكتب فوق ملفات سجل مهمة.

(3) /dev/null — الثقب الأسود

/dev/null هو ملف جهاز خاص — أي بيانات تُكتب إليه تُهمل، والقراءة منه لا تُعيد شيئًا.

💡 نصيحة: /dev/null هو "جهاز الثقب الأسود" في لينكس — النواة تتجاهل البيانات المكتوبة مباشرة على مستوى المحرك، دون استخدام مساحة قرص، ولا يمتلئ أبدًا. يُستخدم عادةً لكتم مخرجات الأوامر: command &> /dev/null يكتم كل المخرجات تمامًا، وcommand 2> /dev/null يكتم الأخطاء فقط.

TEXT
# تجاهل كل المخرجات
command > /dev/null 2>&1

# أو الصيغة الأقصر
command &> /dev/null

# تجاهل الأخطاء فقط
command 2> /dev/null

# تجاهل المخرج العادي فقط
command > /dev/null

(4) ▶ مثال: حفظ مخرجات أمر في ملف

BASH
# كتابة فوق
ls ~ > home-directory.txt
cat home-directory.txt

# إلحاق
echo "A new line" >> home-directory.txt
echo "Another line" >> home-directory.txt
cat home-directory.txt

الإخراج:

TEXT
Desktop
Documents
    Downloads
A new line
Another line

(5) ▶ مثال: فصل المخرج العادي عن مخرج الخطأ

BASH
# حفظ رسائل النجاح، عرض الأخطاء منفصلة
find /etc -name "*.conf" > found.txt 2> errors.txt

# عرض النتائج
echo "=== Found config files ==="
head -5 found.txt

echo "=== Error messages ==="
cat errors.txt

الإخراج:

TEXT
=== Found config files ===
/etc/adduser.conf
/etc/ca-certificates.conf
/etc/debconf.conf
/etc/deluser.conf
/etc/fuse.conf
=== Error messages ===
find: '/etc/ssl/private': Permission denied

(6) ▶ مثال: دمج المخرجات

BASH
# الطريقة 1: &> (bash 4+)
grep -r "error" /var/log/ &> all-results.txt

# الطريقة 2: 2>&1 (أكثر قابلية للنقل)
grep -r "error" /var/log/ > all-results.txt 2>&1

# كلتا الطريقتين تعطيان نفس النتيجة — stdout وstderr يذهبان لنفس الملف

> 💡 نصيحة: ترتيب `2>&1` مهم! `cmd > log.txt 2>&1` صحيح — أولًا أعد توجيه stdout إلى ملف، ثم ادمج stderr في stdout (الذي يشير الآن للملف). إذا كُتبت كـ`cmd 2>&1 > log.txt`، سيتداخل stderr أولًا مع stdout للشاشة، ثم يُعاد توجيه stdout للملف، تاركًا stderr يذهب للشاشة.

الإخراج:

TEXT
$ wc -l all-results.txt
42 all-results.txt

(7) ▶ مثال: /dev/null لكتم المخرجات

BASH
# تنفيذ صامت تمامًا
sudo apt update > /dev/null 2>&1

# صيغة أقصر
sudo apt update &> /dev/null

# كتم الأخطاء فقط
find / -name "*.py" 2> /dev/null

الإخراج:

TEXT
(لا مخرجات — كل الأخطاء والنتائج العادية مكتومة)

(8) ▶ مثال: heredoc — تضمين نص متعدد الأسطر في السكريبتات

BASH
# إنشاء ملف إعدادات متعدد الأسطر
cat << EOF > nginx.conf
server {
    listen 80;
    server_name example.com;
    root /var/www/html;
}
EOF

# إلحاق نص متعدد الأسطر
cat << EOF >> ~/.bashrc
# Add PATH
export PATH="\$PATH:\$HOME/scripts"
EOF

# المتغيرات في heredoc لن تُوسَّع (استخدم 'EOF' بين علامتي اقتباس)
cat << 'EOF' > greeting.sh
#!/bin/bash
echo "Hello, $USER"    # $USER يبقى كاسم متغير
EOF

الإخراج:

TEXT
server {
    listen 80;
    server_name example.com;
    root /var/www/html;
}

(9) ▶ مثال شامل: إدارة المخرجات أثناء تجميع برنامج

BASH
# تجميع برنامج C، تسجيل المخرجات والأخطاء منفصلة
gcc main.c -o app \
    > build.log \        # Compilation success messages
    2> build-errors.log  # Compilation error messages

# إذا نجح التجميع، build-errors.log فارغ
# إذا فشل التجميع، اعرض الأخطاء
if [ -s build-errors.log ]; then
    echo "❌ Compilation failed, errors:"
    cat build-errors.log
else
    echo "✅ Compilation successful!"
fi

❓ أسئلة شائعة

س: ما الفرق بين > و| (أنبوب)؟ ج: \1

س: ماذا يعني 2>&1؟ ج: \1

س: لماذا أستخدم &> بدلًا من 2>&1؟ ج: &> اختصار في bash 4+ أكثر إيجازًا. 2>&1 أكثر قابلية للنقل (يعمل في sh أيضًا). كلاهما يفعل نفس الشيء.

س: هل /dev/null فراغ؟ هل يمكن أن يمتلئ؟ ج: لا. البيانات المكتوبة إلى /dev/null تُهمل من النواة مباشرة، دون استخدام أي مساحة قرص. هو أساسًا "ثقب أسود بسعة لا نهائية."

س: هل يجب أن تكون EOF في heredop بأحرف كبيرة؟ ج: لا. EOF مجرد اتفاق؛ يمكنك استخدام أي سلسلة (EOL أو END أو __EOF__). المهم أن علامتا البداية والنهاية تتطابقان تمامًا.


📖 ملخص


📝 تمارين

  1. أساسي (صعوبة ⭐): احفظ مخرجات ls -la | في home-list.txt، ثم ألحق التاريخ الحالي بـ>>
  2. متوسط (صعوبة ⭐⭐): شغّل find / -name "*.py" 2> errors.txt لعرض أخطاء رفض الصلاحية، ثم استخدم &> لالتقاط stdout وstderr في ملف واحد، واستخدم /dev/null لكتم مخرج الأخطاء
  3. متقدم (صعوبة ⭐⭐⭐): استخدم heredoc لإنشاء ملف إعدادات بـ5 أسطر محتوى، ثم اكتب سكريبتًا يوضح طرق إعادة التوجيه الأربع (> و2> و&> و>>) ويشرح متى تستخدم كلًا منها
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%