タスク マネージャーでは実行中であるにもかかわらず、表示されないプロセスを終了できない

タスク マネージャーでは実行中であるにもかかわらず、表示されないプロセスを終了できない

実行されないアプリケーションを起動しましたが、まだ実行中なので削除できません。PID を印刷することはできますが、それを使用しているプロセスを強制終了することはできません。

~ $ ps ax | grep snappr | awk '{print $1}'
70824
~ $ kill $(ps ax | grep snappr | awk '{print $1}')
-bash: kill: (70832) - No such process

答え1

2 回の試行で 2 つの異なる PID が得られたことに気付きましたか?

次のようなことを考えてみてください。 のようなコマンドを入力するとvi raven.txtps axは のコマンドを示す行を表示しますvi raven.txt。同様に、 のようなコマンドを入力するとgrep snapprps axは のコマンドを示す行を表示しますgrep snappr。そして、その出力をpsにパイプするとgrep snapprgrepは行を見つけます。それは自分自身を表現している. と入力すると

$ ps ax | grep snappr | awk '{print $1}'

繰り返し実行すると、毎回異なる番号が出力されます ( の PID を出力しているため、コマンドを実行するたびにgrep新しい一意のプロセスが取得されます)。grep

最後に、次killの点を考慮してください。コマンドは、引数が判明するまで実行できません。引数が判明するには、パイプラインが完了している必要があります。これは、 が終了している必要がある$(ps ax | grep snappr | awk '{print $1}')ことを意味します1。したがって、 にはプロセスの PID が与えられますが、それはプロセスが終了した後のみです。したがって、当然、「そのようなプロセスはありません」と報告されます。grepkillgrepgrep

おそらく、実行中のプロセスがないことを述べておくべきだったかもしれませんsnappr。 実行中のプロセスがあった場合、最初のコマンドは の PIDsnapprと の PID の2 つの数値を出力しますgrep snapprsnapprが実行中の場合、コマンドはほぼ正常に実行を開始する可能性があります。つまり、コマンドは必要な処理を実行しますが、エラー メッセージも表示されます。 がsnapprPID 42097 で実行中で、grep snapprが PID 70848 で実行されている場合、killコマンドは になりkill 42097 70858、 を強制終了し、存在しないプロセスを強制終了しよsnappr うとするためエラー メッセージが表示されます。grep

おそらく、これを改善したいと思うでしょう。私が 20 年前に考案したお気に入りの方法は、grepを に変更することです。grep "[s]nappr"これは一致しますsnapprが、それ自体には一致しません。もう 1 つの方法は、pgrepではなくを使用することですps | grep


1あるいは、 が単に stdout を閉じたawkだけでも終了する可能性がありますgrep。これは、*nix プログラムとしては非常に珍しい動作です。

答え2

短い回答

パイプしてパイプして、そのようにしてkillするためsnapprにBashの面倒な手続きを踏まないでください。代わりに、次のようにkillしてみてください。psgrepawkpkill; 面倒なことはなく、すぐに使えるプロセス名に基づいてターゲットを設定します。

sudo pkill snappr

より長い回答

あまり明確ではないスナッパーシステム プロセス レベルで動作しますが、親プロセス ID ではなく子プロセス ID のみを取得していることが問題となる可能性があります。

実際、プロセスIDを取得するために使用しているメソッド( )は、親か子かに関係なく、ps ax | grep snappr | awk '{print $1}'接続されているプロセスIDのリスト全体を返すと思います。それを使用してsnapprかもしれない子プロセス ID にすぎないプロセス ID を 1 つ強制終了しますが、親 ID は引き続きアクティブであり、それを補うために別の子プロセスを「生成」することができます。

したがって、おそらく、次のようにして、入力したプロセス ID の最終的な親 ID を取得して、それに基づいて操作することができます。これは、どのように機能するかについての簡単な概念実証です。

ps -p [process ID] -o ppid=

この単純なコマンドを Bash で実行すると、 に入力した子プロセス ID の親プロセス ID が返されます[process ID]。したがって、子 ID4567の親プロセス ID が の場合、123コマンドは次のようになります。

ps -p 4567 -o ppid=

そしてそれは戻ってくるだろう123

そうは言っても、これは迷子のプロセスを処理する危険な方法になる可能性があります。スクリプトが の実際の親プロセス ID を取得すると、そのプロセス ID の親は実際には自分の Bash シェルである可能性があるからです。そのため、プロセスを実行したまま によってシステムから切断されるsnapper代わりに、誤って Bash シェルを強制終了してしまう可能性があります。snappersnapper

しかし、そうは言っても、人生を楽にして走ってみてはいかがでしょうかpkillこのような:

sudo pkill snappr

snapprこれにより、複雑なコマンド ラインの操作をすることなく、接続されているすべてのプロセスを強制終了できます。

関連情報