سؤال كيفية إعادة توجيه stderr إلى ملف [مكرر]


هذا السؤال لديه بالفعل إجابة هنا:

أثناء استخدام nohup لوضع أمر للتشغيل في الخلفية ، يظهر بعض المحتوى في المطراف.

cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

أرغب في حفظ هذا المحتوى في ملف.


163
2018-05-18 12:31


الأصل




الأجوبة:


هناك نوعان من المخرجات الرئيسية في Linux (و أنظمة التشغيل الأخرى) ، الإخراج القياسي (stdout) و الخطأ القياسي (stderr). تتم طباعة رسائل الخطأ ، مثل تلك التي تظهر ، إلى الخطأ القياسي. مشغل إعادة التوجيه الكلاسيكي (command > file) يعيد توجيه الإخراج القياسي فقط ، لذلك لا يزال يظهر الخطأ القياسي على الجهاز. لإعادة توجيه stderr كذلك ، لديك بعض الخيارات:

  1. إعادة توجيه stdout إلى ملف واحد و stderr إلى ملف آخر:

    command > out 2>error
    
  2. إعادة توجيه stderr إلى stdout (&1) ، ثم إعادة توجيه stdout إلى ملف:

    command >out 2>&1
    
  3. إعادة توجيه كلا الملفين:

    command &> out
    

لمزيد من المعلومات حول مختلف مشغلي التحكم وإعادة التوجيه ، راجع هنا.


265
2018-05-18 12:50



وبالتالي hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ >> result_hashdeep.txt 2> error_hashdeep.txt & أو hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ >> result_hashdeep.txt 2>&1 أو hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ &> result_mixed.txt - André M. Faria
@ AndréM.Faria نعم. ولكن الأمرين الأخيرين متساويين ، فسيُرسلان كل من الخطأ والإخراج إلى نفس الملف. - terdon♦
وكما هو الحال في الرابط الذي قدمته ، يمكنني استخدام | وبدلاً من 2> & 1 ، فهي مكافئة ، شكرًا لك على الوقت. - André M. Faria
مرحبًا ، تمكنت من تبسيط هذا إلى: command 2> out. - Surya Teja Karra
SuryaTejaKarra أن يعيد توجيه stderr فقط ، ولكن ليس stdout. - terdon♦


أول شيء يجب أن تلاحظه هو أن هناك طريقتين يعتمدان على الغرض الخاص بك والصدفة ، لذلك يتطلب هذا فهمًا بسيطًا للجوانب المتعددة. الأكثر شيوعا ، هو عبر 2> في قذائف بورن تشبه، مثل dash (والتي ترتبط بـ /bin/sh) و bash. الأول هو shell الافتراضي و POSIX المتوافق والآخر هو ما يستخدمه معظم المستخدمين للجلسة التفاعلية. وهي تختلف في بناء الجملة والميزات ، ولكن لحسن الحظ بالنسبة لنا إعادة توجيه تيار الخطأ يعمل نفسه (باستثناء &> غير قياسي واحد). في حالة csh ومشتقاته ، فإن إعادة توجيه stderr لا يعمل تماما هناك.

دعونا نعود إلى 2> جزء. هناك أمران رئيسيان يجب ملاحظتهما: > يعني مشغل إعادة التوجيه ، حيث نفتح ملف و 2 عدد صحيح يقف ل واصف ملف ستدير ؛ في الواقع هذا هو بالضبط كيف يحدد معيار POSIX للغة shell إعادة التوجيه في القسم 2.7:

[n]redir-op word

للبسيط > إعادة توجيه ، و 1 عدد صحيح ضمني لـ stdout، أي echo Hello World > /dev/null هو نفسه تمامًا echo Hello World 1>/dev/null. لاحظ أنه لا يمكن الإشارة إلى عامل التشغيل الصحيح أو إعادة التوجيه ، وإلا فإن shell لا يتعرف عليها على هذا النحو ، ويعامل بدلاً من ذلك كسلسلة حرفية من النص. بالنسبة إلى المسافات ، من المهم أن يكون العدد الصحيح بجوار مشغل إعادة التوجيه مباشرة ، ولكن يمكن أن يكون الملف بجوار مشغل إعادة التوجيه أم لا ، أي command 2>/dev/null و command 2> /dev/null سوف تعمل على ما يرام.

سيكون بناء الجملة المبسط إلى حد ما للأمر النموذجي في shell

 command [arg1] [arg2]  2> /dev/null

الحيلة هنا هي أن إعادة التوجيه يمكن أن تظهر في أي مكان. هذا هو كليهما 2> command [arg1] و command 2> [arg1] صالحة. لاحظ ذلك ل bash قذيفة ، هناك موجود &> طريقة لإعادة توجيه كل من stdout و stderr دفق في نفس الوقت ، ولكن مرة أخرى - هو bash محددة وإذا كنت تسعى للحصول على إمكانية التنقل من البرامج النصية ، قد لا تعمل. أنظر أيضا أوبونتو ويكي و ما الفرق بين &> و 2> & 1.

ملحوظة: ال > عامل إعادة التوجيه باقتطاعملف والكتابة فوقه ، إذا كان الملف موجودًا. ال 2>> يمكن استخدامها لإلحاق stderr إلى ملف.

إذا كنت قد تلاحظ ، > يقصد لأمر واحد واحد. بالنسبة إلى النصوص البرمجية ، يمكننا إعادة توجيه دفق stderr من البرنامج النصي بأكمله من الخارج كما هو موضح في myscript.sh 2> /dev/null أو يمكننا الاستفادة منها اكسيك مدمج. يمتلك exec المضمّن القدرة على إعادة تشغيل الدفق لجلسة shell بأكملها ، إذا جاز التعبير ، سواء بشكل تفاعلي أو عبر برنامج نصي. شيء مثل

#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file

في هذا المثال ، يجب أن يظهر ملف السجل stat: cannot stat '/etc/non_existing_file': No such file or directory.

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

some_function(){
    command1
    command2
} 2> my_log_file.txt

5
2018-05-03 07:48