Was ist der Unterschied zu STDOUT zwischen dem Schreiben und einem Dateihandle geöffnet „/ dev / tty“?
-
10-10-2019 - |
Frage
Was sind die Unterschiede zwischen diesen beiden Beispielen?
#!/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;
Lösung
Der Unterschied ist, dass Sie zwei schreiben verschieden und (von Perl und Ihrem Programm Sicht) unabhängige Datei-Handles.
-
Die erste ist eine Datei-Handle zu einer speziellen „device“ Datei auf Unixy OS geöffnet, die „ein Synonym für den Steueranschluss eines Prozesses, , wenn ein “ ist (Zitat aus dieses Linux Dokument ). Bitte beachten Sie, dass es zwar häufig als „Bildschirm“ gedacht wird, es nicht zu sein braucht (zum Beispiel, dass der Anschluss an eine serielle Schnittstelle des Geräts Datei verknüpft werden könnten statt); und es kann existieren oder nicht nicht zu öffnen sein.
-
Die zweite ist eine Datei standardmäßig mit Dateideskriptor # 1 für den Prozess verbunden abgewickelt.
Sie scheinen auf den ersten Blick identisch zu sein aufgrund der Tatsache, dass in einer typischen Situation, ein Unix-Shell wird standardmäßig assoziiertes seine Dateideskriptors # 1 (und damit zu jedem Prozess startet es ohne Umleitungen) mit /dev/tty
.
Die beiden haben nichts gemein von Perl Sicht , außer der Tatsache, dass diese beiden häufig standardmäßig zugeordnet sind am Ende aufgrund der Art und Weise Unix-Shells arbeiten.
Das funktionale Verhalten der beiden genannten Teile des Codes werden oft SEEM identisch aufgrund dieser Standard, aber das ist nur „zufällig“.
Unter praktischen Unterschieden:
-
/dev/tty
existiert nicht unbedingt auf nicht-Unixy oss. Es ist daher sehr un-portable Nutzung tty. Windows-Äquivalent istCON:
IIRC. -
STDOUT
eines Programms kann durch (Wieder- gerichtete) zu ANYTHING in Verbindung gebracht werden, wer das Programm genannt. Könnte in eine Datei zugeordnet werden, könnte ein Rohr an einem anderen Prozess der STDIN sein.
können Sie überprüfen, ob Ihr STDOUT an einen tty verbunden wird unter Verwendung des -t
Operator :
if ( -t STDOUT ) { say 'STDOUT is connected to a tty' }
Wie andere beiseite, beachten Sie bitte, dass Sie können sicherstellen, dass Ihre STDOUT /dev/tty
schreibt durch die STDOUT- Dateikennung explizit zu schließen und wieder zu öffnen, es zu Punkt /dev/tty
:
close STDOUT or die $!;
open STDOUT '>:encoding(utf8)', '/dev/tty' or die $!;
Andere Tipps
Zusätzlich zu dem, was DVK sagte, können Sie den einfachen Unterschied mit den Worten:
perl -le 'open $o, ">:encoding(utf8)", "/dev/tty"; print "STDOUT"; print $o "/dev/tty"' > /dev/null
Die Schreib zu STDOUT
zu /dev/null
geht, aber der Schreibvorgang auf $o
geht auf den Bildschirm.
Ein Programm aus einer interaktiven Shell gestartet schreibt normalerweise die Standardausgabe mit einem Terminal, das /dev/tty
und STDOUT
als das gleiche Ziel machen würde. Aber es gibt einige Situationen, in denen Ausgabe STDOUT
an einem anderen geschrieben werden.
STDOUT
in eine separate Datei geführt werden kann:
perl someprogram.pl > a/file
perl someprogram.pl >> a/file
STDOUT
an den Eingang eines anderen Programms geleitet werden
perl someprogram.pl | /usr/bin/mailx -s "Program Output" foo@bar.com
Auch könnte das Programm aus einem nicht-interaktiv Shell gestartet werden, wie ein Cron-Job oder von einem anderen Daemon auf dem System ausgeführt wird. Die Umgebungen für diese Programme keinen Zugriff auf ein /dev/tty
Gerät haben, und STDOUT
in diesen Programmen wird woanders zu verlegen (oder nirgendwo).