¿Cuál es la diferencia entre escribir en STDOUT y un gestor de archivo abierto a “/ dev / tty”?

StackOverflow https://stackoverflow.com/questions/4667154

  •  10-10-2019
  •  | 
  •  

Pregunta

¿Cuáles son las diferencias entre estos dos ejemplos?

#!/usr/bin/perl
use warnings;
use 5.012;
my $str = "\x{263a}";


open my $tty, '>:encoding(utf8)', '/dev/tty' or die $!;
say $tty $str;
close $tty;

open $tty, '>:bytes', '/dev/tty' or die $!;
say $tty $str;
close $tty;

# -------------------------------------------------------

binmode STDOUT, ':encoding(utf8)' or die $!;
say $str;

binmode STDOUT, ':bytes' or die $!;
say $str;
¿Fue útil?

Solución

La diferencia es que usted está escribiendo a dos distinta y (a partir del punto de vista de su programa de Perl y) independiente identificadores de archivo.

  • El primero es un identificador de archivo abierto en un archivo especial "dispositivo" en la Unixy OS que es "un sinónimo de la terminal de control de un proceso, si alguno " (cita de este documento Linux ). Tenga en cuenta que si bien es comúnmente considerado como "pantalla", no tiene por qué ser (por ejemplo, que el terminal podría estar relacionado con archivo de dispositivo de un puerto serie en su lugar); y puede que no existe o no ser capaz de abrirse.

  • El segundo es un archivo manejado asocia por defecto con el descriptor de fichero # 1 para el proceso.

Pueden parecen ser idénticos a primera vista, debido al hecho de que, en una situación típica, una cáscara de Unix por el asociado por defecto su descriptor de archivo # 1 (y por lo tanto uno de cada proceso se pone en marcha sin redirecciones) con /dev/tty.

Los dos tienen nada en común desde el punto de vista Perl , que no sea el hecho de que los dos comúnmente terminan asociado por defecto debido a la forma en Unix conchas de trabajo.

El comportamiento funcional de las dos piezas citadas de código a menudo parecen idénticos debido a este defecto, pero eso es sólo "por accidente".

Entre las diferencias prácticas:

  • /dev/tty no necesariamente existe en no Unixy OSs. Por lo tanto, es altamente no-portátil para uso TTY. Ventanas equivalente es IIRC CON:.

  • STDOUT de un programa puede estar asociada (re-dirigida) para nada por el que llama al programa. Podría estar asociado a un archivo, podría ser un tubo de STDIN de otro proceso.


Se puede comprobar si su STDOUT está conectado a un teléfono de texto usando el operador -t :

if ( -t STDOUT ) { say 'STDOUT is connected to a tty' }

Como otro lado, tenga en cuenta que puede asegurarse de que su STDOUT escribe a /dev/tty cerrando explícitamente el gestor de archivo STDOUT y volver a abrirlo a punto de /dev/tty:

close STDOUT or die $!;
open STDOUT '>:encoding(utf8)', '/dev/tty' or die $!;

Otros consejos

Además de lo que dijo DVK, se puede ver la diferencia sencilla diciendo

perl -le 'open $o, ">:encoding(utf8)", "/dev/tty"; print "STDOUT"; print $o "/dev/tty"' > /dev/null

La escritura a STDOUT va a /dev/null, pero la escritura a $o pasa a la pantalla.

Un programa lanzado desde un shell interactivo normalmente escribir la salida estándar a un terminal, lo que haría /dev/tty y STDOUT como el mismo destino. Pero hay varias circunstancias en las que la producción de STDOUT pudo ser escrito en algún otro destino.

STDOUT puede encaminarse a un archivo separado:

perl someprogram.pl > a/file
perl someprogram.pl >> a/file

STDOUT puede enrutarse a la entrada de otro programa

perl someprogram.pl | /usr/bin/mailx -s "Program Output" foo@bar.com

Además, el programa podría ser lanzado desde un shell no interactivo, como una tarea programada o de algún otro demonio que se ejecuta en el sistema. Los entornos de estos programas no tendrán acceso a un dispositivo /dev/tty y STDOUT en estos programas serán enviados a otra parte (o nada).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top