Was ist der Unterschied zu STDOUT zwischen dem Schreiben und einem Dateihandle geöffnet „/ dev / tty“?

StackOverflow https://stackoverflow.com/questions/4667154

  •  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;
War es hilfreich?

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 ist CON: 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).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top