子プロセスがbashプロンプトを妨げないようにする方法は?

子プロセスがbashプロンプトを妨げないようにする方法は?

関連アプリケーションはDaVinci Resolveです。端末で実行します。閉じると、アプリケーションの「Socket Disconnected」メッセージがターミナル出力に書き込まれます。これでb​​ashプロンプトが正常に表示されます。新しいコマンドの入力を開始しましたが、突然「ソケットの切断」端末に別のメッセージが表示されました。これは私が入力するのを妨げます。次のようになります。

[andrew@unihost ~]$ davinci-resolve
... # Now I exit the application.
Host 'Fusion' Removed
FusionScript Server [37457] Terminated
Socket disconnected
[andrew@unihost ~]$ ls ls Socket disconnected
wtf!!!^C
[andrew@unihost ~]$

ビデオデモ:https://youtu.be/arcCOjrN7kw

なぜこれが起こるのですか?これが起こらないようにする方法はありますか?

私の考えでは、基本プロセスには、基本プロセスが終了した後も持続する子プロセスがあるようです。私が見つけたこれ答え。これは開発者のせいですか?どうすればこの問題を解決できますか(サブプロセスがなくても)?

答え1

予備説明

davinci-resolve私はそれをまったくテストしていません。この回答は一般的に設計されています。


分析する

シェルはdavinci-resolve再び前景に戻り、プロンプトを印刷する前に終了するのを待ちます。明らかに、davinci-resolveメインプロセスが終了し、シェルが応答した後、メインプロセスの一部のサブプロセス(または後続のプロセス)が不要なメッセージを印刷します。


解決策

解決は簡単かもしれません。

davinci-resolve | cat

ヒントは、catパイプに書き込むすべてのプロセスがパイプの端を閉じるまで終了しないことです。問題のある子は、おそらくメインからstdoutを継承して待機しますdavinci-resolvecat通常、これは不要なメッセージがstderrまたはで印刷されている場合にも機能します/dev/tty(つまり、私たちのメッセージをバイパスしますcat)。他の場所で印刷していても、子供がパイプを開いたままにすることが重要です。

欠点もあります:

  • catパイプライン全体の終了状態はではなくから来ますdavinci-resolve一部のシェルでは、次のことができます。

  • 前者は通過し、後者は通過しないため(およびその子)のstdoutとstderrはdavinci-resolve同期されません。cat

  • Ctrl+場合は、c印刷が終了する前に他のプロセスを終了する可能性があるため、cat実際に見たい出力を見逃す可能性があります。また、問題のあるメッセージがstderrに印刷されると、おそらくプロンプトを表示した後にとにかく印刷されます。

    +免疫を作ることができますcatCtrlc

    davinci-resolve | sh -c 'trap "" INT; exec cat'
    
  • 問題のあるプロセスは早期に終了するか、標準出力をリダイレクトする可能性がありますが、まだ標準エラーで印刷されます。この場合は待つ必要はありませんcat

  • 問題のあるプロセスは持続するように設計されている可能性があり、不要なメッセージがプロセスが終了したという意味ではありません。このプロセスがまだ存在し、パイプを開いたままにしておけば、私たちcatの意志も存在し続けます。davinci-resolveバグがない限り、子孫が残る可能性はほとんどありませんが、一般的にそのようなことが発生する可能性があります。

何らかの理由でstdoutを渡したい場合があります。そして標準エラーは通過しますcat。 Immunity cat+はまだ良いアイデアですCtrlc

  davinci-resolve 2>&1 | sh -c 'trap "" INT; exec cat'

これで、stderr of(およびその子)とstdoutを区別できなくなり、両方ともdavinci-resolvestdoutcatを渡します。とにかくターミナルでミックスしたいので問題ありません。個別にリダイレクトまたはキャプチャするには、設定を放棄して最初から始める必要があります。

問題のあるプロセスが早期に終了するか、stdoutとstderrをリダイレクトし、不要なメッセージを/dev/ttyはい)。この状況で私たちができることは何もありませんcat


シェル機能

私たちのソリューションはシェル関数として実装できます。

davinci-resolve() {
   command davinci-resolve "$@" 2>&1 | sh -c 'trap "" INT; exec cat'
}

この関数は引数渡しをサポートしますdavinci-resolveが、終了状態はプロセスでcatはなくから来ます(質問がある場合を参照)。davinci-resolveすでにリンクが提供されています。アイデア)。

答え2

control-lと入力して画面を消去できます。これにより、「ソケットの切断」メッセージが消去されますが、コマンドプロンプトと部分的に作成されたコマンドはそのまま残ります。残念ながら、davinci-resolveの出力も消去されます。

答え3

基本プロセスが終了した直後に「ソケットの切断」というメッセージが表示されたら、コマンドに追加して; sleep 2それをシェルエイリアスに入れることができます。これは基本的に新しいコマンドをすぐに入力しないようにするための方法です。これを行うには、次を追加します。

alias davinci-resolve="davinci-resolve; sleep 2"

あなたの.bashrcに

答え4

バックグラウンドプロセスは実際にシェルを妨げず、画面に落書きをしているだけで、バックグラウンドプロセスの出力とシェルが混在します。

この問題を解決する方法はいくつかあります。

  • ファイルリダイレクトなどの機能を使用して、端末からメッセージを削除したりnohupファイルに保存したりできます。
  • この横説説を無視して入力を続けるか、何も入力しなかった場合はEnterを押すと新しいプロンプトが表示されます。
  • バックグラウンドプロセスから送信されたメッセージを読み取った後、コマンドライン編集キー入力を使用して、入力した内容を更新して再読み込みできるようにします。通常の端末モードでは、Ctrl-Rこれが行われます。 Bashなどの他の多くのアプリケーションでは、Ctrl-L画面が消去され、プロンプトと入力した内容が再印刷されます。
  • 専用ウィンドウでアプリケーションを実行し、グラフィックウィンドウシステムの機能を使用して、その出力によって汚染されていない他のウィンドウを開くことができます。 :) (このような騒々しいアプリケーションを実行するために、隣に小さなウィンドウを残しました.)
  • アプリケーションを終了した後にこれが発生し、停止したいワーカースレッドが残っている場合は、ps -t端末で現在実行中のエントリを表示するためにそのスレッドを見つけて終了できます。

関連情報