Kann man daraus schließen, dass es vier Arten von **Ausgabe** gibt, auf die wir in Linux in einer Datei verweisen können?

Kann man daraus schließen, dass es vier Arten von **Ausgabe** gibt, auf die wir in Linux in einer Datei verweisen können?

Stimmt es, dass es vier Arten vonStream-Ausgabewir können auf eine Datei in Linux verweisen, wenn wir nicht möchten, dass sie nach der Ausführung ihres Befehls in der CLI angezeigt wird?

Mögliche Verweise auf eine Datei:

  1. Alle Stream-Ausgaben
  2. Nur stderr
  3. Nur stdout (einschließlich des Endergebnisses von stdout).
  4. stdout und stderr (ohne das Endergebnis von stdout).

Anmerkungen:

Ein Beispiel für Nummer 4 könnte sein find / -type f -name php.ini 2>/dev/null. So wie ich es verstehe, erhalten wir mit diesem Befehl weder stderr noch stdout (außer demEndergebnis von stdoutDies ist in diesem Fall die gesuchte Datei, sofern sie gefunden wurde).

Antwort1

Mit jedem Prozess auf einem Unix-System sind zwei Ausgabeströme verbunden:Standardausgabe(stdout, Dateideskriptor 1) undStandart Fehler(stderr, Dateideskriptor 2). Diese können unabhängig voneinander umgeleitet werden.Standardeingabeverwendet Dateideskriptor 0.

  • Um die Standardausgabe in die Datei umzuleiten file, verwenden Sie >fileoder die explizitere Option 1>file. Ersetzen Sie filedurch , /dev/nullum die Daten zu verwerfen.
  • Um die Standardfehlermeldung zur Datei umzuleiten file, verwenden Sie 2>file.
  • Um die Standardfehlermeldung dorthin umzuleiten, wo die Standardausgabe hingeht, verwenden Sie 2>&1.
  • Um die Standardausgabe dorthin umzuleiten, wo die Standardfehlerausgabe hingeht, verwenden Sie 1>&2.

Es gibt kein Konzept des „Endergebnisses“ eines Streams oder Prozesses. Ich nehme an, dass alles, was an die Standardausgabe gesendet wird, als „Ergebnis“ eines Prozesses angesehen werden kann, es sei denn, es gibt auch Daten in eine Datei aus, die es selbst öffnet, oder es hat andere Nebeneffekte (wie das Aufheben der Verknüpfung einer Datei mit einem Verzeichnis im Fall von rmoder die Handhabung einer Reihe von Netzwerkverbindungen im Fall von sshd). Ein Prozess gibt auch einen Beendigungsstatus zurück (Null für „Erfolg“ und ungleich Null für „Fehler“), der als „Ergebnis“ dieses Prozesses angesehen werden könnte, aber dies hat nicht unbedingt etwas mit den Ausgabestreams des Prozesses zu tun.

Streams können auch umgeleitet werden inAnfügemodus, was bedeutet, dass bei einer Umleitung zu einer Datei diese Datei zunächst nicht abgeschnitten wird und alle Daten im Stream an das Ende der Datei angehängt werden. Dies geschieht durch die Verwendung von >>fileanstelle von >file.

In der Anmerkung zur Frage wird der Befehl

find / -type f -name php.ini 2>/dev/null

gegeben ist. Dies leitet um (verwirft)nurStandardfehler. Der Standardausgabestrom wird überhaupt nicht umgeleitet und ist daher in seiner Gesamtheit in der Konsole oder im Terminal sichtbar. Wenn es sich um einen Zwischenteil einer Pipeline handeln würde, würde der Standardausgabestrom in die Standardeingabe des nächsten Befehls in der Pipeline eingespeist.

Abschließend möchte ich sagen, dass eszwei(nicht vier) Ausgabeströme. Diese können unabhängig voneinander auf verschiedene Weise umgeleitet werden, was auch das Verwerfen ihres Inhalts einschließt.

Antwort2

JedenVerfahrenkann laut Konvention drei Standarddateideskriptoren verwenden. Diese Dateideskriptoren sind als Streams verfügbar: stdin, stdout, und stderr.

Wenn Sie einen Prozess von einer Shell (CLI) aus starten, wird standardmäßig der erste mit dem Eingang Ihres Terminals (oder Terminalemulators wie xterm) und die anderen beiden mit dem Ausgang Ihres Terminals verbunden.

Sie können die Shell anweisen, sie woandershin umzuleiten, beispielsweise nach /dev/null(wo sie einfach verschluckt werden). Und Sie können das unabhängig für stdoutund tun stderr. Für diesen Fall gibt es also tatsächlich vier Möglichkeiten:

command 
command > /dev/null
command 2> /dev/null
command > /dev/null 2> /dev/null

Sie können jedoch auch einen oder beide Werte woanders hin umleiten:

command > /tmp/myout 2> /tmp/myerr

In diesem Fall erhalten Sie auch keine Ausgabe in Ihrem Terminal, können diese aber später in den Dateien /tmp/myoutund lesen /tmp/myerr.

