実行されないアプリケーションを起動しましたが、まだ実行中なので削除できません。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.txt
、ps ax
は のコマンドを示す行を表示しますvi raven.txt
。同様に、 のようなコマンドを入力するとgrep snappr
、ps ax
は のコマンドを示す行を表示しますgrep snappr
。そして、その出力をps
にパイプするとgrep snappr
、grep
は行を見つけます。それは自分自身を表現している. と入力すると
$ ps ax | grep snappr | awk '{print $1}'
繰り返し実行すると、毎回異なる番号が出力されます ( の PID を出力しているため、コマンドを実行するたびにgrep
新しい一意のプロセスが取得されます)。grep
最後に、次kill
の点を考慮してください。コマンドは、引数が判明するまで実行できません。引数が判明するには、パイプラインが完了している必要があります。これは、 が終了している必要がある$(ps ax | grep snappr | awk '{print $1}')
ことを意味します1。したがって、 にはプロセスの PID が与えられますが、それはプロセスが終了した後のみです。したがって、当然、「そのようなプロセスはありません」と報告されます。grep
kill
grep
grep
おそらく、実行中のプロセスがないことを述べておくべきだったかもしれませんsnappr
。 実行中のプロセスがあった場合、最初のコマンドは の PIDsnappr
と の PID の2 つの数値を出力しますgrep snappr
。snappr
が実行中の場合、コマンドはほぼ正常に実行を開始する可能性があります。つまり、コマンドは必要な処理を実行しますが、エラー メッセージも表示されます。 がsnappr
PID 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してみてください。ps
grep
awk
pkill
; 面倒なことはなく、すぐに使えるプロセス名に基づいてターゲットを設定します。
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 シェルを強制終了してしまう可能性があります。snapper
snapper
しかし、そうは言っても、人生を楽にして走ってみてはいかがでしょうかpkill
このような:
sudo pkill snappr
snappr
これにより、複雑なコマンド ラインの操作をすることなく、接続されているすべてのプロセスを強制終了できます。