redirigiendo a / dev / null


144

Estoy leyendo un ejemplo de script de shell bash:

#!/bin/bash

# This script makes a backup of my home directory.

cd /home

# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1

# First remove the old bzip2 file.  Redirect errors because this generates some if the archive
# does not exist.  Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar

# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1

# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log

Estoy tratando de entender el uso de "/ dev / null 2> & 1" aquí. Al principio, pensé que este script usa / dev / null para ignorar con gracia los errores, sin causar que el script se bloquee (algo así como intentar capturar el manejo de excepciones en lenguajes de programación). Porque no veo cómo el uso de tar para comprimir un directorio en un archivo tar podría causar algún tipo de error.


3
Redirigir a /dev/nullno evitará fallas, pero limpiará las secuencias de salida stdout y stderr. tarpodría causar errores de varias maneras. Es posible que no tenga acceso de escritura, que el archivo ya exista, etc.
Sparhawk

3
Solo un truco para evitar resultados innecesarios. En cuanto a por qué tar puede causar errores: porque el directorio de destino no existe, porque la fuente no existe, porque no tiene acceso de escritura al destino o leyó la fuente, porque tarno está en su $ PATH, porque tarse bloqueó (nunca se sabe), porque no queda espacio en el dispositivo, porque la tarversión cambió y ahora requiere una sintaxis diferente, porque el disco causó un error de E / S. Estoy seguro de que puedes encontrar más.
terdon

Respuestas:


223

No, esto no evitará que el script se bloquee. Si se produce algún error en el tarproceso (por ejemplo: permiso denegado, ningún archivo o directorio, ...), el script seguirá fallando.

Debido a que el uso > /dev/null 2>&1redirigirá toda la salida de su comando (ambos stdouty stderr) a /dev/null, lo que significa que no se imprimen salidas en el terminal.

Por defecto:

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

En el script, usas > /dev/nullcausar:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> fd 2

Y luego 2>&1causando:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> stdout

3
A partir de la comprensión > /dev/null 2>&1, este comando da como resultado stderr ==> stdout, ¿así que stderr todavía se imprime en stdout?
Weishi Zeng

11
probablemente no es demasiado importante, pero ¿qué es fd?
kev


77
¿Por qué funciona: CMD > /dev/null 2>&1pero CMD 2>&1 > /dev/nulltodavía me da STDERR?
dbmikus

3
Recomendado: Use 2>& 1en ejemplos de código para enfatizar que el número y el ampersand se consideran parte del operador de redireccionamiento. Es común que la redirección a un archivo tenga un espacio entre >y /path/to/file, la redirección a un descriptor de archivo es esencialmente lo mismo.
Henk Langeveld

21

Estoy tratando de entender el uso de "> / dev / null 2> & 1" aquí.

(tenga en cuenta que agregué la redirección antes /dev/nullen su pregunta).

Lo anterior redirigiría el STDOUTy STDERRhacia /dev/null. Funciona fusionando el STDERRen el STDOUT. (Esencialmente, toda la salida del comando se redirigiría al dispositivo nulo ).

... sin hacer que el script se bloquee (algo así como intentar capturar el manejo de excepciones en lenguajes de programación)

No es como un try/catcho nada. Simplemente silencia cualquier tipo de salida (incluido el error) del comando.

Porque no veo cómo el uso de tar para comprimir un directorio en un archivo tar podría causar algún tipo de error.

Podría provocar errores por varias razones, que incluyen:

  • Permisos inadecuados en los archivos que intenta archivar o en los archivos en los que intenta escribir
  • Falta de espacio en disco para crear el archivo

Bien explicado.
Aditya Gupta

7

Cuando ejecuta CMD> / dev / null 2> & 1

STDOUT redirige a / dev / null, y luego STDERR redirige a LA DIRECCIÓN de STDOUT, que se ha establecido en / dev / null, por lo tanto, STDOUT y STDERR apuntan a / dev / null

Opuestamente, cuando ejecuta CMD 2> & 1> / dev / null

STDERR redirige a LA DIRECCIÓN de STDOUT (descriptor de archivo 1 en ese momento, o / proc / self / fd / 1), y luego STDOUT redirige a / dev / null, ¡pero STDERR sigue redirigiendo a fd1! Como resultado, la salida normal de STDOUT se descarta, pero los errores que provienen de STDERR todavía se escriben en la consola.


-2

Redirección de E / S de Bash

La idea principal para aclarar las cosas es esta:

Las redirecciones se aplican de DERECHA a IZQUIERDA, opuesto a la forma en que los hablantes de inglés normalmente leen.


Entonces este código:

command > filename 2>&1

redirige stderra stdout first ( 2>&1) y luego envía stdout(incluido el redirigido stderr) a filename( > filename). Aquí está la explicación de ABSG (Capítulo 20) .

Este código:

command >>/dev/null 2>&1

redirecciona stderry stdouta /dev/null... lo que significa a ninguna parte . Las cosas enviadas a /dev/nullno se guardan, almacenan en caché ni se recuerdan de ninguna manera.

Simplemente se envían a " ninguna parte " y se olvidan. Esta es una forma de ejecutar programas y asegurarse de que NO produzcan resultados y que nunca se verán en la línea de comandos o en un archivo de registro.


Veo este tipo de preguntas bastante ... principalmente porque he tenido que buscarlo yo mismo ya que no he estado codificando en años. Aquí hay información útil de ABSG:

"La redirección simplemente significa capturar la salida de un archivo, comando, programa o script y enviarlo como entrada a otro archivo, comando, programa o script".

2>&1 
# Redirects stderr to stdout.

command >>filename 2>&1
# Appends both stdout and stderr
#+  to the file "filename" ...

ABSG: Guía avanzada de secuencias de comandos Bash: el enlace del Capítulo 20 anterior es un enlace a la página de redirección de E / S del documento de código abierto tldp.org llamada Guía avanzada de secuencias de comandos Bash de Mendel Cooper. Está catalogado como "Una exploración en profundidad del arte de las secuencias de comandos de shell" y estoy totalmente de acuerdo. Es un recurso excelente y tiene toneladas de respuestas a todo tipo de situaciones locas.

Otros recursos valiosos: Hay muchos recursos valiosos en la sección actual / mantenida (en varios formatos útiles como html, pdf, texto, etc.) en la página de Guías del proyecto de documentación de Linux . Aquí hay algunos que he encontrado útiles:


1
No, las redirecciones se manejan de izquierda a derecha. En su ejemplo, la salida estándar se redirige a filename, luego el error estándar se redirige a donde sea que vaya la salida estándar (a filename). Si fuera al revés, el error estándar terminaría en el terminal mientras que solo se redirige la salida estándar filename. También, en command >file1 2>file2, file2que no se creará si file1no pudo ser creado (no importa si file1y file2en realidad eran totalmente diferentes nombres de ruta).
Kusalananda
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.