¿Cómo evitar que bash imprima alertas?

2

Al kill -9 $PID &>/dev/nullfinalizar un proceso con un script, todavía se imprime un mensaje en el terminal después de que termina el siguiente comando. ¿Cómo se detiene este comportamiento?

Por ejemplo

while true; do
    /usr/bin/dostuff -a -b -c
    PID=$(pidof -o %PPID /usr/bin/dostuff)
    sleep 1; 
    kill -KILL $PID &>/dev/null
    echo "hello"
done

imprimirá algo como

hello
./my-cript.sh: line 12:  7134 Killed
/usr/bin/dostuff -a -b -c

Cuando solo quiero que imprima "hola"

EDITAR: La solución limpia es ejecutar el programa en una subshell o rechazarlo.

#SOLUTION
while true; do
    /usr/bin/dostuff -a -b -c &
    disown
    PID=$!
    sleep 1; 
    kill -KILL $PID &>/dev/null
    echo "hello"
done
brice
fuente
¿Por qué incluso estás ejecutando kill en segundo plano? En el caso normal, kill volverá rápidamente y no necesita tener antecedentes. En este caso, estás durmiendo de todos modos ... entonces, ¿cuál es el punto? Simplemente elimine el '&'.
William Pursell
1
kill no se ejecuta en segundo plano. &>redirige stdin y stdout
brice

Respuestas:

4

Las líneas de salida no se redirigen a / dev / null porque no son STDOUT / STDERR del proceso de eliminación . Son producto de los mecanismos de control de trabajo del shell.

Si está usando bash , puede ejecutar un rechazo inmediatamente después de la invocación del trabajo:

while true; do
    /usr/bin/dostuff -a -b -c

    ### remove from shell job table
    disown

    PID=$(pidof -o %PPID /usr/bin/dostuff)
    sleep 1; 
    kill -KILL $PID &>/dev/null
    echo "hello"
done

Probé esto en bash v3.2.39 en Debian Lenny, /bin/sleep 10 &en lugar del /usr/bin/dostuffcomando anterior :

./tmp.sh
hello
hello
hello
hello
^C
quijote curandero
fuente
saludos ~ quack! era justo lo que estaba buscando.
brice
2
Si ejecuta dostuffcon un seguimiento &, puede obtener su pid como $!(hasta que ejecute otro proceso en segundo plano). Eso te ahorrará la pidofbúsqueda ... oh sí, alguien ya dijo esto.
dubiousjim
3

La redirección del error no es efectiva porque este mensaje no se imprime mediante kill; el shell lo imprime cuando finaliza el trabajo en segundo plano (supongo que faltaba &).

Puede evitar esto ejecutándose en una subshell, usando paréntesis (pero tenga en cuenta otros posibles problemas):

while true; do
    (
    /usr/bin/dostuff a b c &
    PID=$!
    sleep 1
    kill -9 $PID
    )
    echo hello
done
b0fh
fuente
algunos ejecutables pueden ponerse en segundo plano, por lo que no necesitan el &. pero sí, esta es otra forma de manejar el problema.
quack quijote
Lo siento Bofh, probé la solución de ~ quack primero. ¡Funciona exactamente como se esperaba! +1 gracias.
Brice
0

Podrías hacer set -be instalar una trampa en SIGCHLD. Creo que el controlador SIGCHLD predeterminado es el que imprimirá (inmediatamente) el estado del trabajo en el terminal cuando lo haya hecho set -b. Aquí lo estarías anulando.

dubiousjim
fuente
Sí, me preguntaba si había una setopción que controlara este comportamiento. es parte de la descripción de -m(modo monitor) pero la configuración no parece ayudar. tampoco pude deshacerme de él atrapando a SIGCHLD. (juzgados trap /bin/true SIGCHLD, pero tal vez eso no es suficiente.)
charlatán Quijote
tienes razón, solo lo probé un poco. Supongo que repudiar es la mejor opción entonces.
dubiousjim