我想知道是否有一種方法可以在GNU make
中實現trap
,與BASH
中內置的類似?如何在GNU make中捕獲錯誤和中斷?
如果用戶按CTRL-C
,或者make
本身失敗(非零退出),我想調用一個特定的目標或宏。
我想知道是否有一種方法可以在GNU make
中實現trap
,與BASH
中內置的類似?如何在GNU make中捕獲錯誤和中斷?
如果用戶按CTRL-C
,或者make
本身失敗(非零退出),我想調用一個特定的目標或宏。
不可以。GNU make的信號處理已經有很多不足之處了。從它的信號處理程序中,它調用如printf
這樣的函數,這些函數在信號處理函數中不安全。我已經看到這個原因問題,例如.DELETE_ON_ERROR
規則並不總是運行,如果stderr
重定向到stdout
。
例如,在一個CentOS 7.4框:
創建以下Makefile
:
.DELETE_ON_ERROR:
foo:
touch [email protected]
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
仍然存在。
你有一些`.DELETE_ON_ERROR`不起作用的例子嗎?這是執行中的錯誤嗎? – 2017-10-03 06:33:12
@HakanBaba添加「詳細信息」。 – andrewdotn 2017-10-03 19:59:47
不,據我所知,沒有這樣的功能。
make會產生返回碼。據我現在可以記住,它成功返回0,失敗2(請檢查文檔)。因此,例如,是否將make包裝在shell腳本中就足夠了?
我可以做到這一點,但如果可能的話,儘量避免它,它是獨立的,我試圖*保持這種方式。 – Cyrus 2009-06-10 11:07:35
Make不支持它,但使用BASH技巧可以完成類似的操作。
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
「unmount」將在「make」完成後運行。如果您試圖清理構建過程中可能發生的操作,但在「make」退出時沒有正常清理,通常這是一個令人滿意的解決方案。
在這個時候,GNU make沒有本地支持。
然而有一個可靠的解決方法:
.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覆蓋並使選項傳遞給submake。
在陷阱:
DELETE_ON_ERROR不爲目錄工作的,所以這是mktemp -d
後清理鍵,例如
與有效的CMD更換<DO CLEANUP HERE>
。
除了回聲中的嵌套引用,這當然是非法的,這似乎不起作用,至少對於我想要完成的。人們應該如何使用它?假設我的makefile只有一個具有睡眠和觸摸的目標,如@andrewdotn示例(忽略.DELETE_ON_ERROR),那麼如何修改它以使用此解決方法? – Davide 2017-10-06 18:44:16
@ kevinf的答案的簡化版本,這似乎不夠好基本情況:
run:
bash -c "trap 'docker-compose down' EXIT; docker-compose up --build"
(這個例子是有原因的:docker-compose up
不說
當 命令退出時,所有容器被停止。
但它不會rm
停止的contai如docker run --rm
會,所以你仍然可以看到他們與docker ps -a
。)
+1的有趣的問題,即使你在做什麼聽起來像一個壞主意。 – finnw 2009-06-10 07:32:13