Standardstreams - Standard streams

In der Computerprogrammierung , Standardströme miteinander verbunden sind Eingangs- und Ausgangskommunikationskanäle zwischen einem Computerprogramm und seiner Umgebung , wenn es der Ausführung beginnt. Die drei Input/Output (I/O) Verbindungen heißen Standard Input ( stdin ), Standard Output ( stdout ) und Standard Error ( stderr ). Ursprünglich geschah I/O über eine physisch angeschlossene Systemkonsole (Eingabe über Tastatur, Ausgabe über Monitor), aber Standardstreams abstrahieren dies. Wenn ein Befehl über eine interaktive Shell ausgeführt wird , sind die Streams normalerweise mit dem Textterminal verbunden, auf dem die Shell ausgeführt wird, können jedoch mit Umleitung oder einer Pipeline geändert werden . Allgemeiner gesagt erbt ein Kindprozess die Standardströme seines Elternprozesses .

Anwendung

Die Standardstreams für Eingabe, Ausgabe und Fehler

Benutzer kennen Standardstreams im Allgemeinen als Eingabe- und Ausgabekanäle, die Daten verarbeiten, die von einem Eingabegerät kommen, oder die Daten von der Anwendung schreiben. Die Daten können Text mit beliebiger Codierung oder binäre Daten sein . In vielen modernen Systemen wird der Standardfehlerstrom eines Programms in eine Protokolldatei umgeleitet, typischerweise zu Fehleranalysezwecken.

Streams können verwendet werden, um Anwendungen zu verketten, was bedeutet, dass der Ausgabestream eines Programms als Eingabestream zu einer anderen Anwendung umgeleitet werden kann. In vielen Betriebssystemen wird dies durch die Auflistung der Anwendungsnamen ausgedrückt, getrennt durch den vertikalen Strich, aus diesem Grund oft als Pipeline- Zeichen bezeichnet. Ein bekanntes Beispiel ist die Verwendung einer Paginierungsanwendung , wie z. B. more , die dem Benutzer die Kontrolle über die Anzeige des Ausgabestroms auf der Anzeige bietet.

Hintergrund

In den meisten Betriebssystemen vor Unix mussten sich Programme explizit mit den entsprechenden Eingabe- und Ausgabegeräten verbinden. Betriebssystemspezifische Feinheiten machten dies zu einer mühsamen Programmieraufgabe. Auf vielen Systemen war es notwendig, die Umgebungseinstellungen zu kontrollieren, auf eine lokale Dateitabelle zuzugreifen, den beabsichtigten Datensatz zu bestimmen und die Hardware im Falle eines Lochkartenlesers , Magnetbandlaufwerks , Diskettenlaufwerks , Zeilendruckers , Kartenlochers richtig zu handhaben , oder interaktives Terminal.

Einer von mehreren bahnbrechenden Fortschritten von Unix waren abstrakte Geräte , die es einem Programm überflüssig machten , zu wissen oder sich darum zu kümmern, mit welcher Art von Geräten es kommunizierte. Ältere Betriebssysteme zwangen dem Programmierer eine Datensatzstruktur und häufig nicht orthogonale Datensemantik und Gerätesteuerung auf. Unix beseitigte diese Komplexität mit dem Konzept eines Datenstroms: einer geordneten Folge von Datenbytes, die bis zum Ende der Datei gelesen werden können . Ein Programm kann auch Bytes nach Wunsch schreiben und muss dies nicht und kann ihre Anzahl oder Gruppierung nicht leicht deklarieren.

Ein weiterer Unix-Durchbruch bestand darin, die Eingabe und Ausgabe standardmäßig automatisch der Terminal-Tastatur bzw anderes Paradigma). Im Gegensatz dazu erforderten frühere Betriebssysteme normalerweise eine – oft komplexe – Jobsteuerungssprache , um Verbindungen herzustellen, oder der entsprechende Aufwand musste vom Programm orchestriert werden.

Da Unix Standard-Streams bereitstellte, war die Unix- C- Laufzeitumgebung verpflichtet, dies ebenfalls zu unterstützen. Daher bieten die meisten C-Laufzeitumgebungen (und die Nachkommen von C ) unabhängig vom Betriebssystem eine gleichwertige Funktionalität.

