web-dev-qa-db-ja.com

Bash:control-cがプロセスを強制終了しない場合の対処方法、オン/オフボタンの解決策はありますか?

この質問の完全なタイトルは次のとおりです。

Bash:bashスクリプトに別のプロセスを呼び出すループが含まれているために、control-cがプロセスを強制終了しない場合の対処方法:電源ボタンのオン/オフの解決策はありますか?

この質問のタイトルはかなり自明ですが、詳細は次のとおりです。

別のプログラムを呼び出すbashスクリプトを実行しています。 (別のプログラムを実行/実行します。)

このプログラムはデータ/カーブフィッティングプログラムであり、CTRL-Cで中断することはできません。しかし、これを読んだところ post で、CTRL-\を使用してそれを強制終了できることがわかりました

仮説的思考...

したがって、キーボードをマッシュしてCTRLキーを押しながら\キーをマッシュするだけで可能です[〜#〜]しかし[〜#〜]昨日、本当に高価なメカニカルキーボードを購入し、「マッシュ」にしたい別の安価なキーボードを購入するのに十分なお金がない場合(これらの10 ^ 6キーを使いたくないので) -光沢のある新しいメカニカルキーボードが磨耗する前に押すか、または家が古いキーボードを見つけるのに十分な時間がないため、家が非常に乱れている(混乱している)またはチップパン火災が同時に発生するなどの緊急事態が発生したため...

また、ループがこのフィッティングプログラムを呼び出しており、おそらく1000個のデータファイルをフィッティングしていると考えてください。\キーを1000回押すと、時間がかかる可能性があります。

ハイパースペースの考え...

あるいは; bashスクリプトに誤りがあり、それが実際に無限ループを実行している場合はどうなりますか?

この状況で親スクリプトの実行を停止するにはどうすればよいですか?コンピュータのプラグを抜くか、電源ボタンを10秒間押して電源を切るか、またはチップパンの火の中に投げて動作を停止することができますが、これらの解決策は、発生する可能性のあるデータの損失のために無意味なようです。

理論的には、システムモニターを実行してbashプロセスを終了することもできますが、そのようなプロセスがすべて同じ名前である場合、これを見つけるのは難しいかもしれません...さらに、単一のコアコンピューター、またはたとえばNコアのマルチコアコンピュータで、100%CPUを使用しようとするNプロセスを実行している。または、たった1つのプロセスが4 GBを超えるRAMを使用しているため、コンピューターがそのために非常に遅い...少なくとも、今のところシステムモニターを実行するには遅すぎる。この後の次善の策は、CTRL-ALT-F1を押してrootとしてログインし、ps -A、次にkill PID...を使用して問題のあるbashの親を見つけることです。ただし、これには数分かかる場合がありますコンピューターの負荷が非常に高いため、スワップのために継続的に書き込みを行っている場合は、.

SIG TERM exec cpu_broken.sh;再招集;画面をクリアします。 think_processesをクリアします。続行...

より良い解決策はありますか?

1
user3728501

したがって、基本的にはすべてにアクセスできないスクリプトを実行し、それを停止するための迅速かつ簡単な解決策が必要です。パワーサイクリングの代わりに、 SYSRQ キー(それは同じです PRTSC 多くの場合キーを押して)、1つずつ押します R、 E、 ISUB。基本的に、これは実行中のすべてのプロセスを強制終了してシステムを再起動する安全な方法です。

その代わりにSudo nano /proc/sysrq-trigger、そのファイルにbを書き込んで保存します。システムはすぐに再起動します

詳細: https://en.wikipedia.org/wiki/Magic_SysRq_key

2

通常、tophtopなどを使用してプロセスを見つけて強制終了できます(または、プロセスの名前またはPIDがわかっている場合は、killallpkillなど)。たとえば、topを使用して、ターミナルから実行されているスクリプトを選択し、 k+Enter

enter image description here

それがうまくいかない場合、 k+9+Enter SIGKILLシグナルを使用する必要があります。 SIGKILLは、プロセスをすぐに強制終了することを要求し、SIGTERMのようにプロセスがリソースのクリーンアップを完了するのを待ちません。 Ctrl+C SIGTERMが行うように、プロセスはSIGINTを送信してプロセスを中断するだけです。

ツリービューの使用( t)htopでは、スクリプトの親プロセスを特定し、それらを強制終了して、ループが実行されないようにすることもできます。

以下も参照してください:

1
Wilf

プロセスグループ全体を強制終了する必要があります。プロセスグループID(PGID)は、グループを開始したプロセスのPIDです。プロセスグループを強制終了するには、プロセスグループを開始したプロセスのPID、つまりそれをすべて開始したスクリプトまたはコマンドを見つける必要があります。構文は次のとおりです。

kill -- -PGID

例えば:

kill -- -1234

ここで1234はPGID(プロセスグループID)です。

これにより、プロセスグループ内のすべてのプロセスにSIGTERMが送信されます。異なる信号を送信するには、例えばSIGKILL(9)は:

kill -9 -1234

PGIDを見つける方法:

できるよ:

ps -eo 'pid,ppid,pgid,cmd'

これにより、PID、PPID(親プロセスID)、PGID、およびプロセス名が表示されます。

これで、grepまたは他の適切な方法を使用してPGIDを見つけ、前述の方法でPGIDを強制終了できます。

PPIDを表示するコマンドを作成した理由は、pkillによるPPIDマッチングに基づいてプロセスを強制終了することもできるためです。

pkill -P PPID

例えば:

pkill -P 6789

この方法を使用すると、すべての親(および子プロセス)を見つけて強制終了する必要があるため、私の考えでは、プロセスツリー全体を強制終了する方が、すべてを強制終了したい場合に適しています。

1
heemayl