La execcarcasa incorporada (primer matiz)

La execcarcasa incorporada (primer matiz)

Estoy intentando redirigir toda la salida de un programa (Steam) a /dev/null para que no aparezca en la terminal.

Esto es lo que he probado: steam & > /dev/null 2>/dev/nullysteam & > /dev/null 2>&1

Ninguno de los cuales suprime sus mensajes (hasta donde yo sé).

Tengo entendido que & desconecta el proceso del terminal, y > redirige la entrada/salida, siendo el valor predeterminado/en blanco > stdout y 2> siendo stderr. ¿Hay más resultados que esos dos? ¿Por qué sigo viendo resultados si los estoy redirigiendo todos?

Respuesta1

Intentar:

steam 2>&1 > /dev/null &

2>&1redirige stderr a stdout y > /dev/nullredirige stdout a /dev/null.

El &fondo del proceso estaba fuera de lugar. Debe ir al final de la línea. Si se coloca después steampero antes , no se redirigirá >nada , aunque el proceso se realizará correctamente en segundo plano.steam

Respuesta2

Este problema en particular steamresulta ser un caso especial que a veces puede requerir una comprensión y un manejo especiales. El steamtiempo de ejecución es un script contenedor que contiene lo siguiente:

#!/bin/bash
# default to minimize on close, so we never have a running steam process
# in the background because of a broken Tray Icon on some desktops/WMs
#export STEAM_FRAME_FORCE_CLOSE=${STEAM_FRAME_FORCE_CLOSE:-0}
exec /usr/lib/steam/steam "$@"

Tenga en cuenta que utiliza el execshell integrado, además de pasar todos los argumentos con $@.

Entonces, si bien la solución habitual para la redirección de salida del shell sería similar a@Adobe y la respuesta de @Gary, este tipo particular de caso a menudo puede requerir un enfoque un poco más matizado y una comprensión de lo que sucede detrás de escena. Hay cierta sutileza en cuanto a por qué todos los posibles métodos de redirección de salida y el orden de las operaciones steama veces no funcionan como se esperaba.

La execcarcasa incorporada (primer matiz)

El estándar POSIX define un comportamiento paraEl execcomando. Bash proporciona esto a través delexecCarcasa incorporada. Lo que puede afectar la redirección de E/S estándar y el árbol de subprocesos, dependiendo de cómo se llame. Nota:Si bien esto no se aplica técnicamente en el caso de uso específico del OP ni en los comandos enumerados, lo incluyo aquí porque es un error y una advertencia común a tener en cuenta.

De la norma IEEE. 1003.1, edición de 2004:

La utilidad exec abrirá, cerrará y/o copiará descriptores de archivos según lo especificado en cualquier redireccionamiento como parte del comando.

Si se especifica exec sin comando ni argumentos, y cualquier descriptor de archivo con números mayores que 2 se abre con instrucciones de redirección asociadas, no se especifica si esos descriptores de archivo permanecen abiertos cuando el shell invoca otra utilidad. Los scripts preocupados por que los shells secundarios puedan hacer un mal uso de los descriptores de archivos abiertos siempre pueden cerrarlos explícitamente, como se muestra en uno de los siguientes ejemplos.

Si se especifica exec con comando, reemplazará el shell con comando sin crear un nuevo proceso. Si se especifican argumentos, serán argumentos para ordenar. La redirección afecta el entorno de ejecución actual del shell.

