这两个例子有什么区别?
#!/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;
解决方法
不同之处在于您正在写入两个独立的文件句柄(从Perl和程序的角度来看).
>第一个是Unixy OS上特殊的“设备”文件打开的文件句柄,它是“进程的控制终端的一个同义词(如果有的话)”(从this Linux document引用).请注意,虽然通常被认为是“屏幕”,但不一定是(例如,该终端可以链接到串行端口的设备文件);它可能不存在或不可开放.
>第二个是处理关联的文件,文件描述符#1用于进程.
由于在典型情况下,Unix shell将默认将/ dev / tty与其文件描述符#1(因此每个进程之间没有重定向启动)将它们关联起来,所以它们可能一目了然.
这两个与Perl的观点没有任何共同之处,除了这两个事实之外,由于Unix shell的工作原理,这两个默认情况下默认关联.
由于这个默认值,两个引用的代码段的功能行为通常会相同,但这只是“意外”.
实际差异:
> / dev / tty不一定存在于非Unixy操作系统上.因此,使用tty非常不可移植. Windows等效于CON:IIRC.
程序的STDOUT可以由任何调用程序的人关联(重定向)到任何人.可以关联到一个文件,可以是管道到另一个进程的STDIN.
您可以检查您的STDOUT是否通过使用-t
operator连接到tty:
if ( -t STDOUT ) { say 'STDOUT is connected to a tty' }
另一方面,请注意,您可以确保STDOUT通过明确地关闭STDOUT文件句柄并重新打开它来指向/ dev / tty来写入/ dev / tty:
close STDOUT or die $!; open STDOUT '>:encoding(utf8)','/dev/tty' or die $!;