テスト実行エンジン用の一時的なコンテナー/VM の (リモート) シェルで、本質的に任意のコマンドを実行する必要があります。場合によっては、これらがバックグラウンド プロセスをリークし、コマンド全体がハングすることがあります。これは、次の単純なコマンドに要約できます。
$ sh -c 'sleep 30 & echo payload'
payload
$
ここで、backgroundedsleep 30
はリークされたプロセスの役割を果たし (実際には のようなものになりますdbus-daemon
)、echo は実際に実行したいものです。ここsleep 30 & echo payload
では、アトミックな不透明なコマンドの例と見なす必要があります。
上記のコマンドは問題なく、シェルとスリープの stdout/stderr が PTY であるため、すぐに戻ります。ただし、コマンドの出力をパイプ/ファイルにキャプチャすると (テスト ランナーは、結局のところ、すべてをログに保存する必要があります)、コマンド全体がハングします。
$ sh -c 'sleep 30 & echo payload' | cat
payload
# ... does not return to the shell (until the sleep finishes)
現在、これは、stdout/err の FD を から決定し、同じ stdout/stderr を持つすべてのプロセスを/proc/$$/fd/{1,2}
反復して強制終了する、かなりばかげて複雑なシェル マジックで修正できます。ls /proc/[0-9]*/fd/*
しかし、これには多くの壊れやすいシェル コードと高価なシェル文字列の比較が含まれます。
これらのリークされたバックグラウンド プロセスをよりエレガントでシンプルな方法でクリーンアップする方法はありますか? setsid
助けにならない:
$ sh -c 'setsid -w sh -c "sleep 30 & echo payload"' | cat
payload
# hangs...
リークされたプロセス (dbus-daemon など) はしばしば自身を設定するため、プロセス グループ/セッションを強制終了するだけでは不十分であることに注意してください。
PS私は、これらの環境ではPOSIXシェルまたはbashしか想定できません。Python、Perl などはありません。
前もって感謝します!