¿Cómo es STDERR.puts diferente de puts en Ruby?
(3)
Estoy aprendiendo el lenguaje de Programming Ruby 1.9 y lanzan STDERR.puts en un bloque de código al inicio del libro sin explicar por qué lo están usando o cómo es diferente de las puts.
Busqué en Google y escribí el término, pero todo lo que puedo deducir de mi investigación es que está involucrado en el diagnóstico. En ninguna parte del código provisto por Programming Ruby parece haber un enlace al manejo de excepciones de errores.
Aquí está el código.
require_relative ''csv_reader''
reader = CsvReader.new
ARGV.each do |csv_file_name|
STDERR.puts "Processing #{csv_file_name}"
reader.read_in_csv_data(csv_file_name)
end
Me las arreglé para leer en algún lugar que STDERR.puts se utiliza para el manejo de errores fuera de la convención, pero supongo que estoy preguntando si actúa de manera diferente a las puts.
Cada programa comienza con tres descriptores de archivos estándar cuando se generan: entrada estándar, salida y secuencias de error.
La secuencia de entrada estándar es una secuencia genérica desde la cual se debe leer la entrada del programa. Del mismo modo, la secuencia de salida estándar es una secuencia genérica a la que se puede escribir la salida del programa. Entonces, ¿qué es el error estándar?
La diferencia entre la salida estándar y el error estándar es sutil pero extremadamente importante en los sistemas UNIX debido a la forma en que los programas se usan juntos a través de las tuberías. Los programas a menudo están diseñados para consumir el resultado de otros programas como su entrada; esto se hace redireccionando la salida estándar de un programa a la entrada estándar de otro, a menudo a través del operador de tubería ( |
). Esto deja un error estándar todavía conectado a la terminal. El usuario puede elegir ver los datos enviados a esa transmisión en el terminal mismo, o redirigirlos a un archivo de registro, o a /dev/null
, cualquier cosa que el usuario desee. Tenga en cuenta que los datos enviados a stderr
no necesitan necesariamente ser mensajes de error; solo son datos que están separados de la salida real del programa.
Respaldar este paradigma es extremadamente importante para la usabilidad de los programas, ya que proporciona una interfaz de usuario predecible para la entrada, salida y mensajes del programa. El usuario puede manipularlos como mejor le parezca y, a menudo, surgen aplicaciones interesantes de una manera imprevista.
Entonces, en términos generales, la salida estándar es para la salida real y el error estándar es para comunicarse con el usuario.
Dentro de un sistema basado en * nix cuando se inicia un nuevo proceso, tendrá por defecto tres manejadores de archivos abiertos, estos son los siguientes
0 - STDIN 1 - STDOUT 2 - STDERR
Estos números, vamos a llamarlos descriptores de archivos, son importantes para el shell de Unix que está utilizando para iniciar su programa. STDIN es donde su programa espera obtener su entrada desde (por lo general, el teclado a menos que haya cambiado eso). STDOUT es donde su programa escribirá su salida (generalmente la pantalla a menos que lo haya cambiado) y STDERR es donde escribirá sus errores (de nuevo usualmente la pantalla a menos que la haya cambiado).
La declaración común de arriba es "A menos que lo hayas cambiado". Si ejecuta un comando como este
command > file.out
Entonces, la salida (todo lo escrito en STDOUT) no aparecerá en la pantalla, aparecerá en file.out. Si ejecuta su comando de esta manera
command 2> file.err
Luego, su salida aparecerá en la pantalla nuevamente, pero los errores escritos en STDERR aparecerán en file.err. De hecho, command > file.out
es realmente una abreviatura para el command 1>file.out
. Lo que se aplica al símbolo> (Redirección) también se aplica a | símbolo para la tubería. Esto significa que si ejecuta su programa como un filtro, recibe datos en STDIN y escribe en STDOUT, entonces otros programas pueden recibir sus datos de su programa pero no recibirán los datos escritos en STDERR. (A menos que lo haya pedido)
Puede usar ambos comandos juntos de esta manera.
command 1> file.out 2> file.err # Generally you would leave out the 1
En este caso, no es sorprendente que la salida y el error estén en 2 archivos separados. Bash también tiene la idea de duplicar descriptores de archivos. Esto se hace con> & operador. El siguiente comando colocará STDOUT y STDERR en el mismo archivo.
command > file.out 2>&1
Lo que este comando está diciendo es ejecutar el comando configurando STDOUT para ser redirigido a file.out luego duplicar (> &) el descriptor de archivo 2 (STDERR) para ir a donde sea que esté el archivo descriptor 1 (file.out)
Debe tener un poco de cuidado aquí con el orden en que usa estos argumentos. Compare lo anterior con este comando.
command 2>&1 > file.out
Esto tiene un resultado completamente diferente. Este comando dice ejecutar el comando y duplicar STDERR en STDOUT (en este punto en el tiempo el terminal) luego redirigir STDOUT a file.out. Su texto de error permanecerá en la pantalla.
Por defecto, puts
escrituras en STDOUT. Al especificar STDERR.puts
, está enviando su salida al controlador STDERR. Aunque el comportamiento de implementación es el mismo, usar STDERR en lugar de STDOUT definitivamente impactará a los consumidores de su programa, ya que intentarán capturar los resultados de su programa de STDOUT, por convención. La mejor práctica es registrar la información de depuración, errores, advertencias, estado, etc. en STDERR y la salida real del programa en STDOUT.