La exec /usr/lib/steam/steam "$@"línea en el /usr/bin/steamscript contenedor reemplazará el /bin/bashshell en ejecución (según la línea "shebang) sin crear un nuevo subproceso. El $@especificador de argumento se pasa entre comillas dobles, lo que en la mayoría de los casos debería evitar cualquier efecto secundario con los operadores de redirección IO Sin embargo, es bueno tener en cuenta que pasar algunos operadores de redirección de salida como argumentos (por ejemplo, mediante comillas erróneas "o 'mediante evalescape char \) podría presentar la oportunidad de inyectar operadores de redirección de shell en el script de modo que la execllamada posiblemente afecte el estándar. IO y descriptores de archivos del comando. Entonces, dependiendo de cómo pase 2>&1u >somefileotros operadores de redirección al script contenedor, se evaluarán en el contexto de: "$@"Afortunadamente, las comillas dobles en este caso eliminarían la mayoría de los efectos secundarios. , pero es importante tener cuidado qué proceso bash o subshell está evaluando esos argumentos.

Redirección de salida de Unix: stdin, stdout, &stderr

La mayoría de UnixREPLLos shells tienen un método similar para redirigir elflujos IO estándar, stdin, stdout, y stderr. Esto incluye, entre otros: POSIX sh, Bash, Z Shell zsh, Korn Shell ksh, C Shell csh, Dash dashy otros.

Para los propósitos de la pregunta del OP, nos centraremos solo en Bash porque el /usr/bin/steamscript contenedor comienza con Bash "el asunto" línea: #!/bin/bash.

En Bash, los primeros 3 descriptores de archivo ( fd's) siempre se definen de la siguiente manera, indexados comenzando desde cero 0:

  • stdin=fd 0
  • stdout=fd 1
  • stderr=fd 2

La salida de cualquier comando se puede redirigir usando eloperadores de redirección de salida en Bash (Manual de referencia de Bash: § 3.6 Redirecciones). Puede encontrar una introducción básica a esto en este artículo:Diversión de redirección de Bash con descriptores. Para una explicación más intuitiva, con ayudas visuales,vea este excelente artículo (¡Muy recomendable!).

Orden de Operaciones (segundo matiz):

Existe un orden sutil de operaciones entre:

... y el:

Desde elManual de referencia de Bash § 3.6 Redirecciones:

Las redirecciones se procesan en el orden en que aparecen, de izquierda a derecha.

[...RECORTE...]

Tenga en cuenta que el orden de las redirecciones es importante. Por ejemplo, el comando

ls > dirlist 2>&1

dirige tanto la salida estándar (descriptor de archivo 1) como el error estándar (descriptor de archivo 2) a la lista de directorios de archivos, mientras que el comando

ls 2>&1 > dirlist

dirige solo la salida estándar al archivo dirlist, porque el error estándar se realizó como una copia de la salida estándar antes de que la salida estándar fuera redirigida a dirlist.

Asimismo, existe un orden de operaciones para &y otros operadores de control.

Desde elManual de referencia de Bash: 2.4 Listas de comandos:

Una lista es una secuencia de una o más canalizaciones separadas por uno de los operadores ' ;', ' &', ' &&' o ' ||', y opcionalmente terminadas por uno de ' ;', ' &' o un newline.

De estos operadores de lista, ' &&' y ' ||' tienen la misma precedencia, seguidos de ' ;' y ' &', que tienen la misma precedencia.

Puede aparecer una secuencia de una o más nuevas líneas en un listcomando para delimitar, equivalente a un punto y coma.

Por último, concretamente el apartado sobre &:

Si el operador de control ' ' finaliza un comando &, el shell ejecuta el comando de forma asincrónica en un subshell. Esto se conoce como ejecutar el comando en elfondo, y estos se conocen comoasincrónicocomandos. El shell no espera a que finalice el comando y el estado de retorno es 0( true). Cuando el control de trabajos no está activo (consulteControl de Trabajo), la entrada estándar para comandos asincrónicos, en ausencia de redirecciones explícitas, se redirige desde /dev/null.

Por qué los comandos del OP no hicieron lo que se esperaba

Los dos primeros comandos probados fueron:

  • steam & > /dev/null 2>/dev/null
  • steam & > /dev/null 2>&1

La razón por la que estos no realizaron la redirección prevista de ambos stdouty stderrcomo se esperaba se debe a lo mencionado anteriormente.orden de operaciones / precedencia de operadoresreglas enumeradas anteriormente. Específicamente, el &operador aparece primero en orden de izquierda a derecha. Se aplica a la primera palabra, el comando steam, y lo envía a un segundo plano ejecutándose como uncomando asincrónico. stdinestá conectado a /dev/null, mientras stdouty stderrpermanece conectado al controlPseudoterminal /pty. Esto se explica más adelante.

Pero primero...

¡Más confusión encadenada exec!

información relacionada