إرجاع قيمة واحدة من وظيفة البرنامج النصي shell
-
01-10-2019 - |
سؤال
مثال:
#!/bin/sh
a() {
R=f
ls -1 a*
[ "$?" == "1" ] && { R=t; }
echo $R
}
r=`a`
echo $r
$r
يحتوي على t
أو f
ولكن أيضا إخراج ls
يأمر.
قد أكتب ls -1 a* >/dev/null 2>/dev/null
, ، ولكن إذا كان هناك نص أكثر تعقيدًا يمكن أن يؤدي إلى أخطاء.
هل هناك أي طريقة لإرجاع قيمة واحدة من a()
?
المحلول
يمكن أن تُرجع وظيفة shell قيمة رقمية. فكر في 0 و 1 بدلاً من "F" و "T"
#!/bin/sh
a() {
R=0
ls -1 a*
[ "$?" == "1" ] && { R=1; }
return $R
}
a
r=$?
echo $r
سيظل هذا يكتب الإخراج من ls -1 a*
والتي ربما لا تزال تريد التخلص منها ، ولكن قيمة r
سيكون إما 0 أو 1 ولن يتضمن الإخراج.
الأمثلة الأخرى لإعادة توجيه الإخراج إما من خط أو كتلة كاملة جيدة ، وكما اقترح آخرون ، يجب أن تتعرف على طرق أخرى لاختبار الظروف (لكنني كنت أفترض ls
كان نوعا من مثال تعسفي)
نصائح أخرى
ليس عليك استخدام ls
للتحقق من وجود ملفات تبدأ بال a
. فقط استخدم القشرة
a() {
shopt -s nullglob
ret="f"
for file in a*
do
ret="t"
break
done
echo "$ret"
}
يمكنك وضع إعادة توجيه على قائمة الأوامر:
{ command1 command2 } >/dev/null
إذا كنت في مرحلة ما من البرنامج النصي لا تريد أي إخراج من أوامر لاحقة ، فيمكنك إعادة توجيه إخراج القشرة باستخدام exec
مدمج:
echo interesting exec >/dev/null echo boring
لاحظ أن هذا يستمر حتى نهاية البرنامج النصي ، ليس فقط حتى نهاية الوظيفة. هذا يعتني بالأوامر بعد الاهتمام ولكنه ليس من قبل.
هناك طريقة لإعادة تأثير exec /dev/null
, ، باستخدام معالجة واصف الملف. لا أوصي به بالضرورة ، لأنه قد يكون من الصعب العمل في الممارسة العملية. تتمثل الفكرة في نقل كل ما هو متصل بالإخراج القياسي إلى واصف مختلف ، ثم إعادة توجيه الإخراج القياسي إلى ملف مختلف ، وأخيراً نقل الإخراج القياسي الأصلي إلى الإخراج القياسي.
{ exec 3>&1 # duplicate fd 3 to fd 1 (standard output) exec >/dev/null # connect standard output to /dev/null echo boring exec 1>&3 # connect standard output back to what was saved in fd 3 echo interesting exec >/dev/null # connect standard output to /dev/null again echo more boring } 3>/dev/null # The braced list must have its fd 3 connected somewhere, # even though nothing will actually be written to it.
a() {
ls -1 a* > /dev/null
[ "$?" == "0" ] && echo t || echo f
}
r=`a`
echo $r
النظر في استخدام [-f filename] واختبارات الملف الأخرى كذلك.