Standardeingabe (stdin)

Standardeingabe ist ein Stream, aus dem ein Programm seine Eingabedaten liest. Das Programm fordert Datenübertragungen unter Verwendung der Leseoperation an . Nicht alle Programme erfordern eine Stream-Eingabe. Beispielsweise können die Programme dir und ls (die in einem Verzeichnis enthaltene Dateinamen anzeigen) Befehlszeilenargumente annehmen , aber ihre Operationen ohne Eingabe von Stream-Daten ausführen.

Sofern nicht umgeleitet , wird die Standardeingabe vom übergeordneten Prozess geerbt. Im Fall einer interaktiven Shell ist dies normalerweise mit der Tastatur verbunden .

Der Dateideskriptor für die Standardeingabe ist 0 (null); die POSIX <unistd.h> Definition ist STDIN_FILENO; die entsprechende C <stdio.h> -Variable ist FILE* stdin; ähnlich ist die C++- Variable <iostream>std::cin .

Standardausgabe (stdout)

Standardausgabe ist ein Stream, in den ein Programm seine Ausgabedaten schreibt. Mit der Schreiboperation fordert das Programm die Datenübertragung an . Nicht alle Programme erzeugen eine Ausgabe. Der Befehl zum Umbenennen von Dateien (auch als mv , move oder ren bezeichnet ) ist beispielsweise bei Erfolg stumm.

Sofern nicht umgeleitet , wird die Standardausgabe vom übergeordneten Prozess geerbt. Im Fall einer interaktiven Shell ist dies normalerweise das Textterminal , das das Programm gestartet hat.

Der Dateideskriptor für die Standardausgabe ist 1 (eins); die POSIX <unistd.h> Definition ist STDOUT_FILENO; die entsprechende C <stdio.h> -Variable ist FILE* stdout; ähnlich ist die C++- Variable <iostream>std::cout .

Standardfehler (stderr)

Standardfehler ist ein weiterer Ausgabestrom, der typischerweise von Programmen verwendet wird, um Fehlermeldungen oder Diagnosen auszugeben . Es ist ein Stream unabhängig von der Standardausgabe und kann separat umgeleitet werden. Dies löst das Semi-Prädikat-Problem , wodurch Ausgabe und Fehler unterschieden werden können, und ist analog zu einer Funktion, die ein Wertepaar zurückgibt – siehe Semi-Prädikat-Problem: Mehrwertige Rückgabe . Das übliche Ziel ist das Textterminal, das das Programm gestartet hat, um die besten Chancen zu bieten, gesehen zu werden, auch wenn die Standardausgabe umgeleitet wird (also nicht ohne weiteres zu beobachten ist). Beispielsweise wird die Ausgabe eines Programms in einer Pipeline an die Eingabe des nächsten Programms umgeleitet, aber Fehler von jedem Programm gehen immer noch direkt an das Textterminal.

Es ist akzeptabel und normal, die Standardausgabe und die Standardfehlermeldung an dasselbe Ziel zu leiten , beispielsweise an das Textterminal. Nachrichten werden in der gleichen Reihenfolge angezeigt, in der das Programm sie schreibt, es sei denn, es handelt sich um eine Pufferung . In üblichen Situationen ist beispielsweise der Standardfehlerstrom ungepuffert, aber der Standardausgabestrom ist zeilengepuffert; In diesem Fall kann später in Standardfehler geschriebener Text früher auf dem Terminal erscheinen, wenn der Standardausgabestrompuffer noch nicht voll ist.

Der Dateideskriptor für Standardfehler wird von POSIX als 2 (zwei) definiert; die Header-Datei <unistd.h> enthält das Symbol STDERR_FILENO; die entsprechende C <stdio.h> -Variable ist FILE* stderr. Der C++- Standardheader <iostream> stellt zwei Variablen bereit, die diesem Stream zugeordnet sind: std::cerrund std::clog, wobei erstere ungepuffert ist und letztere denselben Pufferungsmechanismus wie alle anderen C++-Streams verwendet.

