في عالم واجهة سطر الأوامر، تتعامل البرامج غالبًا مع ثلاثة تدفقات بيانات قياسية:
stdin): حيث يستقبل البرنامج مُدخلاته (عادةً من لوحة المفاتيح).stdout): حيث يُرسل البرنامج مُخرجاته العادية (عادةً إلى شاشة الطرفية).stderr): حيث يُرسل البرنامج رسائل الخطأ (عادةً إلى شاشة الطرفية).تذكّر أننا قدّمنا هذه التدفقات في فصل الأنابيب وقوائم الأوامر.
يمكن اعتبار الأنابيب شكلًا من أشكال إعادة التوجيه: يُرسَل الإخراج القياسي من برنامج ما مباشرةً إلى الإدخال القياسي لبرنامج آخر. لقد تناولنا الأنابيب بالفعل. سيتناول هذا المفهوم إعادة التوجيه إلى الملفات ومنها.
إعادة التوجيه في الصدفة آلية قوية تتيح لك تغيير وجهة هذه التدفقات. فبدلًا من أن يقرأ البرنامج من لوحة المفاتيح أو يكتب على الشاشة، يمكنك إعادة توجيه الإدخال من ملف أو إرسال الإخراج إلى ملف. ويمنحك هذا مرونة وتحكمًا كبيرين في كيفية تعامل البرامج مع البيانات.
فيما يلي أكثر عوامل إعادة التوجيه شيوعًا وما تفعله:
> (إعادة توجيه الإخراج)الغرض: إعادة توجيه الإخراج القياسي (stdout) لأمر ما إلى ملف.
السلوك:
مثال:
# Sends the output of 'ls -l' to 'file_listing.txt'
ls -l > file_listing.txt
تُنفَّذ إعادة التوجيه قبل تنفيذ الأمر. وهذا يعني أنك لا تستطيع إعادة التوجيه إلى الملف نفسه الذي تحتاج إلى القراءة منه.
date > date.txt # populate the file with the current date
cat date.txt > date.txt # 'date.txt' is now empty!
في الأمر الثاني من المثال أعلاه،
>> (إعادة توجيه الإخراج بالإلحاق)الغرض: إلحاق الإخراج القياسي (stdout) لأمر ما بملف.
السلوك:
مثال:
# Adds "Another line" to the end of the file
echo "Another line" >> file_listing.txt
< (إعادة توجيه الإدخال)الغرض: إعادة توجيه الإدخال القياسي (stdin) لأمر ما من ملف.
السلوك: يقرأ الأمر مُدخلاته من الملف المحدد بدلًا من لوحة المفاتيح.
مثال:
# 'tr' reads from 'lowercase.txt' and
# output is redirected to 'uppercase.txt'
tr 'a-z' 'A-Z' < lowercase.txt > uppercase.txt
2> (إعادة توجيه الخطأ):stderr) لأمر ما إلى ملف.# Error message from 'rm' is sent to 'error_log.txt'
rm non_existent_file 2> error_log.txt
يمكنك إلحاق الخطأ القياسي بملف باستخدام 2>>.
هناك أيضًا إعادات توجيه يمكنها دمج كلٍّ من stdin وstderr.
راجع الدليل للتفاصيل.
/dev/null/dev/null ملف خاص:
يُشار إليه أحيانًا باسم «bitbucket». وهو مفيد لكتم الإخراج أو الأخطاء.
some_command > /dev/null # Discards stdout
some_command 2> /dev/null # Discards stderr
# Using /dev/null as input will prevent the command
# from reading data from the keyboard
some_command < /dev/null
يمكن إعطاء إعادات توجيه متعددة في وقت واحد.
some_command < input.txt > output.txt 2> error.txt
يمكن نسخ إعادة التوجيه.
# send stderr to the same destination as stdout
some_command > output.txt 2>&1
عندما ترى 2>&1، اقرأها هكذا: «أعد توجيه stderr إلى _أي وجهة يشير إليها stdout حاليًا».
يعالج Bash تعليمات إعادة التوجيه من اليسار إلى اليمين بدقة، ما يعني أنه يمكنك فعل ما يلي:
# redirect stdout to 'output1.txt'
# redirect stderr to the same place
# then change stdout to 'output2.txt'
some_command > output1.txt 2>&1 > output2.txt
في سياق البرمجة بالصدفة وأنظمة التشغيل مثل Linux/Unix، واصف الملف (FD) هو عدد صحيح غير سالب يعمل كمعرّف أو مقبض لملف مفتوح أو لمورد إدخال/إخراج (Input/Output). تخيّله مثل ملصق أو رقم مرجعي يستخدمه نظام التشغيل لتتبّع الملفات المفتوحة وتدفقات البيانات.
الأرقام التي تراها على الجانب الأيسر من إعادات التوجيه هي واصفات ملفات.
تُمنح تدفقات الإدخال/الإخراج القياسية أول 3 واصفات ملفات:
يمكن ضبط واصفات ملفات جديدة أو إنشاؤها باستخدام أمر exec وعوامل إعادة التوجيه.
# create FD 3 as a copy of stdout
exec 3>&1
# send stdout to a log file
exec > log.txt
# then redirect both stdout and file descriptor 3
echo "some debug message" >&3 # displayed in the terminal
some_command 2>&1 # stdout and stderr send to 'log.txt'
تبدو هذه التقنية معقّدة إلى حد كبير، لكنها قد تكون مفيدة جدًا في الحالات التي يشغّل فيها برنامج آخر نصك البرمجي، ويلتقط هذا البرنامج الإخراج القياسي تلقائيًا.
أمر bats الذي يُستخدم لتشغيل اختبارات الوحدة في هذا المسار يعمل بهذه الطريقة: يلتقط bats الإخراج القياسي والخطأ القياسي للاختبار، لكن رسائل التنقيح المرسلة إلى واصف الملف 3 ستُعرض على الطرفية.
لماذا تُعدّ إعادة التوجيه مفيدة؟
تمنحك إعادات التوجيه في الصدفة تحكمًا دقيقًا في كيفية تعامل البرامج مع البيانات، ما يمكّنك من بناء مسارات عمل معقّدة وإدارة المعلومات بفعالية.