に組み込まれているのと同様にtrap
、 GNUで実装する方法があるかどうか疑問に思っていますか?make
BASH
ユーザーが を押した場合CTRL-C
、またはそれ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 オーバーライドと make オプションが submake に渡されることに注意してください。
トラップ時:
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
。)
いいえ。GNU make のシグナル処理には、まだ多くの要望が残されています。printf
シグナル ハンドラー内から、シグナル ハンドラー内から呼び出すのが安全ではないような関数を呼び出します。これが原因で問題が発生するのを見てきました。たとえば、が にリダイレクトされた.DELETE_ON_ERROR
場合、ルールが常に実行されるわけではありません。stderr
stdout
たとえば、CentOS 7.4 ボックスの場合:
以下を作成しますMakefile
。
.DELETE_ON_ERROR:
foo:
touch $@
sleep 10
で開いてvim
実行し:make
、
Vim/make プリント
Press ENTER or type command to continue
touch foo
sleep 10
^C
shell returned 130
Interrupt: Press ENTER or type command to continue
Make に割り込みシグナルが送信されましたが、foo
まだ存在しています。
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
「メイク」が完了すると、「アンマウント」が実行されます。これは、ビルド中に発生する可能性がある操作をクリーンアップしようとしているが、「make」終了時に正常にクリーンアップされない場合、通常は満足のいく解決策です。
いいえ。私が知る限り、そのような機能はありません。
makeは戻りコードを生成します。私が今覚えている限り、成功した場合は0、失敗した場合は2を返します(ドキュメントを確認してください)。したがって、たとえばシェルスクリプト内にmakeをラップするだけで十分でしょうか?