Bourne -Stil shells erlauben Standardfehler an das gleiche Ziel umgeleitet werden , dass die Standardausgabe zur Verwendung gerichtet ist

 2>&1

CSH -Stil shells erlauben Standardfehler an das gleiche Ziel umgeleitet werden , dass die Standardausgabe zur Verwendung gerichtet ist

 >&

Der Standardfehler wurde in den 1970er Jahren zu Unix hinzugefügt, nachdem mehrere verschwendete Fotosatzläufe damit endeten, dass Fehlermeldungen gesetzt und nicht auf dem Terminal des Benutzers angezeigt wurden.

Zeitleiste

1950er: Fortran

Fortran hat das Äquivalent zu Unix-Dateideskriptoren: Laut Konvention verwenden viele Fortran-Implementierungen Unit-Nummern UNIT=5für stdin, UNIT=6für stdout und UNIT=0für stderr. In Fortran-2003 die intrinsische ISO_FORTRAN_ENVwurde Modul standardisiert die genannten Konstanten sind INPUT_UNIT, OUTPUT_UNITund ERROR_UNITzu portably die Einheitsnummern angeben.

! FORTRAN 77 example
      PROGRAM MAIN
        INTEGER NUMBER
        READ(UNIT=5,*) NUMBER
        WRITE(UNIT=6,'(A,I3)') ' NUMBER IS: ',NUMBER
      END
! Fortran 2003 example
program main
  use iso_fortran_env
  implicit none
  integer :: number
  read (unit=INPUT_UNIT,*) number
  write (unit=OUTPUT_UNIT,'(a,i3)') 'Number is: ', number
end program

1960: ALGOL 60

ALGOL 60 wurde dafür kritisiert, dass es keinen Standard-Dateizugriff hat.

1968: ALGOL 68

Die Eingabe- und Ausgabeeinrichtungen von ALGOL 68 wurden zusammenfassend als Transput bezeichnet. Koster koordinierte die Definition des Transportstandards . Das Modell enthielt drei Standardkanäle: stand in, stand out, und stand back.

Beispiel
# ALGOL 68 example #
main:(
  REAL number;
  getf(stand in,($g$,number));
  printf(($"Number is: "g(6,4)"OR "$,number)); # OR #
  putf(stand out,($" Number is: "g(6,4)"!"$,number));
  newline(stand out)
)
Eingang: Ausgabe:
3.14159
Number is: +3.142 OR Number is: +3.142!

1970er: C und Unix

In der Programmiersprache C werden die standardmäßigen Eingabe-, Ausgabe- und Fehlerströme an die vorhandenen Unix-Dateideskriptoren 0, 1 bzw. 2 angehängt. In einer POSIX- Umgebung sollten statt der magischen Zahlen die < unistd.h > -Definitionen STDIN_FILENO , STDOUT_FILENO oder STDERR_FILENO verwendet werden . Die Dateizeiger stdin , stdout und stderr werden ebenfalls bereitgestellt.

Ken Thompson (Designer und Implementierer des ursprünglichen Unix-Betriebssystems) änderte die Sortierung in Version 5 Unix , um "-" als Standardeingabe zu akzeptieren, die sich auf andere Dienstprogramme ausbreitete und in Version 8 als spezielle Datei Teil des Betriebssystems wurde . Diagnosen waren bis Version 6 Teil der Standardausgabe , woraufhin Dennis M. Ritchie das Konzept des Standardfehlers entwickelte.

1995: Java

In Java werden die Standardstreams mit System.in(für stdin), System.out(für stdout) und System.err(für stderr) bezeichnet.

public static void main(String args[]) {
    try {
        BufferedReader br = 
          new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        double number = Double.parseDouble(s);
        System.out.println("Number is:" + number);
    } catch (Exception e) {
        System.err.println("Error:" + e.getMessage());
    }
}

2000er: .NET

