9

この 2 つの例の違いは何ですか?

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

3 に答える 3

13

違いは、(Perl とプログラムの観点から)独立した 2 つの別個のファイル ハンドルに書き込むことです。

  • 最初のものは、Unixy OS の特別な「デバイス」ファイルに開かれたファイル ハンドルです。これは、「プロセスの制御端末のシノニムです」 (この Linux ドキュメントからの引用)。これは一般的に「スクリーン」と考えられていますが、必ずしもそうである必要はありません (たとえば、ターミナルは代わりにシリアル ポートのデバイス ファイルにリンクすることができます)。存在しないか、開くことができない可能性があります。

  • 2 つ目は、プロセスのファイル記述子 #1 にデフォルトで関連付けられたファイル処理です。

典型的な状況では、Unix シェルはデフォルトでファイル記述子 #1 (したがって、リダイレクトなしで起動するすべてのプロセスの 1 つ) を/dev/tty.

この 2 つは Perl の観点からは何の共通点もありませんが、 Unix シェルの動作方法により、これら 2 つがデフォルトで関連付けられるという事実以外にはありません。

引用された 2 つのコード部分の機能的動作は、このデフォルトにより同一のように見えることがよくありますが、それは単なる「偶然」です。

実際の違いの中で:

  • /dev/ttyUnixy 以外の OS には必ずしも存在しません。したがって、tty を使用することは非常に移植性がありません。Windows に相当するのはCON:IIRC です。

  • STDOUTプログラムの呼び出しは、プログラムを呼び出した人が何にでも関連付ける (リダイレクトする) ことができます。ファイルに関連付けることも、別のプロセスの STDIN へのパイプにすることもできます。


-toperatorを使用して、STDOUT が tty に接続されているかどうかを確認できます。

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

余談ですが/dev/tty、STDOUT ファイルハンドルを明示的に閉じて、再度開いて を指すようにすることで、STDOUT が に書き込むことができることに注意して/dev/ttyください。

close STDOUT or die $!;
open STDOUT '>:encoding(utf8)', '/dev/tty' or die $!;
于 2011-01-12T12:05:34.007 に答える
4

対話型シェルから起動されたプログラムは、通常、標準出力を端末に書き込みます。これは、 と 同じ出力先としてレンダリング/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

また、プログラムは、cron ジョブなどの非対話型シェルから、またはシステムで実行されている他のデーモンから起動される可能性があります。/dev/ttyこれらのプログラムの環境はデバイスにアクセスできずSTDOUT、これらのプログラムでは別の場所 (またはどこにもルーティングされません) にルーティングされます。

于 2011-01-12T17:13:34.350 に答える
4

DVKが言ったことに加えて、次のように言うと単純な違いがわかります

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

への書き込みは にSTDOUT行きます/dev/nullが、 への書き込み$oは画面に行きます。

于 2011-01-12T13:09:13.440 に答える