¿Cuál es la diferencia entre escribir en STDOUT y un gestor de archivo abierto a “/ dev / tty”?
-
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;
Solución
La diferencia es que usted está escribiendo a dos distinta ??strong> 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 IIRCCON:
. -
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).