Etwas Besonderes an / dev / fd / 3

9

Ich habe versucht, etwas über Dateideskriptoren zu lernen. Wenn ich "ls -l / dev / fd /" eingebe, bekomme ich

lrwx------ 1 me users 64 May  2 16:02 0 -> /dev/pts/5
l-wx------ 1 me users 64 May  2 16:02 1 -> /home/me/file
lrwx------ 1 me users 64 May  2 16:02 2 -> /dev/pts/5
lr-x------ 1 me users 64 May  2 16:02 3 -> /proc/31518/fd

/ dev / fd / 3 scheint auf den aktuellen Prozess zu verweisen. Erklärungen zu Dateideskriptoren, die ich gesehen habe, z. B. http://www.tldp.org/LDP/abs/html/io-redirection.html , sagen jedoch nicht, dass / dev / fd / 3 (und implizieren, dass es genau wie jedes / dev / fd / N für N> 3) ist. Was ist denn hier los?

Ich habe dies unter Arch Linux und Ubuntu beobachtet, aber nicht auf dem Solaris-Server, auf dem ich einen SSH-Account habe.

qqw
quelle

Antworten:

12

/ dev / fd / 3 scheint auf den aktuellen Prozess zu verweisen.

Dh lsselbst (beachten Sie, dass pid danach nicht mehr existiert). Alle diese beziehen sich tatsächlich auf den aktuellen Prozess, da Dateideskriptoren nicht global sind. Es gibt nicht nur eine einzige 0, 1 und 2 für das gesamte System - es gibt eine separate 0, 1 und 2 für jeden Prozess.

Wie Frederik Dweerdt bemerkt, /dev/fdist ein Symlink. Wenn Sie Ihre lsvon verschiedenen Terminals wiederholen , werden Sie Links zu verschiedenen ptys bemerken. Diese stimmen mit der Ausgabe des ttyBefehls überein .

Im lsBeispiel würde ich mir vorstellen, dass Deskriptor 3 derjenige ist, der zum Lesen des Dateisystems verwendet wird. Einige C-Befehle (z. B. open()), die die Generierung von Dateideskriptoren unterstützen, garantieren die Rückgabe des "nicht verwendeten Dateideskriptors mit der niedrigsten Nummer" ( POSIX - beachten Sie, dass open () auf niedriger Ebene tatsächlich nicht Teil von Standard C ist). Sie werden also nach dem Schließen recycelt (wenn Sie verschiedene Dateien wiederholt öffnen und schließen, erhalten Sie immer wieder 3 als fd).

Wenn Sie einen Hinweis darauf erhalten möchten, wie sie entstehen, finden Sie hier einen Ausschnitt aus C-Code opendir(), den Sie wahrscheinlich in der Quelle für ls finden:

// open directory for reading
DIR *dh = opendir(".");
// print the fd of the directory handle to standard out:
printf("fd: %d\n", dirfd(dh));
closedir(dh);  

Führen Sie es so aus, wie es ist. Der fd ist 3, da dies der niedrigste nicht verwendete Deskriptor ist (0, 1 und 2 sind bereits vorhanden).

Goldlöckchen
quelle
12

/dev/fd/3ist kein Standarddeskriptor (edit: Zuweisung). Es (bearbeiten: mit mehr als 0, 1 und 2) ist spezifisch für Ihren Fall ( ls). Sie können ls durchlaufen, um zu verstehen, was passiert:

strace -e trace=openat,readlink ls -l /dev/fd/
openat(AT_FDCWD, "/dev/fd/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
readlink("/dev/fd/0", "/dev/pts/0", 65) = 10
readlink("/dev/fd/1", "/dev/pts/0", 65) = 10
readlink("/dev/fd/2", "/dev/pts/0", 65) = 10
readlink("/dev/fd/3", "/proc/28401/fd", 65) = 14

lsist, den Inhalt anzuzeigen, der /dev/fdder gleiche ist wie /proc/self/fd. lsmuss das Verzeichnis öffnen, um seine Einträge zu lesen. /dev/fd/3ist nur der Dateideskriptor für dieses Verzeichnis.

Andere Programme haben nicht /dev/fd/3:

start cmd:> sleep 100 &
[1] 28414

ec:0   17:28:10  hl@inno:~/.wine/drive_c
start cmd:> ls -l /proc/28414/fd
insgesamt 0
crw------- 1 hl tty 136, 0 18. Apr 01:18 0
crw------- 1 hl tty 136, 0 18. Apr 01:18 1
crw------- 1 hl tty 136, 0 18. Apr 01:18 2
Hauke ​​Laging
quelle
Vielleicht ist es etwas irreführend zu sagen, es sei "kein Standarddeskriptor. Es ist spezifisch für Ihren Fall ..."? 3 ist ein normaler Dateideskriptor genau wie 0, 1 und 2, aber 0, 1 und 2 haben Standardzuweisungen (Standard-In, Standard-Out, Standard-Fehler), während 3 alles sein kann. Beachten Sie, dass es möglich ist, 0, 1 und 2 auf die gleiche Weise zu verwenden, dies wird jedoch als schlechte Vorgehensweise angesehen.
Goldlöckchen
^ wäre ^ -> könnte sein, da es zwangsläufig passieren wird, wenn Sie z close(0).
Goldlöckchen
Wenn Sie bereits fd 3 verwenden, wählt ls ein anderes fd?
CMCDragonkai
@CMCDragonkai Dein Systemaufruf open()verwendet den ersten kostenlosen Dateideskriptor. Die aufrufende Anwendung sollte sich nicht um ihre Nummer kümmern. Deshalb wird es vom Anruf zurückgegeben.
Hauke ​​Laging
6

Unter Archlinux /dev/fdist ein Symlink zu /proc/self/fd. Was Sie sehen, ist das fdVerzeichnis Ihres lsBefehls. Und dieser Befehl öffnete tatsächlich das Verzeichnis als Dateideskriptor 3.

EDIT: Übrigens, ein guter Weg, um zu verstehen, was los ist, ist zu verwenden strace. Sie sehen, wie der Prozess die Dateideskriptoren öffnet.

Frederik Deweerdt
quelle