写入 STDOUT 和打开“/dev/tty”的文件句柄有什么区别?
这两个例子有什么区别?
#!/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;
What are the differences between this two examples?
#!/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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不同之处在于,您正在写入两个不同并且(从 Perl 和您的程序的角度来看)独立文件句柄。
第一个是在 Unixy 操作系统上打开一个特殊“设备”文件的文件句柄,它是“进程控制终端的同义词,如果有”(引自 此 Linux 文档)。请注意,虽然它通常被认为是“屏幕”,但它不一定是(例如,终端可以链接到串行端口的设备文件);它可能不存在或不可打开。
第二个是默认与进程的文件描述符#1 关联的文件处理。
乍一看它们可能看起来是相同的,因为在典型情况下,Unix shell 默认情况下会将其文件描述符 #1(以及它在不重定向的情况下启动的每个进程之一)与
/dev 关联起来/tty
。从 Perl 的角度来看,两者没有任何共同点,除了由于 Unix shell 的工作方式,这两者通常最终默认关联之外。
由于这种默认设置,两个引用的代码片段的功能行为通常看起来是相同的,但这只是“偶然”的。
实际差异包括:
/dev/tty
不一定存在于非 Unixy 操作系统上。因此使用 tty 是非常不可移植的。 Windows 等效项是CON:
IIRC。STDOUT
可以由调用该程序的人关联(重定向)到任何内容。可以与一个文件相关联,也可以是到另一个进程的 STDIN 的管道。您可以使用
-t
运算符:另外,请注意,您可以通过显式关闭 STDOUT 文件句柄并重新打开它以指向
来确保 STDOUT 写入
:/dev/tty
>/dev/ttyThe difference is that you are writing to two distinct and (from Perl's and your program's point of view) independent file handles.
The first one is a file handle opened to a special "device" file on Unixy OS which is "a synonym for the controlling terminal of a process, if any" (quote from this Linux document). Please note that while it is commonly thought of as "screen", it doesn't have to be (e.g. that terminal could be linked to a serial port's device file instead); and it may not exist or not be openable.
The second one is a file handled associated by default with file descriptor #1 for the process.
They may SEEM to be identical at first glance due to the fact that, in a typical situation, a Unix shell will by default associate its file descriptor #1 (and thus one of every process it launches without redirects) with
/dev/tty
.The two have nothing in common from Perl point of view, OTHER than the fact that those two commonly end up associated by default due to the way Unix shells work.
The functional behavior of the two quoted pieces of code will often SEEM identical due to this default, but that is just "by accident".
Among practical differences:
/dev/tty
does not necessarily exist on non-Unixy OSs. It's therefore highly un-portable to use tty. Windows equivalent isCON:
IIRC.STDOUT
of a program can be associated (re-directed) to ANYTHING by whoever called the program. Could be associated to a file, could be a pipe to another process's STDIN.You can CHECK whether your STDOUT is connected to a tty by using the
-t
operator:As another aside, please note that you CAN make sure that your STDOUT writes to
/dev/tty
by explicitly closing the STDOUT filehandle and re-opening it to point to/dev/tty
:除了 DVK 所说的之外,您还可以通过说
写入
STDOUT
转到/dev/null
来看到简单的区别,但是写入$o< /code> 转到屏幕。
In addition to what DVK said, you can see the simple difference by saying
The write to
STDOUT
goes to/dev/null
, but the write to$o
goes to the screen.从交互式 shell 启动的程序通常将标准输出写入终端,这会将
/dev/tty
和STDOUT
呈现为同一目标。但在某些情况下,STDOUT
的输出可以写入其他目标。STDOUT
可以路由到单独的文件:STDOUT
可以路由到另一个程序的输入此外,该程序可以从非交互式 shell 启动,例如 cron作业或系统上运行的其他守护进程。这些程序的环境将无法访问
/dev/tty
设备,并且这些程序中的STDOUT
将被路由到其他地方(或无处)。A program launched from an interactive shell normally write standard output to a terminal, which would render
/dev/tty
andSTDOUT
as the same destination. But there are several circumstances where output toSTDOUT
could be written to some other destination.STDOUT
may be routed to a separate file:STDOUT
may be routed to the input of another programAlso, the program could be launched from a non-interactive shell, like a cron job or from some other daemon running on your system. The environments for these programs will not have access to a
/dev/tty
device, andSTDOUT
in these programs will be routed somewhere else (or nowhere).1. stdout、stderr、stdin 是什么?它们是 fd/0、fd/1、fd/2
2 的别名。 /dev/console 是什么? /dev/console 指向tty1 或ttyS0。
3. /dev/std{out, in, err} 和 tty* 设备之间有什么关系? 设备 /dev/std{out, in, err} 是一个tty* 设备的 wapper。
或者,一个更简单的例子:
1. what stdout, stderr, stdin is? they are alias for fd/0, fd/1, fd/2
2. what /dev/console is? /dev/console is pointed to tty1 or ttyS0.
3.what relationship is between the /dev/std{out, in, err} and tty* devices? the devices /dev/std{out, in, err} are a wapper of tty* devices.
or, a more simple example: