¿Cómo imprimir el PID en el terminal al inicio de *cada* proceso?

¿Cómo imprimir el PID en el terminal al inicio de *cada* proceso?

Si empiezo unasincrónico("en segundo plano"), cierta información, incluido el PID del nuevo proceso, se imprime en la terminal antes de que se ejecute el proceso; Por ejemplo

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

¿Hay alguna manera de imprimir dicha información (especialmente el PID) al comienzo del proceso?cadaproceso, no sólo aquellos que comienzan de forma asincrónica?


Fondo

La razón para querer esto es que, debido a las peculiaridades de mi entorno de trabajo diario, a menudo sucede que unsincrónicoEl proceso de larga duración no responde Ctrl-C. (Invariablemente, lo que hace que estos procesos sean "de larga duración" es que producen muchos más resultados de los que había anticipado). La forma más segura de detener un proceso de este tipo es hacerlo kill -9desde una ventana diferente, y sería bueno tener su PID disponible para esto.

ACTUALIZACIÓN: En mi publicación original omití mencionar que Ctrl-Zno es una opción. (Estoy trabajando en un shell que se ejecuta en Emacs, por lo que Ctrl-Zsimplemente suspende Emacs).

Respuesta1

ComoStephen Kitt explica, hacer que zsh imprima el PID sería bastante difícil. Pero puedes obtener la información de otras maneras.

Puede presionar Ctrl+ Zpara suspender el proceso, luego zsh muestra su PID. Y si quieres matarlo, intenta presionar Ctrl+ Cprimero, para matarlo directamente. Si Ctrl+ Cfalla, intente Ctrl+ \realizar una eliminación “más difícil” ( Ctrl+ Cenvía SIGINT, que convencionalmente le dice a un programa que detenga su acción actual y devuelva el control al usuario; Ctrl+ \envía SIGQUIT, que convencionalmente le dice a un programa que se bloquee bruscamente). Puede hacer esto incluso desde Emacs: en modo Shell, presione C-c C-zpara pasar C-zal terminal, C-c C-cpara pasar C-c, C-c C-\para pasar C-\. En el modo Term, C-zy C-\se pasan directamente, pero es necesario C-c C-cpasar un solo archivo C-c.

Si el proceso cambia la configuración del terminal o bloquea las señales, una forma conveniente de localizarlo para matarlo es mediante el terminal. Descubra cuál es la terminal; puedes hacer esto con el ttycomando dentro de la terminal. Puede hacer que esto forme parte de su mensaje o del título de la terminal (lo puse en el título de la terminal). Emacs no muestra el título de la terminal, pero te da acceso a la información evaluando la siguiente expresión:

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

Para evaluar una expresión en la mayoría de los modos, incluido el modo Shell, escriba M-:y luego ingrese la expresión. En el modo Término, escriba C-c M-x eval-expression RETy luego ingrese la expresión. Si usa esto con frecuencia, vincule el siguiente comando a una clave en los modos relevantes:

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

Una vez que sepa el nombre del terminal, puede usar, por ejemplo, ps -t pts/42o pgrep -t pts/42para enumerar los procesos que están adjuntos a ese terminal.

Respuesta2

No parece haber una forma de registrar esta información y analizarla con más detalle; sería difícil diseñarla correctamente (inicialmente pensé que también sería difícil de implementar, peroilkkachuarreglado eso).

Pensé que el problema de implementación era registrar la información en el lugar correcto. Cuando un shell inicia un niño, se bifurca y luego ejecuta al niño (a menos que pueda reemplazarse con el niño, en cuyo caso no se bifurca). Cuando se bifurca, el proceso se duplica; una de las copias obtiene un código de retorno de 0 de la fork()llamada, lo que indica que es el hijo, y la otra obtiene el identificador de proceso del hijo, que indica que es el padre. El niño hereda los descriptores de archivos del padre, por lo que puede registrar su propio pid antes de configurar las cosas para exec().

El problema de diseño es elegir qué registrar. Si registramos todos los procesos iniciados por el shell, terminamos con muchos registros extraños,p.ejpara los procesos involucrados en la construcción del mensaje! Incluso para los comandos "reales", debemos decidir qué registrar para los pipelines y otros comandos compuestos... Y luego, para mantener la coherencia, debemos idear algo para registrar para los comandos integrados o para las circunstancias en las que el shell reemplaza con el niño (aunque no creo que eso pueda suceder con un shell interactivo, a menos que lo haga manualmente exec).

Si desea explorar esto más a fondo, consulte addproc()y printjobs()en jobs.cy zexecve()en exec.c.

información relacionada