写入STDOUT和打开到“/ dev / tty”的文件句柄有什么区别?

时间:2011-01-12 09:35:19

标签: perl stdout tty filehandle

这两个例子之间有什么区别?

#!/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;

3 个答案:

答案 0 :(得分:13)

不同之处在于您正在写两个不同和(从Perl和您的程序的角度来看)独立文件句柄。

  • 第一个是在Unixy OS上打开一个特殊“设备”文件的文件句柄,它是“进程控制终端的同义词,,如果有的话”(引自this Linux document)。请注意,虽然它通常被认为是“屏幕”,但它不一定是(例如,该终端可以链接到串口的设备文件);它可能不存在或不可开放。

  • 第二个是默认关联的文件,文件描述符#1用于该过程。

由于在典型情况下,Unix shell默认情况下会将其文件描述符#1(因此在没有重定向的情况下启动的每个进程中的一个)与{{{}相关联,因此它们看起来可能相同。 1}}。

这两者从Perl的角度来看没有任何共同之处,除了这两个通常由于Unix shell工作方式而默认最终关联的事实。

由于此默认值,两个引用代码段的功能行为通常会相同,但这只是“偶然”。

实际差异:

  • /dev/tty不一定存在于非Unix操作系统上。因此使用tty非常不便携。 Windows等效项为/dev/tty IIRC。

  • 程序的
  • CON:可以被任何调用该程序的人关联(重定向)到ANYTHING。可以与文件关联,可以是到另一个进程的STDIN的管道。


您可以使用-t operator检查您的STDOUT是否已连接到tty:

STDOUT

另外请注意,您可以通过明确关闭STDOUT文件句柄并重新打开它以指向if ( -t STDOUT ) { say 'STDOUT is connected to a tty' } 来确保您的STDOUT写入/dev/tty

/dev/tty

答案 1 :(得分:4)

除了DVK所说的,你可以通过说

看到简单的区别
perl -le 'open $o, ">:encoding(utf8)", "/dev/tty"; print "STDOUT"; print $o "/dev/tty"' > /dev/null

STDOUT的写入转到/dev/null,但写入$o会转到屏幕。

答案 2 :(得分:4)

从交互式shell启动的程序通常将标准输出写入终端,这会将/dev/ttySTDOUT呈现为同一目的地。但是在某些情况下,STDOUT的输出可以写入其他目的地。

STDOUT可能会被路由到一个单独的文件:

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

STDOUT可能会被路由到另一个程序的输入

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

此外,程序可以从非交互式shell启动,如cron作业或系统上运行的其他守护程序。这些程序的环境无法访问/dev/tty设备,这些程序中的STDOUT将被路由到其他地方(或无处)。