Wie kann die PID zu Beginn *jedes* Prozesses auf dem Terminal ausgedruckt werden?

Wie kann die PID zu Beginn *jedes* Prozesses auf dem Terminal ausgedruckt werden?

Wenn ich einasynchron("Hintergrund-")Prozess werden einige Informationen, einschließlich der PID des neuen Prozesses, auf dem Terminal ausgegeben, bevor der Prozess ausgeführt wird. Zum Beispiel

$ sleep 3 &
[1] 8217
$ 
[1]  + done       sleep 3
$ 

Gibt es eine Möglichkeit, solche Informationen (vor allem die PID) am Anfang desjedenProzess, nicht nur diejenigen, die asynchron gestartet werden?


Hintergrund

Der Grund dafür ist, dass es aufgrund der Besonderheiten meines Arbeitsalltags oft vorkommt, dass einsynchronEin lang laufender Prozess reagiert nicht auf Ctrl-C. (Was diese Prozesse ausnahmslos „lang laufend“ macht, ist, dass sie viel mehr Ausgabe erzeugen, als ich erwartet hatte.) Der sicherste Weg, einen solchen Prozess zu stoppen, besteht darin, ihn kill -9von einem anderen Fenster aus zu starten, und es wäre schön, seine PID dafür sofort zur Hand zu haben.

UPDATE: In meinem ursprünglichen Beitrag habe ich vergessen zu erwähnen, dass dies Ctrl-Zkeine Option ist. (Ich arbeite an einer Shell, die unter Emacs läuft, also Ctrl-Zunterbreche ich Emacs einfach.)

Antwort1

AlsStephen Kitt erklärt, wäre es ziemlich schwierig, zsh die PID drucken zu lassen. Aber Sie können die Informationen auch auf andere Weise erhalten.

Sie können Ctrl+ drücken Z, um den Prozess anzuhalten, dann zeigt zsh seine PID an. Und wenn Sie ihn beenden möchten, versuchen Sie zuerst Ctrl+ zu drücken C, um ihn direkt zu beenden. Wenn Ctrl+ Cfehlschlägt, versuchen Sie Ctrl+ \für einen „härteren“ Prozess ( Ctrl+ Csendet SIGINT, was einem Programm üblicherweise sagt, dass es seine aktuelle Aktion stoppen und die Kontrolle an den Benutzer zurückgeben soll; Ctrl+ \sendet SIGQUIT, was einem Programm üblicherweise sagt, dass es hart abstürzen soll). Sie können dies sogar von Emacs aus tun: Drücken Sie im Shell-Modus, um zum Terminal C-c C-zzu gelangen , um zu übergeben , um zu übergeben . Im Term-Modus werden und direkt übergeben, aber Sie müssen ein einzelnes übergeben .C-zC-c C-cC-cC-c C-\C-\C-zC-\C-c C-cC-c

Wenn der Prozess die Terminaleinstellungen ändert oder die Signale blockiert, können Sie ihn bequem über ttydas Terminal lokalisieren und beenden. Finden Sie heraus, um welches Terminal es sich handelt. Dies können Sie mit dem Befehl im Terminal tun. Sie können dies zu einem Teil Ihrer Eingabeaufforderung oder zum Teil des Terminaltitels machen (ich habe es in den Terminaltitel eingefügt). Emacs zeigt den Terminaltitel nicht an, aber Sie erhalten Zugriff auf die Informationen, indem Sie den folgenden Ausdruck auswerten:

(process-tty-name (get-buffer-process (current-buffer)))

Um einen Ausdruck in den meisten Modi, einschließlich dem Shell-Modus, auszuwerten, M-:geben Sie den Ausdruck ein und geben Sie ihn ein. Geben Sie im Term-Modus C-c M-x eval-expression RETden Ausdruck ein und geben Sie ihn ein. Wenn Sie dies häufig verwenden, binden Sie den folgenden Befehl in den entsprechenden Modi an eine Taste:

(defun buffer-process-tty-name ()
  (interactive)
  (let ((tty (process-tty-name (get-buffer-process (current-buffer)))))
    (if (interactivep) (message "%s" tty))
    tty))

Sobald Sie den Terminalnamen kennen, können Sie beispielsweise ps -t pts/42oder verwenden pgrep -t pts/42, um die Prozesse aufzulisten, die an dieses Terminal angeschlossen sind.

Antwort2

Es scheint keine Möglichkeit zu geben, diese Informationen zu protokollieren, und wenn man sich das genauer ansieht, wäre es schwierig, es richtig zu gestalten (ich dachte zunächst auch, es wäre schwierig, es umzusetzen, aberAbonnierenbehoben).

Ich dachte, das Implementierungsproblem liege darin, die Informationen an der richtigen Stelle zu protokollieren. Wenn eine Shell ein Kind startet, verzweigt sie sich und führt dann das Kind aus (es sei denn, sie kann sich selbst durch das Kind ersetzen, in welchem ​​Fall sie sich nicht verzweigt). Wenn sie sich verzweigt, wird der Prozess dupliziert; eine der Kopien erhält vom fork()Aufruf einen Rückgabecode von 0, was darauf hinweist, dass es das Kind ist, und die andere erhält die Prozesskennung des Kindes, was darauf hinweist, dass es das übergeordnete Element ist. Das Kind erbt die Dateideskriptoren des übergeordneten Elements, sodass es seine eigene PID protokollieren kann, bevor es die Dinge für einrichtet exec().

Das Designproblem besteht darin, zu entscheiden, was protokolliert werden soll. Wenn wir alle von der Shell gestarteten Prozesse protokollieren, erhalten wir am Ende eine Menge irrelevanter Protokolle.z.Bfür Prozesse, die an der Erstellung der Eingabeaufforderung beteiligt sind! Sogar für „echte“ Befehle müssen wir entscheiden, was für Pipelines und andere zusammengesetzte Befehle protokolliert werden soll … Und dann müssen wir uns aus Konsistenzgründen etwas einfallen lassen, das für integrierte Befehle protokolliert wird oder für Umstände, in denen die Shell sich selbst durch das untergeordnete Element ersetzt (obwohl ich nicht glaube, dass das bei einer interaktiven Shell passieren kann, es sei denn, Sie tun es manuell exec).

Wenn Sie dies weiter erkunden möchten, schauen Sie sich addproc()und printjobs()in jobs.cund zexecve()in an exec.c.

verwandte Informationen