/ proc / PID / fd / X link number

36

W systemie Linux /proc/PID/fd/Xłącza do deskryptorów plików, które są potokami lub gniazdami, mają numer, na przykład:

l-wx------ 1 user user 64 Mar 24 00:05 1 -> pipe:[6839]
l-wx------ 1 user user 64 Mar 24 00:05 2 -> pipe:[6839]
lrwx------ 1 user user 64 Mar 24 00:05 3 -> socket:[3142925]
lrwx------ 1 user user 64 Mar 24 00:05 4 -> socket:[3142926]
lr-x------ 1 user user 64 Mar 24 00:05 5 -> pipe:[3142927]
l-wx------ 1 user user 64 Mar 24 00:05 6 -> pipe:[3142927]
lrwx------ 1 user user 64 Mar 24 00:05 7 -> socket:[3142930]
lrwx------ 1 user user 64 Mar 24 00:05 8 -> socket:[3142932]
lr-x------ 1 user user 64 Mar 24 00:05 9 -> pipe:[9837788]

Jak w pierwszym wierszu: 6839. Co to jest liczba reprezentująca?

Tanatos
źródło

Odpowiedzi:

36

Jest to numer i- węzła dla danej rury lub gniazda.

Potok jest kanałem jednokierunkowym z końcem zapisu i końcem odczytu. W twoim przykładzie wygląda na to, że FD 5 i FD 6 rozmawiają ze sobą, ponieważ numery i-węzłów są takie same. (Może jednak nie. Zobacz poniżej.)

Bardziej powszechne niż oglądanie programu rozmawiającego z sobą przez potok jest para oddzielnych programów rozmawiających ze sobą, zwykle dlatego, że konfigurujesz potok między nimi za pomocą powłoki:

shell-1$ ls -lR / | less

Następnie w innym oknie terminala:

shell-2$ ...find the ls and less PIDs with ps; say 4242 and 4243 for this example...
shell-2$ ls -l /proc/4242/fd | grep pipe
l-wx------ 1 user user 64 Mar 24 12:18 1 -> pipe:[222536390]
shell-2$ ls -l /proc/4243/fd | grep pipe
l-wx------ 1 user user 64 Mar 24 12:18 0 -> pipe:[222536390]

Oznacza to, że standardowe wyjście PID 4242 (FD 1, zgodnie z konwencją) jest podłączone do rury o numerze i-węzła 222536390, a standardowe wejście PID 4243 (FD 0) jest podłączone do tej samej rury.

Wszystko to stanowi długą drogę do stwierdzenia, że lsdane wyjściowe są wysyłane do lessdanych wejściowych.

Wracając do twojego przykładu, FD 1 i FD 2 prawie na pewno nie rozmawiają ze sobą. Najprawdopodobniej jest to wynik połączenia stdout (FD 1) i stderr (FD 2), więc obaj idą do tego samego miejsca docelowego. Możesz to zrobić za pomocą takiej powłoki Bourne'a:

$ some-program 2>&1 | some-other-program

Tak więc, jeśli zajrzysz do środka /proc/$PID_OF_SOME_OTHER_PROGRAM/fd, znajdziesz trzecią FD dołączoną do rury o takim samym numerze i-węzła, jak dla FD 1 i 2 dla some-programinstancji. Być może tak dzieje się w przypadku twojego FD 5 i 6, ale nie mam gotowej teorii, w jaki sposób te dwa FD zostały ze sobą powiązane. Musisz dowiedzieć się, co program robi wewnętrznie, aby to zrozumieć.

Warren Young
źródło
1
Myślę, że przykładem był pidgin- miał wiele rur i gniazd i innych rzeczy, więc był to dobry przykład. Ostatnie pytanie: i-węzły są specyficzne tylko w kontekście konkretnego systemu plików, prawda? W tej chwili mógłbym mieć i-węzeł 3 w moim /systemie plików, a inny (inny) i-węzeł 3 w moim /bootsystemie plików.
Tanatos
4
Tak. W przypadku /procsystemu plików numery i-węzłów są tworzone w locie (patrz get_next_ino()w fs/inode.cjądrze), zaczynając od 0, gdy system jest świeżo uruchamiany. Mechanizm, który je tworzy, jest współużytkowany przez kilka nieistotnych systemów plików Linuksa (proc, configfs, ramfs, autofs ...), wśród których numery i-węzłów unikalne, chociaż semantyka POSIX tego nie wymaga. To jednak dość szczególny przypadek. Reguła, o której mówisz, jest zwykle przywoływana w połączeniu z normalnymi trwałymi systemami plików, takimi jak ext3.
Warren Young,
33

Dla gniazd można znaleźć więcej informacji na temat węzła w /proc/net/tcp, /proc/net/udplub /proc/net/unix. Na przykład:

ls -l /proc/<pid>/fd
lrwx------ 1 root root 64 May 26 22:03 3 -> socket:[53710569]

Widzimy, że i-węzeł to 53710569.

head -n1 < tcp ; grep -a 53710569 tcp
sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                   
155: 0100007F:001B 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0        0 53710569 1 ffff88011f52c200 300 0 0 2 -1

W tym przypadku jest to gniazdo nasłuchujące (brak adresu zdalnego), nasłuchujące na lokalnym porcie 27 (0x1B). Adres IP ma 4 bajty szesnastkowe w „notacji sieciowej”, możesz użyć inet_ntoafunkcji do konwersji na standardową notację abcd (w tym przypadku 127.0.0.1).

Zauważ, że te pliki wydają się mieć 0 bajtów, ale mają treść, jeśli je czytasz. Zauważ też, że -ajest to wymagane w przypadku grep, ponieważ mogą (np. Z unix) wyglądać na binarne.

Marki555
źródło
Jest też /proc/net/tcp6i /proc/net/udp6dla IPv6.
Craig McQueen