bash شرح - صدى أن المخرجات إلى stderr




7 Answers

هذا السؤال قديم ، ولكن يمكنك القيام بذلك ، مما يسهل القراءة:

>&2 echo "error"

المشغل >&2 تعني حرفياً إعادة توجيه عنوان واصف الملف 1 ( stdout ) إلى عنوان واصف الملف 2 ( stderr ) لهذا الأمر 1 . اعتمادًا على مدى عمق فهمك له ، اقرأ هذا: http://wiki.bash-hackers.org/howto/redirection_tutorial

لتجنب التفاعل مع عمليات إعادة التوجيه الأخرى استخدم subshell

(>&2 echo "error")

1 >&2 نسخ ملف واصف # 2 إلى ملف واصف # 1. لذلك ، بعد إجراء إعادة التوجيه هذا ، سيشير كل من واصفات الملف إلى نفس الملف: واصف الملف الأول # 2 في الأصل إلى.

معنى download

هل هناك أداة Bash قياسية تعمل مثل الارتداد ، ولكن يتم إخراجها إلى stderr بدلاً من stdout؟

أعلم أنه يمكنني القيام echo foo 1>&2 ولكنه قبيح نوعًا ما ، وأظن أنه عرضة للخطأ (على سبيل المثال أكثر احتمالية لتحرير الخطأ عندما تتغير الأشياء).




نظرًا لأن 1 هو الإخراج القياسي ، لا يلزمك تسميته صراحةً أمام إعادة توجيه الإخراج مثل > ولكن بدلاً من ذلك يمكنك ببساطة كتابة:

echo This message goes to stderr >&2

نظرًا لأنك تشعر بالقلق من أن 1>&2 سيكون من الصعب عليك الكتابة بشكل موثوق به ، قد يكون التخلص من العنصر الإضافي 1 تشجيعاً بسيطًا لك!




لا ، هذه هي الطريقة القياسية للقيام بذلك. لا ينبغي أن يسبب أخطاء.




إذا كنت لا تمانع في تسجيل الرسالة أيضًا إلى سجل النظام ، فإن الطريقة not_so_ugly هي:

logger -s $msg

يعني الخيار -s: "إخراج الرسالة إلى الخطأ القياسي بالإضافة إلى سجل النظام."




ملاحظة: سأجيب عن السؤال "غير الصادق / المتساهل على المخرج إلى stderr" الذي لم يكن مضللاً / غامضًا (تمت الإجابة عليه من قبل OP).

استخدم وظيفة لإظهار النية ومصدر التنفيذ الذي تريده. على سبيل المثال

#!/bin/bash

[ -x error_handling ] && . error_handling

filename="foobar.txt"
config_error $filename "invalid value!"

output_xml_error "No such account"

debug_output "Skipping cache"

log_error "Timeout downloading archive"

notify_admin "Out of disk space!"

fatal "failed to open logger!"

ويجري error_handling :

[email protected]

config_error() { filename="$1"; shift; echo "Config error in $filename: $*" 2>&1; }

output_xml_error() { echo "<error>$*</error>" 2>&1; }

debug_output() { [ "$DEBUG"=="1" ] && echo "DEBUG: $*"; }

log_error() { logger -s "$*"; }

fatal() { which logger >/dev/null && logger -s "FATAL: $*" || echo "FATAL: $*"; exit 100; }

notify_admin() { echo "$*" | mail -s "Error from script" "$ADMIN_EMAIL"; }

الأسباب التي تعالج المخاوف في OP:

  • أجمل بناء الجملة ممكن (كلمات ذات مغزى بدلا من الرموز القبيحة)
  • يصعب عمل خطأ (خاصة إذا كنت تستخدم البرنامج النصي)
  • إنها ليست أداة Bash قياسية ، ولكنها يمكن أن تكون مكتبة shell قياسية لك أو لشركتك / مؤسستك

أسباب أخرى:

  • الوضوح - يظهر نية للمشرفين الآخرين
  • السرعة - تكون الوظائف أسرع من نصوص shell
  • reusability - يمكن لوظيفة استدعاء وظيفة أخرى
  • configurability - لا حاجة لتحرير النص الأصلي
  • تصحيح الأخطاء - يسهل العثور على الخط المسؤول عن أي خطأ (خاصة إذا كنت تعاني من كمية كبيرة من مخرجات إعادة التوجيه / الفلترة)
  • القوة - إذا كانت إحدى الوظائف مفقودة ولا يمكنك تحرير البرنامج النصي ، يمكنك الرجوع إلى استخدام أداة خارجية تحمل الاسم نفسه (على سبيل المثال ، يمكن أن يكون log_error مستعارًا إلى برنامج تسجيل الدخول على Linux)
  • تبديل التطبيقات - يمكنك التبديل إلى أدوات خارجية عن طريق إزالة سمة "x" للمكتبة
  • لا داعي للقلق - لم يعد عليك أن تهتم إذا ذهبت إلى STDERR أو في أي مكان آخر
  • تخصيص - يمكنك تكوين السلوك مع متغيرات البيئة



read عبارة عن أمر بني مدمج يتم طباعته إلى stderr ، ويمكن استخدامه مثل الارتداد بدون تنفيذ حيل إعادة التوجيه:

read -t 0.1 -p "This will be sent to stderr"

يعتبر -t 0.1 مهلة تعطل الوظائف الرئيسية للقراءة ، حيث يتم تخزين سطر واحد من stdin في متغير.




نظام التشغيل Mac OS X: جربت الإجابة المقبولة واثنين من الإجابات الأخرى وكلها أسفرت عن كتابة STDOUT NOT STDERR على جهاز Mac.

هذه طريقة محمولة للكتابة إلى الخطأ القياسي باستخدام Perl:

echo WARNING! | perl -ne 'print STDERR'



Related

bash

Tags

bash