سؤال باش البرنامج النصي لا يسجل


لذا ، أنا هنا ، أعزف مع بعض نصوص bash ، وهناك شيء لا يعمل:

#!/bin/bash

script -c \
sudo apt-get update &&
sudo apt-get upgrade &&

exit

echo "(Not important for the question)"

أرغب في تشغيل التحديث المعتاد وترقية الأشياء ، وكذلك تسجيل الإخراج ، ولكن عندما أقوم بتشغيل البرنامج النصي ، فإنه يقول فقط أن البرنامج النصي بدأ في التسجيل apt-get ، ويظهر استخدام sudo ( usage: sudo -h هو السطر الأول) ، ويقول أن النص قد تم. بعد ذلك يبدأ الاشياء sudo.

ما الذي يتعين علي فعله لتسجيل ناتج مهمة التحديث والترقية؟ بشكل عام، كيف يمكنني تسجيل إخراج برنامج نصي كامل shell؟


4
2018-02-14 19:35


الأصل




الأجوبة:


إذا فهمت سؤالك بشكل صحيح ، فيمكنك استخدام ما يلي:

#!/bin/bash

apt-get update &> update.log
apt-get -y upgrade &> upgrade.log

echo "all done"

احفظ هذا النص البرمجي باسم run_updates.sh، وجعلها قابلة للتنفيذ مع chmod 755 run_updates.sh وادخلها sudo ./run_updates.sh.
إذا كنت تريد حفظ كل المخرجات في ملف واحد ، قم بإزالة &> updates.log و &> upgrades.log من البرنامج النصي وتشغيل البرنامج النصي باسم sudo./run_updates.sh &> run_updates.log


شرح البرنامج النصي:

  • apt-get update &> update.log أشواط apt-get update ويحفظ الإخراج في update.log
  • apt-get -y upgrade &> upgrade.log أشواط apt-get upgrade ويحفظ الإخراج في upgrade.log. ال -y يمنع ملائمة من طلب المتابعة (يفترض "نعم")

ملاحظة حول إعادة التوجيه:
يمكنك استخدام عمليات إعادة التوجيه أدناه إلى "إرسال" الإخراج من أمر أو برنامج نصي إلى ملف.

  • &> يعيد توجيه STDOUT و STDERR
  • > أو 1> يعيد توجيه STDOUT
  • 2> يعيد توجيه STDERR

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


تصحيح:
في التعليمة البرمجية التالية ، يتم إعادة توجيه إخراج كل من أوامر apt إلى update.log. المزدوج > (>>) يستخدم لإلحاق البيانات إلى ملف (بدلاً من استبداله)

#!/bin/bash

apt-get update &> update.log
apt-get -y upgrade &>> update.log

echo "all done"

9
2018-02-14 19:53



لم أكن أدرك أنني أستطيع تشغيل البرنامج النصي نفسه sudo. سوف يجعل حياتي أسهل ، شكرا. حول إعادة التوجيه ، هل من الممكن كتابة شيء ما في البرنامج النصي لتسجيل إخراج كلا الأمرين تلقائيًا في نفس الملف بدلاً من كتابة الإخراج على ملفات منفصلة؟ - macacomen98
@ macacomen98 راجع تعديلي ؛-) - Wayne_Yux
حسنا ، هذا يحصل على العمل المنجز. شكر :) - macacomen98


بشكل عام ، لتسجيل إخراج البرنامج النصي بأكمله ، قم بإعادة توجيه إخراج البرنامج النصي بأكمله:

exec &> some.log
# Or, when using `/bin/sh`:
# exec >some.log 2>&1

ال exec مدمج غالباً ما يستخدم لتغيير واصفات الملفات المفتوحة أو إضافة واصفات الملفات الجديدة (مصادر ووجهات الإدخال والإخراج) للصدفة.

على سبيل المثال ، معطى example.sh:

#! /bin/bash
exec &> some.log
ls foo
echo foo

على التوالي:

$ ./example.sh
$ cat some.log
ls: foo: No such file or directory
foo

إذا كنت تريد إخراج كل من المخرج والملف ، فاستخدمه tee مع استبدال عملية:

exec &> >(tee some.log)

4
2018-02-14 23:18





لا حاجة للنص ، فقط افعل ذلك في سطر واحد باستخدام باش tee:

{ sudo apt-get update && sudo apt-get upgrade ; } |& tee output.txt

في حال كنت تريد إلحاق الإخراج إلى ملف تسجيل موجود ، أضف -a الخيار بعد tee.


لتوضيح ما يفعله:

  • { ... ; } مجموعات ... الأوامر في الداخل ، بحيث تسري عمليات إعادة توجيه الإخراج التي سنعملها على جميع الأوامر وليس فقط آخرها. يرجى الانتباه على الفراغ بعد { و قبل } وكذلك على الفاصلة المنقوطة ; بعد كل الاوامر! (شكرا @ kos ليقول لي لتجنب وضع البيض)
  • sudo apt-get update && sudo apt-get upgrade هي أمثلة الأوامر التي نريد تشغيلها وتسجيلها هنا. يمكنك تبادل هذا الجزء كله مع ما تريد.
  • |& ("الأنبوب") يعيد توجيه كل من دفق الإخراج (STDERR / خطأ قياسي و STDOUT / الإخراج القياسي) للأمر الأيسر منه إلى STDIN (الإدخال القياسي) للأمر على اليمين. (شكراmuru لتدريس لي عن & لإعادة توجيه كل من STDOUT و STDERR)
  • tee output.txt نسخ كل ما يقرأ من STDIN إلى STDOUT وأيضا يحفظ output.txt. إذا كان الملف الهدف موجودًا بالفعل ، فستتم الكتابة فوقه بصمت. يمكنك إلحاق الملف بدلاً منه إذا كنت تستخدم tee -a output.txt.

3
2018-02-14 19:55



حول البرنامج النصي ، وعادة ما تفعل هذا على المحطة. يمكنني استخدام البرنامج النصي لمجرد القليل من المرح وتعلم بعض الاشياء. ولكن شكرا للملاحظة على إعادة توجيه STERR و STDOUT إلى نفس الملف ، لم أكن أعرف أنني يمكن أن تفعل ذلك. - macacomen98
بما أنك هناك ، يمكنك أيضًا الإسقاط tee: (sudo apt-get update && sudo apt-get upgrade) >output.txt 2>&1. وإذا كنت ترغب في الذهاب إلى أبعد من ذلك ، يمكنك أيضًا تجنب إنتاج القشرة الفرعية: { sudo apt-get update && sudo apt-get upgrade; } >output.txt 2>&1 ؛) - kos
باش لديه |& إلى عن على 2>&1 |. - muru
kos أحافظ على teeلأن الأشخاص عادة ما يريدون رؤية ما يفعله الأمر. لكن الأقواس المتعرجة تبدو كتحسين. - Byte Commander
@ macacomen98 ./file.txt أو bash file.txt - muru