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

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

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

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

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

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

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

    command >out 2>&1
  3. إعادة توجيه كلاهما إلى ملف (هذا غير مدعوم من قبل جميع الأصداف, bash و zsh دعم ذلك ، على سبيل المثال ، ولكن sh و ksh لا):

    command &> out

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

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

النظرية الأساسية وراء إعادة التوجيه هي أن العملية التي تولدها شل (بافتراض أنها أمر خارجي وليست قذيفة مدمجة) يتم إنشاؤها عبر fork() و execve() سيسكالز ، وقبل أن يحدث سيسكالز آخر dup2() ينفذ عمليات إعادة التوجيه اللازمة من قبل execve() يحدث. وبهذا المعنى ، يتم توريث عمليات إعادة التوجيه من الغلاف الأصلي. ال m&>n و m>n.txt إبلاغ قذيفة على كيفية تنفيذ open() و dup2() سيسكال (انظر أيضا كيف يعمل إعادة توجيه الإدخال, ما هو الفرق بين إعادة التوجيه والأنابيب، و ماذا يعني بالضبط في إعادة توجيه الإخراج )

إعادة توجيه شل

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

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

[n]redir-op word

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

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

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

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

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

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

#!/bin/shexec 2> ./my_log_file.txtstat /etc/non_existing_file

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

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

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

أوامر الكتابة إلى ستدير حصريا

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

time echo foo 2>&1 > file.txt

بدلا من ذلك ، يمكن إعادة توجيه قائمة متزامنة أو سوبشيل إذا كنت ترغب في فصل الإخراج (كما هو مبين في وظيفة ذات صلة ):

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

أوامر أخرى، مثل strace أو dialog توفير وسائل لإعادة توجيه ستدير. strace لديه -o <filename.txt> الخيار الذي يسمح بتحديد اسم الملف حيث يجب كتابة الإخراج. هناك أيضا خيار لكتابة ملف نصي لكل عملية فرعية strace يرى. ال dialog الأمر يكتب واجهة المستخدم النص إلى ستدوت ولكن الإخراج إلى ستدير ، وذلك من أجل حفظ انتاجها إلى متغير (لأن var=$(...) وخطوط الأنابيب يتلقى فقط ستدير) نحن بحاجة إلى مبادلة واصفات الملف

result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);

ولكن بالإضافة إلى ذلك ، هناك --output-fd العلم ، والتي يمكننا أيضا الاستفادة منها. هناك أيضا طريقة الأنابيب المسماة. أوصي بقراءة المنشور المرتبط حول dialog الأمر للحصول على وصف شامل لما يحدث.

@تيردون هذا سؤال أكثر تحديدا ، ويظهر بشكل صحيح في بحث غوغل عن السؤال الأكثر تحديدا، وهو أمر جيد.

نعم ، وسوف تستمر في الظهور ، وهذا لن يتغير. لكن أي إجابات جديدة يجب أن تذهب إلى السؤال الأكثر عمومية.