bash shell unix parallel-processing

¿Hay alguna manera de hacer que el control del trabajo bash sea silencioso?



#!/ bin csh (5)

Bash es bastante detallado cuando ejecuta trabajos en segundo plano:

$ echo toto& toto [1] 15922 [1]+ Done echo toto

Como intento ejecutar trabajos en paralelo y utilizar la salida, me gustaría encontrar una forma de silenciar a bash. ¿Hay alguna manera de eliminar esta salida superflua?


Envuélvalo en una secuencia de comandos ficticia:

quiet.sh:

#!/bin/bash $@ &

luego llámalo, pasando tu comando a él como argumento:

./quiet.sh echo toto

Es posible que deba jugar con comillas dependiendo de su entrada.


Interactivamente, no. Siempre mostrará el estado del trabajo. Puede influir cuando se muestra el estado usando set -b .

No hay nada que le impida usar la salida de sus comandos (a través de tuberías, o almacenar variables, etc.). El shell envía el estado de la tarea al terminal de control y no se mezcla con otras E / S. Si está haciendo algo complejo con los trabajos, la solución es escribir un script separado.

Los mensajes de trabajo solo son realmente un problema si tiene, por ejemplo, funciones en su bashrc que hacen uso del control de trabajo y desea tener acceso directo a su entorno interactivo. Lamentablemente, no hay nada que puedas hacer al respecto.


Puede usar paréntesis para ejecutar un comando de fondo en una subcadena, y eso silenciará los mensajes de control de trabajo. Por ejemplo:

(sleep 10 & )


Una solución (en bash de todos modos) es enrutar toda la salida a / dev / null

echo ''hello world'' > /dev/null &

Lo anterior no le dará ningún resultado que no sea la identificación para el proceso bg.


Nota: Lo siguiente se aplica a las sesiones Bash interactivas . En las secuencias de comandos , los mensajes de control de trabajos nunca se imprimen.

Hay 2 escenarios básicos para silenciar los mensajes de control de trabajo de Bash :

Lanzamiento y olvido:

La respuesta de respuesta útil de CodeGnome sugiere incluir el comando de fondo en una sub-shell simple , por ejemplo, (sleep 10 &) , que efectivamente silencia los mensajes de control de trabajos, tanto en la creación de trabajos como en la terminación de trabajos.

Esto tiene un efecto secundario importante :

  • Al usar el operador de control & dentro de la subcapa, se pierde el control del trabajo en segundo plano : los jobs no lo mostrarán, ni el %% (la especificación (ID) del trabajo lanzado más recientemente) ni $! (El PID del (último) proceso iniciado (como parte de) el trabajo más reciente) lo reflejará. [1]

Para escenarios de lanzamiento y olvido, esto no es un problema :

  • Usted acaba de disparar el trabajo de fondo,
  • y dejas que termine por sí mismo (y confías en que funcione correctamente).

[1] Posiblemente, podría buscar el proceso usted mismo, buscando procesos en ejecución para aquellos que coincidan con su línea de comando, pero eso es engorroso y no es fácil de robustecer.

Launch-and-control-later:

Si desea mantener el control del trabajo , para poder hacerlo más tarde:

  • matarlo , si es necesario.
  • espera sincrónicamente (en algún momento posterior) para su finalización,

se necesita un enfoque diferente:

  • El silenciamiento de los mensajes de creación de trabajos de control se maneja a continuación, pero para silenciar categóricamente los mensajes de terminación de control de trabajos , debe desactivar la opción de shell de control de trabajos :

    • set +m ( set -m vuelve a encender)
    • Advertencia : este es un entorno global que tiene una serie de efectos secundarios importantes , en particular:
      • Stdin para comandos de fondo es entonces /dev/null lugar de la shell actual.
      • Los accesos directos de teclado para suspender ( Ctrl-Z ) y suspender la suspensión ( Ctrl-Y ) un comando de primer plano están deshabilitados.
      • Para la historia completa, vea man bash y (sin distinción de mayúsculas y minúsculas) busque ocurrencias de "control de trabajo".
  • Para silenciar los mensajes de creación de trabajo de creación , encierre el comando de fondo en un comando de grupo y redirija la salida de stderr de este último a /dev/null

    { sleep 5 & } 2>/dev/null

El siguiente ejemplo muestra cómo iniciar de forma silenciosa un trabajo en segundo plano al tiempo que conserva el control del trabajo en principio.

$ set +m; { sleep 5 & } 2>/dev/null # turn job-control option off and launch quietly $ jobs # shows the job just launched; it will complete quietly due to set +m

Si no desea desactivar la opción de control de trabajos ( set +m ), la única forma de silenciar el mensaje de terminación de control de trabajos es cancelar el trabajo o wait :

Advertencia: hay dos casos de borde donde esta técnica todavía produce salida:

  • Si el comando de fondo intenta leer de stdin de inmediato .
  • Si el comando de fondo termina de inmediato .

Para iniciar el trabajo en silencio (como se indicó anteriormente, pero sin set +m ):

$ { sleep 5 & } 2>/dev/null

wait en silencio

$ wait %% 2>/dev/null # use of %% is optional here

Para kill en silencio:

{ kill %% && wait; } 2>/dev/null

La wait adicional es necesaria para hacer que el mensaje de terminación de control de trabajos que normalmente se muestra asincrónicamente por Bash (en el momento de la finalización del proceso real, poco después del cierre) sea una salida sincrónica de wait , que luego permite silenciar.

Pero, como se dijo, si el trabajo se completa solo , aún se mostrará un mensaje de control de trabajo.