始めたら非同期(「バックグラウンド」)プロセスでは、新しいプロセスのPIDを含むいくつかの情報が、プロセスが実行される前に端末に印刷される。
$ sleep 3 &
[1] 8217
$
[1] + done sleep 3
$
最初にこのような情報(具体的にはPID)を出力する方法はありますか?すべて非同期的に開始されたプロセスだけでなく、プロセスもありますか?
背景
これをやりたい理由は、日常業務設定の特性により、次のようなことが頻繁に発生するためです。同期長期実行プロセスは応答しませんCtrl-C
。 (常にこれらのプロセスを「長期実行」にする理由は、予想よりもはるかに多くの出力を生成することです。)これらのプロセスを停止する最も信頼性の高い方法は、別のウィンドウからアクセスすることであり、それを使用することをお勧めkill -9
します。目的に応じてPIDを簡単に使用できます。
更新:元の投稿では、これがCtrl-Z
オプションではないことを見落としました。 (Emacsで実行されるシェルを開発しているので、Ctrl-Z
Emacsを一時停止するだけです。)
答え1
〜のようにスティーブンキットが説明します。、zshにPIDを印刷させるのは非常に難しいでしょう。しかし、他の方法でも情報を得ることができます。
Ctrl+を押してZプロセスを一時停止すると、zshはそのPIDを表示します。殺したい場合は、まずCtrl+を押してC直接殺します。Ctrl+C失敗した場合は、Ctrl+ \「より厳しい」シャットダウンを試みます。 (Ctrl+C通常、プログラムに現在のタスクを停止し、ユーザーに制御を返すように指示するSIGINTを送信します。Ctrl+\通常、プログラムが重大にクラッシュするように指示するSIGQUITを送信します。)Emacsでもこれを実行できます。シェルモードで、C-c C-z
pass C-z
to Terminal、C-c C-c
pass C-c
、C-c C-\
passを押しますC-\
。 Termモードでは、C-z
合計はC-\
直接渡されますが、C-c C-c
単一C-c
。
プロセスが端末設定を変更した場合、または信号をブロックした場合は、そのプロセスを見つけて終了する便利な方法は、端末を介することです。端末が何であるかを調べてください。tty
端末内でコマンドを使用してこれを実行できます。この部分をプロンプトまたは端末のタイトルの一部として含めることができます(私は端末のタイトルに入れました)。 Emacsは端末のタイトルを表示しませんが、次の式を評価して情報にアクセスできるようにします。
(process-tty-name (get-buffer-process (current-buffer)))
シェルモードを含むほとんどのモードで式を評価するには、M-:
式を入力してから入力します。用語モードで式を入力しC-c M-x eval-expression RET
て入力します。この機能を頻繁に使用する場合は、そのモードのキーに次のコマンドをバインドします。
(defun buffer-process-tty-name ()
(interactive)
(let ((tty (process-tty-name (get-buffer-process (current-buffer)))))
(if (interactivep) (message "%s" tty))
tty))
端末名がわかったら、またはを使用してその端末に接続されているプロセスを一覧表示できps -t pts/42
ますpgrep -t pts/42
。
答え2
この情報を記録し、さらに詳しく研究する方法がないようで、正しく設計することが難しいです(最初はこれも実装しにくいと思ったが、イルカチョこの問題を解決しました)。
実装の問題は、情報を正しい場所に記録することだと思います。シェルが子プロセスを起動したときに子プロセスを分岐して実行します(自己プロセスに置き換えることができる場合を除く)。この場合、分岐しません。分岐すると、プロセスが繰り返されます。あるコピーはfork()
呼び出しから戻りコード0を取得し、これは子プロセスであることを示し、もう一方のコピーは子プロセスの識別子を取得し、これは親プロセスであることを示します。子プロセスは親プロセスのファイル記述子を継承するため、設定する前に自分のpidを記録できますexec()
。
デザインの問題は、何を記録するかを選択することです。シェルで開始されたすべてのプロセスを記録すると、無関係なログがたくさん残ります。例えば建築のヒントに関連するプロセスについて! 「実際の」コマンドの場合でも、パイプや他の複合コマンドについて何を記録するかを決定する必要があります。そして、一貫性のために、組み込みコマンドまたは子としてシェル置換自体の場合にいくつかの記録が必要です。手動で行わない限り、対話式シェルではこれは発生しませんexec
。
これについて詳しくは、addproc()
とprintjobs()
をご覧ください。jobs.c
zexecve()
exec.c