Programmausgangsumleitung

11

Wenn Sie versuchen, die Programmausgabe mit der Syntax "Einige Zahlen größer als" (z. B. foo 2> myfile) umzuleiten , welche Zahlen sind hier möglich und was stellen sie dar?

Ich glaube 1 ist /dev/stdout, 2 ist /dev/stderr. Was ist mit 5 & 6? Gibt es 3, 4 oder eine Zahl größer als 6?

Fermats Schüler
quelle
Siehe auch Wann würden Sie einen zusätzlichen Dateideskriptor verwenden?
Gilles 'SO - hör auf böse zu sein'

Antworten:

11

Dieses angebliche Programm schreibt in die von Ihnen angegebene Dateideskriptornummer. Betrachten Sie das folgende Hallo-Welt-Programm:

#include <stdio.h>

main()
{
   ssize_t i = 0 ;
   printf ("hello world\n") ;
   i = write( 5 , "Bonjour Monde\n", 14 ) ;
   printf ("%d octet dans 5\n", (int) i) ;
}

kompiliere es

me@mybox:~/tmp7$ make hw
cc     hw.c   -o hw

jetzt ein einfacher Lauf

me@mybox:~/tmp7$ ./hw
hello world
-1 octet dans 5

Keine Datei für 5, also kein Byte geschrieben.

nächster Versuch:

me@mybox:~/tmp7$ ./hw 5> u
hello world
14 octet dans 5
me@mybox:~/tmp7$ cat u
Bonjour Monde

Ich schaffe es, eine Ausgabe zu erhalten, während ich eine Datei und einen Dateideskriptor (z 5>u. B. ) spezifiziere .

In der Praxis ist es unwahrscheinlich, dass Sie Daten mit sammeln, es sei denn, Sie haben ein so lustiges Programm wie oben geschrieben 5>foo.

Im Shell-Skript sind Konstrukte mit <() nützlicher:

 diff <( cmd -par 1 ) <(cmd -par 2)
Archemar
quelle
write()kehrt zurück ssize_t, nicht int.
Andrew Henle
Das ist nicht der Hauptpunkt der Frage, es gibt auch eine Rückgabe für die Funktion printf.
Archemar
Die Nichtverwendung eines zurückgegebenen Werts unterscheidet sich erheblich von der Verwendung des falschen Typs .
Andrew Henle
bearbeitet Ich sehe keine Änderung in der Ausgabe tho ...
Archemar
10

Die Zahlen stehen für Dateideskriptoren (Handles für geöffnete Dateien).

Die Shell hat normalerweise 3 automatisch eingestellt,

0 - stdin 1 - stdout 2 - stderr

Es können jedoch weitere Dateien geöffnet und die Zahlen erhöht werden.

X Tian
quelle
7

Diese Nummern sind Dateideskriptoren . Wie Sie bereits bemerkt haben, gibt es mehrere, die automatisch erstellt werden. Wenn andere Dateien oder dateiähnliche Dinge geöffnet werden, erhalten sie andere Nummern.

Die Nummern, die in einem bestimmten Programm verwendet werden, hängen davon ab, welche Dateien von diesem Programm geöffnet oder anderweitig verwendet wurden. Wenn Sie beispielsweise das aktuelle stdin "speichern" und stdin vorübergehend von einem anderen Ort umleiten und später wiederherstellen möchten, können Sie Folgendes tun:

exec 4<&0
exec < /some/file
#process
exec 0<&4 4<&- # restore stdin and close our duplicate

Für dieses Skript wäre also 4zumindest für einige Zeit ein Dateideskriptor verfügbar. Diese 4 kann alles sein, was nicht verwendet wird (nun, es gibt eine Begrenzung für die Anzahl der Dateien, die ein Prozess geöffnet haben kann, aber alles innerhalb dieser Begrenzung).

Sie können sehen, welche Dateideskriptoren ein Prozess geöffnet hat und wo sie geöffnet sind, indem Sie nachsehen /proc/<pid>/fd. Das zeigt alle offenen Dateideskriptoren für diesen Prozess <pid>und welche Dateien diesen zugeordnet sind.

Eric Renouf
quelle
0

Jeder Prozess erhält Ganzzahlnummern als Dateideskriptoren, wobei es in POSIX drei reservierte gibt: 0 ist stdin, 1 ist stdout und 2 ist stderr. Alle weiteren Dateien erhalten weitere Nummern. Sie können es einfach mit diesem Programm überprüfen und als fdtest.c speichern , damit es zur Laufzeit seinen eigenen Programmcode öffnet:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int fd = open("fdtest.c", O_RDONLY);
    printf("%d\n", fd);
    close(fd);
    return 0;
}

Kompiliere es:

gcc fdtest.c -o fdtest

Starte es:

./fdtest

Die Ausgabe, die Sie erhalten, ist ungefähr so:

3

... das ist die Nummer des Dateideskriptors der Datei, auf die sich die Variable bezieht fd.

Rexkogitans
quelle