別のバイナリを実行するときに、bash EXITトラップを実現するにはどうすればよいですか? 質問する

別のバイナリを実行するときに、bash EXITトラップを実現するにはどうすればよいですか? 質問する

EXITバッシュトラップを使いたいそしてexec新しいプロセスの生成を避けるために使用します。これは可能ですか?

あれは、

#!/bin/bash
touch $0.$$
trap "rm -v $0.$$" EXIT
/bin/echo Hello

$0.$$bashのEXITトラップを使用して一時ファイルを削除します

#!/bin/bash
touch $0.$$
trap "rm -v $0.$$" EXIT
exec /bin/echo Hello

トラップを「起動」することはありません (完了後に からのメッセージやrmファイル$0.$$が存在しません)。

もちろん、トラップが発動できないのは、bashが制御不能になった後だからであるexec。これを機能させる方法はあるだろうか?そして使用ですかexec? これは確かに実用的な問題というよりも好奇心から来ています。

ベストアンサー1

一般的には、いいえ。あなたが述べた理由により、これは不可能です。

それは退屈な答えです。回避策のオプションを見てみましょう。

exec セマンティクスを重視し、複数のプロセスの開始をあまり気にしない場合は、任意の実行可能ファイルに対して次の操作を実行できます。

{ while kill -0 $$; do sleep 5; done; rm "$0.$$"; } &
exec ./file

これによりexec、ファイルが別のプロセスによってポーリングされ、完了したらクリーンアップが実行されます。

フォークを避けたい場合、別のシェルスクリプトを実行するには次のようにします。

exec bash --rcfile <(echo 'trap "..." exit') -i ./file

execファイルに を追加し、その後クリーンアップを実行します (スクリプトがexecトラップを上書きしない限り)。新しいプロセスは開始されません。sourceの代わりに を使用するとexec、ほぼ同じ効果が得られます。

trap "..." exit
source ./file

本当にハックしたい場合は、LD_PRELOADを使用してオーバーライドしexit(3)、選択したコマンドを実行することができます。

#include <stdlib.h>

void exit(int c) {
    char* cmd = getenv("EXIT");
    char *argv[] = { "bash", "-c", cmd, NULL };
    char *envp[] = { NULL };
    execvpe("bash", argv, envp);
}

これをライブラリとしてコンパイルできます:

$ gcc -shared -fPIC foo.c -o libfoo.so

そして、それを任意の動的にリンクされた実行可能ファイルにプリロードします。

$ LD_PRELOAD=./libfoo.so EXIT='echo "This is a hack"' ls *foo*
foo.c  libfoo.so
This is a hack

これらのハックは楽しいですが、現実世界で必要になることはほとんどありません。よりシンプルで、より優れた、より標準的な解決策は、単にハックしないことですexec

おすすめ記事