Antwort3

Die Situation ist einfacher und komplizierter, als Ihre Frage vermuten lässt. Um es zusammenzufassen:Kusalanandasagt inseine Antwortgibt es zwei standardmäßige (konventionelle) I/O-Streams (Dateideskriptoren), die konventionell konfiguriert und für die Ausgabe verwendet werden: stdout (Dateideskriptor 1) und stderr (Dateideskriptor 2). Unsere kanonische Frage, Was sind die Steuer- und Umleitungsoperatoren der Shell?, erläutert, wie man sie umleitet. Naiv betrachtet können wir fünf verschiedene Kombinationen aufzählen:

╔══════════════════════════════╦═════════════════════════════════════════════╗
║                              ║                   stderr                    ║
║                              ╟─────────────────────┬───────────────────────╢
║                              ║       default       │                       ║
║                              ║ (same as the shell) │       redirected      ║
╠════════╤═════════════════════╬═════════════════════╦═══════════════════════╣
║        │       default       ║                     ║                       ║
║        │ (same as the shell) ║          1          ║           2           ║
║        ├─────────────────────╠═════════════════════╬═══════════════════════╣
║ stdout │                     ║                     ║ 4. redirected         ║
║        │                     ║                     ║    to the same file   ║
║        │      redirected     ║          3          ╟───────────────────────╢
║        │                     ║                     ║ 5. redirected         ║
║        │                     ║                     ║    to different files ║
╚════════╧═════════════════════╩═════════════════════╩═══════════════════════╝

aber wenn Sie es /dev/nullals etwas anderes als eine Datei betrachten, den Anfügemodus als Sonderfall, den Lese-/Schreibmodus als etwas anderes als den Nur-Schreibmodus und Pipes als etwas anderes als Dateien, dann steigt die Anzahl der Kombinationen exponentiell. Wie jedoch wiederholt festgestellt wurde, ist „das Endergebnis von stdout“ kein Standardausdruck für Unix/Linux/Bash.

Nur zwei?

Die anderen Antworten (vielleicht klugerweise) beschränkten sich auf stdout und stderr (Dateideskriptoren 1 und 2). Ich bin (rücksichtslos?) der Meinung, dass eine vollständige Antwort auf diese Frage die Tatsache berücksichtigen sollte, dass andere Dateideskriptoren verfügbar sind – bis zu Hunderten, Tausenden oder sogarüber eine Million. Wenn Sie beispielsweise einen Befehl wie ausführen , öffnet sich diff file1 file2das Programm und , und der Kernel weist wahrscheinlich die Dateideskriptoren 3 und 4 zu. Der Unterschied besteht darin, dass nur die Dateideskriptoren 0, 1 und 2 vordefiniert sind. Die Umleitung von Dateideskriptoren höher als 2 wird an den folgenden Stellen erläutert:difffile1file2

Sehen Sie sich beispielsweise dieses Beispiel eines High-File-Deskriptors an:

$ Katze Hund.c
#include <stdio.h>
#include <string.h>

hauptsächlich()
{
        int i, Länge;
        char msg[] = "Hallo, Hund.\n";

        len = strlen(msg);
        i = schreibe(17, Nachricht, Länge);
        wenn (i == Länge)
                printf("Erfolgreich! i = %d = len\n", i);
        sonst wenn (i == -1)
            {
                printf("Fehler! i = %d (Länge = %d)\n", i, Länge);
                perror("");
            }
        anders
                printf("Unerwartetes Ergebnis: i = %d, len = %d\n", i, len);
}

$ machen Eckzahn
cc Hund.c -o Hund

$ ./Hund
Fehler! i = -1 (Länge = 12)
Ungültiger Dateideskriptor

$ ./Hund 17> Tier
Erfolg! i = 12 = len

$ ls -l
insgesamt 70
-rw-r--r-- 1meinBenutzername meinGruppenname    12 Apr 12 13:36 Tier
-rwxr-xr-x 1meinBenutzername meinGruppenname67067 Apr 12 13:36 Hund
-rw-r--r-- 1meinBenutzername meinGruppenname   358 Apr 12 13:36 canine.c

$ Katze Tier
Hallo Hund.

Warnung: Ich bin nicht sicher, ob das oben Genannte für alle Versionen aller Shells funktioniert.

Standardprogramme schreiben nicht in Dateideskriptoren, die höher als 2 sind (es sei denn, sie haben diesen Dateideskriptor vom Kernel erhalten, indem sie eine Datei geöffnet, eine Netzwerkverbindung hergestellt oder etwas Ähnliches gemacht haben). Wenn Sie jedoch ein (nicht standardmäßiges) Programm haben, das dies tut, können Sie diese Dateideskriptoren umleiten.

Und wenn Sie lediglich 100 Dateideskriptoren haben und nur berücksichtigen, ob jeder einzelne umgeleitet wird oder nicht, haben Sie über eine Nonillion (1.000.000.000.000.000.000.000.000.000.000) mögliche Kombinationen.

verwandte Informationen