كيف يمكنني صخرة الأخطاء والمقاطعات في جنو
سؤال
أتساءل عما إذا كانت هناك طريقة لتنفيذها trap
في جنو make
, ، على غرار ذلك بنيت في BASH
?
إذا ضغط المستخدم CTRL-C
, ، أو إذا make
نفسها فشل (مخرج غير صفر)، أود أن استدعاء هدف معين أو ماكرو معين.
المحلول
لا، فإن معالجة إشارة جنو يترك بالفعل الكثير مما هو مرغوب فيه. من داخل معالج الإشارة، فإنه يدعو وظائف مثل printf
ليس من الآمن أن يتم استدعاؤه من داخل معالج إشارة. لقد رأيت هذه المشاكل السبب، على سبيل المثال .DELETE_ON_ERROR
القواعد لا تعمل دائما إذا stderr
يتم إعادة توجيهها إلى stdout
.
على سبيل المثال، في مربع Centos 7.4:
إنشاء ما يلي
Makefile
:.DELETE_ON_ERROR: foo: touch $@ sleep 10
افتحه
vim
و اهرب:make
,- بينما ينام، ضرب كنترول-جيم
VIM / جعل المطبوعات
Press ENTER or type command to continue
touch foo
sleep 10
^C
shell returned 130
Interrupt: Press ENTER or type command to continue
تم إرسال إشارة المقاطعة، ولكن foo
لا يزال موجودا.
نصائح أخرى
في هذه المرحلة الزمنية، لا يملك جنو دعما أصليا.
هناك حل ملائم موثوق به:
.PHONY: internal-target external-target
external-target:
bash -c "trap 'trap - SIGINT SIGTERM ERR; <DO CLEANUP HERE>; exit 1' SIGINT SIGTERM ERR; $(MAKE) internal-target"
internal-target:
echo "doing stuff here"
هذا يمسك الانقطاعات والإنهاء وأي رموز خروج غير صفرية.
لاحظ ال $(MAKE)
تتجاوز cmdline وجعل الخيارات التي تنتقل إلى توضح.
في فخ:
- معالج فخ واضح (مع -)
- هل التنظيف
- الخروج من حالة خروج غير صفرية، لذلك قم بإنشاء أدوات الأتمتة الإبلاغ عن الإنشاء الفاشل.
delete_on_error لا يعمل من أجل الدلائل، لذلك هذا هو مفتاح التنظيف بعد mktemp -d
, ، علي سبيل المثال
يحل محل <DO CLEANUP HERE>
مع cmd صالح.
نسخة مبسطة من إجابة @ Kevinf التي تبدو جيدة بما يكفي للحالات الأساسية:
run:
bash -c "trap 'docker-compose down' EXIT; docker-compose up --build"
(هذا المثال هو لسبب ما: docker-compose up
لا يقول
عند خروج الأمر، يتم إيقاف جميع الحاويات.
لكنها لا rm
حاويات توقف مثل docker run --rm
سوف، حتى لا يزال بإمكانك رؤيتهم docker ps -a
.)
لا تدعمها، ولكن باستخدام الحيل باش، يمكنك تحقيق شيء مشابه.
default: complete
complete: do_mount
echo "Do something here..."
do_mount:
mkdir -p "$(MOUNTPOINT)"
( while ps -p $$PPID >/dev/null ; do \
sleep 1 ; \
done ; \
unmount "$(MOUNTPOINT)" \
) &
mount "$(MOUNTSOURCE)" "$(MOUNTPOINT)" -o bind
سيتم تشغيل "إلغاء الحمل" بعد اكتمال "جعل". عادة ما يكون هذا حلا مرضيا إذا كنت تحاول تنظيف العمليات التي قد تحدث أثناء الإنشاء ولكن لا يتم تنظيفها بشكل طبيعي على الخروج "جعل".
رقم بقدر ما أعرف أنه لا توجد وظيفة مثل هذه الوظيفة.
جعل تنتج رموز الإرجاع. بقدر ما أستطيع أن أتذكر الآن، فإنه يعود 0 للنجاح، 2 للفشل (يرجى التحقق من الوثائق). لذلك، هل سيكون ذلك كافيا بالنسبة لك لف جعل داخل برنامج نصي شل على سبيل المثال؟