/ proc / PID / fd / X номер ссылки

36

В Linux /proc/PID/fd/Xссылки на файловые дескрипторы, представляющие собой каналы или сокеты, имеют номер, например:

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]

Как в первой строке: 6839. Что представляет собой это число?

Танатос
источник

Ответы:

36

Это номер инода для рассматриваемой трубы или сокета.

Канал - это однонаправленный канал с концом записи и концом чтения. В вашем примере, похоже, что FD 5 и FD 6 разговаривают друг с другом, поскольку номера инодов одинаковы. (Возможно, нет. См. Ниже.)

Более распространенным, чем наблюдение программы, говорящей с самим собой по каналу, является пара отдельных программ, взаимодействующих друг с другом, обычно потому, что вы устанавливаете канал между ними с помощью оболочки:

shell-1$ ls -lR / | less

Затем в другом окне терминала:

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]

Это говорит о том, что стандартный выход PID 4242 (FD 1, по соглашению) подключен к каналу с номером инода 222536390, и что стандартный вход PID 4243 (FD 0) подключен к той же трубе.

Все это долгий способ сказать, что lsвывод отправляется на lessвход.

Возвращаясь к вашему примеру, FD 1 и FD 2 почти наверняка не разговаривают друг с другом. Скорее всего, это результат связывания stdout (FD 1) и stderr (FD 2) вместе, поэтому они оба отправляются в один и тот же пункт назначения. Вы можете сделать это с помощью оболочки Bourne следующим образом:

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

Таким образом, если вы заглядываете внутрь /proc/$PID_OF_SOME_OTHER_PROGRAM/fd, вы обнаружите третий FD, подключенный к каналу с тем же номером инода, что и для FD 1 и 2 для some-programэкземпляра. Это также может быть тем, что происходит с FD 5 и 6 в вашем примере, но у меня нет готовой теории, как эти два FD были связаны вместе. Вы должны знать, что программа делает внутри, чтобы понять это.

Уоррен Янг
источник
1
Пример, я думаю, был pidgin- у него было много трубок, розеток и прочего, поэтому был хороший пример. Последний вопрос: inode специфичны только в контексте конкретной файловой системы, верно? Например, у меня может быть инод 3 в моей /файловой системе и другой (другой) инод 3 в моей /bootфайловой системе.
Танатос
4
Да. В случае /procфайловой системы номера инодов просто создаются на лету (см. get_next_ino()В fs/inode.cядре), начиная с 0, когда система загружается заново. Механизм , который делает их разделяют несколько impersistent файловых систем для Linux (Proc, configfs, RamFs, AutoFS ...) , среди которых номера индексных дескрипторов являются уникальными , даже если семантика POSIX не требуют его. Это довольно частный случай, однако. Правило, о котором вы говорите, обычно упоминается в связи с обычными постоянными файловыми системами, такими как ext3.
Уоррен Янг
33

Для сокетов вы можете найти больше информации об inode /proc/net/tcp, /proc/net/udpили /proc/net/unix. Например:

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

Мы видим, что индекс 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

В этом случае это прослушивающий сокет (без удаленного адреса), который прослушивает локальный порт 27 (0x1B). IP-адреса имеют 4 байта в шестнадцатеричном формате в «сетевой нотации», вы можете использовать inet_ntoaфункцию для преобразования ее в стандартную нотацию abcd (в данном случае 127.0.0.1).

Обратите внимание, что эти файлы имеют размер 0 байт, но имеют содержимое, если вы их читаете. Также обратите внимание, что -aтребуется с grep, так как они могут (например, с unix) быть двоичными.

Marki555
источник
Там же /proc/net/tcp6и /proc/net/udp6для IPv6.
Крейг МакКуин