In C# und anderen .NET- Sprachen werden die Standardstreams durch System.Console.In(für stdin), System.Console.Out(für stdout) und System.Console.Error(für stderr) bezeichnet. Auf grundlegende Lese- und Schreibfähigkeiten für die Streams stdin und stdout kann auch direkt über die Klasse zugegriffen werden System.Console(zB System.Console.WriteLine()kann anstelle von verwendet werden System.Console.Out.WriteLine()).

System.Console.In, System.Console.Outund System.Console.Errorsind System.IO.TextReader(stdin) und System.IO.TextWriter(stdout, stderr) Objekte, die nur textbasiert den Zugriff auf die zugrunde liegenden Standardstreams erlauben. Voll binären Zugriff auf die Standard - Streams müssen durch die durchgeführt werden , System.IO.Streamvon zurückgegebenen Objekte System.Console.OpenStandardInput(), System.Console.OpenStandardOutput()und System.Console.OpenStandardError()jeweils.

// C# example
public static int Main(string[] args)
{
    try {
        string s = System.Console.In.ReadLine();
        double number = double.Parse(s);
        System.Console.Out.WriteLine("Number is: {0:F3}", number);
        return 0;

    // If Parse() threw an exception
    } catch (ArgumentNullException) { 
        System.Console.Error.WriteLine("No number was entered!");
    } catch (FormatException) {
        System.Console.Error.WriteLine("The specified value is not a valid number!");
    } catch (OverflowException) {
        System.Console.Error.WriteLine("The specified number is too big!");
    }

    return -1;
}
' Visual Basic .NET example

Public Function Main() As Integer
    Try
        Dim s As String = System.Console.[In].ReadLine()
        Dim number As Double = Double.Parse(s)
        System.Console.Out.WriteLine("Number is: {0:F3}", number)
        Return 0

    ' If Parse() threw an exception
    Catch ex As System.ArgumentNullException
        System.Console.[Error].WriteLine("No number was entered!")
    Catch ex2 As System.FormatException
        System.Console.[Error].WriteLine("The specified value is not a valid number!")
    Catch ex3 As System.OverflowException
        System.Console.[Error].WriteLine("The specified number is too big!")
    End Try

    Return -1
End Function

Bei Anwendung der System.Diagnostics.Process Klasse kann man die Instanz verwenden Eigenschaften StandardInput , StandardOutputund StandardErrordieser Klasse den Zugriff auf den Standard - Streams des Prozesses.

GUIs

Grafische Benutzeroberflächen (GUIs) verwenden nicht immer die Standardstreams; Sie tun es, wenn GUIs Wrapper von zugrunde liegenden Skripten und/oder Konsolenprogrammen sind, zum Beispiel die Synaptic- Paketmanager-GUI, die apt-Befehle in Debian und/oder Ubuntu umschließt. GUIs, die mit Skriptwerkzeugen wie Zenity und KDialog vom KDE- Projekt erstellt wurden, verwenden stdin, stdout und stderr und basieren auf einfachen Skripten und nicht auf einer vollständigen GUI, die in C/C++ mit Qt , GTK oder einem anderen gleichwertigen proprietären Widget programmiert und kompiliert wurde Rahmen.

Das Menü Dienste , wie es in NeXTSTEP und Mac OS X implementiert ist, entspricht ebenfalls den Standard-Streams. Auf diesen Betriebssystemen können grafische Anwendungen Funktionen über ein systemweites Menü bereitstellen , das unabhängig von der Anwendung auf die aktuelle Auswahl in der GUI wirkt .

Einige GUI-Programme, hauptsächlich unter Unix, schreiben immer noch Debug-Informationen in den Standardfehler. Andere (wie viele Unix-Mediaplayer) können Dateien von der Standardeingabe lesen. Beliebte Windows-Programme, die zusätzlich zu ihren GUI-Fenstern ein separates Konsolenfenster öffnen, sind die Emulatoren pSX und DOSBox .

GTK-Server kann stdin als Kommunikationsschnittstelle mit einem interpretierten Programm verwenden, um eine GUI zu realisieren.

Das Common Lisp Interface Manager- Paradigma "präsentiert" GUI-Elemente, die an einen erweiterten Ausgabestrom gesendet werden.

Siehe auch

Verweise

Quellen

Externe Links