Pregunta

¿Cómo se puede suprimir el Terminated ¿Mensaje que surge después de matar un proceso en un script bash?

Lo intenté set +bm, pero eso no funciona.

Sé que otra solución implica llamar exec 2> /dev/null, pero ¿eso es confiable?¿Cómo lo reinicio para poder seguir viendo stderr?

¿Fue útil?

Solución

La respuesta corta es que no puedes.Bash siempre imprime el estado de los trabajos en primer plano.El indicador de supervisión solo se aplica a trabajos en segundo plano y solo a shells interactivos, no a scripts.

consulte notify_of_job_status() en jobs.c.

Como usted dice, puede redirigir de modo que el error estándar apunte a /dev/null pero luego se pierda cualquier otro mensaje de error.Puede hacerlo temporal realizando la redirección en un subshell que ejecuta el script.Esto deja el entorno original en paz.

(script 2> /dev/null)

lo que perderá todos los mensajes de error, pero solo de ese script, no de nada más que se ejecute en ese shell.

Puede guardar y restaurar el error estándar redirigiendo un nuevo descriptor de archivo para que apunte allí:

exec 3>&2          # 3 is now a copy of 2
exec 2> /dev/null  # 2 now points to /dev/null
script             # run script with redirected stderr
exec 2>&3          # restore stderr to saved
exec 3>&-          # close saved version

Pero no recomendaría esto: la única ventaja del primero es que guarda una invocación de sub-shell, aunque es más complicado y posiblemente incluso altere el comportamiento del script, si el script altera los descriptores de archivos.


EDITAR:

Para obtener una respuesta más apropiada, consulte la respuesta dada por Marcos Edgar

Otros consejos

Para silenciar el mensaje debes estar redireccionando stderr en el momento en que se genera el mensaje.Porque el kill El comando envía una señal y no espera a que el proceso objetivo responda, redirigiendo stderr del kill El mando no te sirve de nada.El bash incorporado wait fue hecho específicamente para este propósito.

Aquí hay un ejemplo muy simple que elimina el comando en segundo plano más reciente.(Obtenga más información sobre $!aquí.)

kill $!
wait $! 2>/dev/null

porque ambos kill y wait Acepte varios pids, también puede realizar eliminaciones por lotes.Aquí hay un ejemplo que elimina todos los procesos en segundo plano (del proceso/script actual, por supuesto).

kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null

Fui conducido aquí desde intento:matar silenciosamente el proceso de función en segundo plano.

Inspirado por La respuesta de MarcH.yo estaba usando kill -INT como sugiere con cierto éxito, pero noté que no estaba matando algunos procesos.Después de probar algunas otras señales, veo que SIGPIPE matará también sin un mensaje.

kill -PIPE

o simplemente

kill -13

Solución:use SIGINT (funciona solo en shells no interactivos)

Manifestación:

cat > silent.sh <<"EOF"
sleep 100 &
kill -INT $!
sleep 1
EOF

sh silent.sh

http://thread.gmane.org/gmane.comp.shells.bash.bugs/15798

Tal vez separe el proceso del proceso de shell actual llamando disown?

¿Es esto lo que todos buscamos?

No deseado:

$ sleep 3 &
[1] 234
<pressing enter a few times....>
$
$
[1]+  Done                    sleep 3
$

Buscado:

$ (set +m; sleep 3 &)
<again, pressing enter several times....>
$
$
$
$
$

Como puede ver, no hay mensaje de finalización del trabajo.También me funciona en scripts bash, también para procesos en segundo plano cancelados.

'set +m' deshabilita el control de trabajos (consulte 'conjunto de ayuda') para el shell actual.Entonces, si ingresa su comando en un subshell (como se hace aquí entre paréntesis), no influirá en la configuración de control de trabajos del shell actual.La única desventaja es que necesita devolver el pid de su proceso en segundo plano al shell actual si desea verificar si ha terminado o evaluar el código de retorno.

Otra forma de desactivar las notificaciones de trabajo es colocar el comando para que aparezca en segundo plano en un sh -c 'cmd &' construir.

#!/bin/bash
# ...
pid="`sh -c 'sleep 30 & echo ${!}' | head -1`"
kill "$pid"
# ...

# or put several cmds in sh -c '...' construct
sh -c '
sleep 30 &
pid="${!}"
sleep 5 
kill "${pid}"
'

Esto también funciona para Killall (para aquellos que lo prefieran):

killall -s SIGINT (yourprogram) 

suprime el mensaje...Estaba ejecutando mpg123 en modo de fondo.Solo se puede eliminar silenciosamente enviando Ctrl-c (SIGINT) en lugar de SIGTERM (predeterminado).

disown hizo exactamente lo correcto para mí - el exec 3>&2 es riesgoso por muchas razones - set +bm no pareció funcionar dentro de un script, solo en el símbolo del sistema

Tuvo éxito al agregar 'jobs 2>&1 >/dev/null' al guión, no estoy seguro si ayudará al guión de alguien más, pero aquí hay una muestra.

    while true; do echo $RANDOM; done | while read line
    do
    echo Random is $line the last jobid is $(jobs -lp)
    jobs 2>&1 >/dev/null
    sleep 3
    done

Descubrí que poner el comando kill en una función y luego poner la función en segundo plano suprime la salida de terminación.

function killCmd() {
    kill $1
}

killCmd $somePID &

Simple:

{ kill $! } 2>/dev/null

¿Ventaja?puede usar cualquier señal

ex:

{ kill -9 $PID } 2>/dev/null
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top