Dado un proceso de shell (por ejemplo, sh
) y su proceso hijo (por ejemplo, cat
), ¿cómo puedo simular el comportamiento de Ctrl +C usando el ID de proceso del shell?
Esto es lo que he probado:
Ejecutando sh
y luego cat
:
[[email protected] ~]$ sh
sh-4.3$ cat
test
test
Enviando SIGINT
a cat
desde otra terminal:
[[email protected] ~]$ kill -SIGINT $PID_OF_CAT
cat
recibió la señal y terminó (como se esperaba).
Enviar la señal al proceso principal no parece funcionar. ¿Por qué la señal no se propaga a cat
? cuando se envía a su proceso padre sh
?
Esto no funciona:
[[email protected] ~]$ kill -SIGINT $PID_OF_SH
Respuesta aceptada:
Cómo CTRL +C funciona
Lo primero es entender cómo CTRL +C funciona.
Cuando presionas CTRL +C , su emulador de terminal envía un carácter ETX (fin de texto / 0x03).
El TTY está configurado de tal manera que cuando recibe este carácter, envía un SIGINT al grupo de procesos en primer plano del terminal. Esta configuración se puede ver haciendo stty -a
y mirando intr = ^C;
.
La especificación POSIX dice que cuando se recibe INTR, debe enviar un SIGINT al grupo de procesos en primer plano de ese terminal.
¿Qué es el grupo de procesos en primer plano?
Entonces, ahora la pregunta es, ¿cómo determina cuál es el grupo de procesos de primer plano?
El grupo de procesos de primer plano es simplemente el grupo de procesos que recibirá cualquier señal generada por el teclado (SIGTSTP, SIGINT, etc.).
La forma más sencilla de determinar el ID del grupo de procesos es usar ps
:
ps ax -O tpgid
La segunda columna será el ID del grupo de procesos.
¿Cómo envío una señal al grupo de proceso?
Ahora que sabemos cuál es el ID del grupo de procesos, necesitamos simular el comportamiento POSIX de enviar una señal a todo el grupo.
Esto se puede hacer con kill
poniendo un -
delante del ID de grupo.
Por ejemplo, si su ID de grupo de proceso es 1234, usaría:
kill -INT -1234
Simular CTRL +C utilizando el número de terminal.
Entonces, lo anterior cubre cómo simular CTRL +C como un proceso manual. Pero, ¿qué sucede si conoce el número TTY y desea simular CTRL? +C para ese terminal?
Esto se vuelve muy fácil.
Relacionado:Bash convertir \xC3\x89 a É?
Supongamos $tty
es el terminal al que desea dirigirse (puede obtenerlo ejecutando tty | sed 's#^/dev/##'
en la terminal).
kill -INT -$(ps h -t $tty -o tpgid | uniq)
Esto enviará un SIGINT a cualquiera que sea el grupo de procesos en primer plano de $tty
es.