¿Cómo mata un proceso en ejecución en un bashscript sin matar el script?

Oct 03 2020

¿Cómo mata un proceso en ejecución en un script bash sin matar el script?

Objetivo

Entonces ... necesito matar un proceso en ejecución para continuar con la ejecución de mi script.

Aquí hay una versión simplificada de mi script:

# Setup
echo "Use ctrl+C to stop gathering data..."
./logger
#------------------
echo "Rest..."

Necesito poder matar ./logger sin matar mi script

Resultados esperados frente a resultados reales

Esperaba un resultado como este:

Use ctrl+C to stop gathering data...
^C
Rest...

pero se detiene cuando mato el programa

use ctrl+C to stop gathering data...
^C

El ./loggercomando es un programa en C que ya maneja la SIGINTseñal ( Ctrl + C) pero no se detendrá hasta que la reciba. ¿Hay alguna forma de detener el programa sin matar mi script?

El programa C no es importante, pero se parece a esto

#include <stdio.h>
#include <signal.h>

int flag = 1;

void handler(int i)
{
     flag = 0;
}

int main(int argc, char** argv)
{
    signal(SIGINT, handler);
    while(flag)
    {
       usleep(10000);
    }
}

Respuestas

4 JonathanLeffler Oct 03 2020 at 10:21

Si escribe control-C en la terminal donde se ejecuta el script, la señal va a todos los procesos: el programa de registro y el script. Y el script termina porque no le ha dicho que ignore las señales mientras se ejecuta el registrador. Puede hacerlo usando el trapcomando, pero deberá deshacer la captura antes de ejecutar el programa C. Consulte también el manual de Bash sobre señales .

Por ejemplo, tengo un programa dribblerque genera mensajes, uno cada segundo por defecto, pero es configurable. Lo estoy usando como sustituto de su ./loggerprograma. Las -mopciones especifican el mensaje; la -nopción solicita que los mensajes estén numerados y la -topción especifica la salida a la salida estándar (en lugar de un archivo en el que escribe de forma predeterminada).

#!/bin/bash
#
# SO 6418-0134

program="dribbler -t -n -m Hello"
echo "About to run '$program' command" trap "" 2 (trap 2; $program)

echo "Continuing after '$program' exits"
sleep 1
echo "But not for long"

El sub-caparazón es necesario. Cuando ejecuto ese script ( trapper.sh), obtengo, por ejemplo:

$ bash trapper.sh
About to run 'dribbler -t -n -m Hello' command
0: Hello
1: Hello
2: Hello
3: Hello
^CContinuing after 'dribbler -t -n -m Hello' exits
But not for long
$

Por cierto, POSIX define un comando loggerque escribe mensajes usando la syslog()función o funciones del syslogdemonio.

También podría valer la pena revisar las preguntas y respuestas sobre el envío de SIGINT a un proceso ejecutivo bifurcado que ejecuta un script no lo mata , especialmente la respuesta aceptada y sus enlaces a preguntas y respuestas en otros sitios de Stack Exchange, ya que es importante que ambos ejecutamos una C programa, no un script de shell.