How to list the open file descriptors (and the files they refer to) in my current bash session
I am running in an interactive bash session. I have created some file descriptors, using exec, and I would like to list what is the current status of my bash session. Is there a way to list the currently open file descriptors?
bash is not part of the kernel, so it can not know what other processes are doing, even those that it started.
@JuliePelletier: but child processes do not change the file descriptors of the parent process, do they?
5 Answers 5
Yes, this will list all open file descriptors:
$ ls -l /proc/$$/fd total 0 lrwx------ 1 isaac isaac 64 Dec 28 00:56 0 -> /dev/pts/6 lrwx------ 1 isaac isaac 64 Dec 28 00:56 1 -> /dev/pts/6 lrwx------ 1 isaac isaac 64 Dec 28 00:56 2 -> /dev/pts/6 lrwx------ 1 isaac isaac 64 Dec 28 00:56 255 -> /dev/pts/6 l-wx------ 1 isaac isaac 64 Dec 28 00:56 4 -> /home/isaac/testfile.txt
Of course, as usual: 0 is stdin, 1 is stdout and 2 is stderr.
The 4th is an open file (to write) in this case.
@JZ. $$ will give the process ID of the currently running shell. Try echo $$ and ps and compare their outputs. Similar question here.
Assuming you want to list the file descriptors that are attached to any terminal, you can use lsof / fuser or similar like:
$ lsof -p $$ 2>/dev/null | awk '$NF ~ /\/pts\//' bash 32406 foobar 0u CHR 136,31 0t0 34 /dev/pts/31 bash 32406 foobar 1u CHR 136,31 0t0 34 /dev/pts/31 bash 32406 foobar 2u CHR 136,31 0t0 34 /dev/pts/31 bash 32406 foobar 3u CHR 136,31 0t0 34 /dev/pts/31 bash 32406 foobar 255u CHR 136,31 0t0 34 /dev/pts/31
These tools basically parse /proc , so you can just access /proc/$$/fd/ too e.g.:
Use the lsof utility to print all file descriptors for the current shell process (process identified by -p $$ ) and ( -a ) where the file descriptor is numeric ( -d 0-256 ):
$ lsof -p $$ -a -d 0-256 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 16883 ant 0u CHR 136,15 0t0 18 /dev/pts/15 bash 16883 ant 1u CHR 136,15 0t0 18 /dev/pts/15 bash 16883 ant 2u CHR 136,15 0t0 18 /dev/pts/15 bash 16883 ant 255u CHR 136,15 0t0 18 /dev/pts/15
Pipe into Awk to print only the file descriptor and its corresponding filename:
$ lsof -p $$ -a -d 0-256 | awk '< printf("%4s:\t%s\n", $4, $NF) >' FD: NAME 0u: /dev/pts/15 1u: /dev/pts/15 2u: /dev/pts/15 255u: /dev/pts/15
Note: when lsof prints the file descriptors, it appends the following code to indicate the file access mode:
Файловые дескрипторы
Пытаюсь разобраться в файловых дескрипторах. Читаю разные статьи, пока не очень понятно как потрогать эти самые дескрипторы.
Вот я выбрал интересующий процесс (vlc с открытым фильмом).
По идее это покажет список всех файлов, открытых процессом, а заодно и их дескрипторы. Ожидал увидеть 1 строку с названием фильма. А там (помимо фильма) — просто МИЛЛИОННАЯ ПРОСТЫНЯ! Сотни файлов типа dir, reg, chr, fifo, unix, a_inode. Что это такое?
Неужели, чтобы плеер запустил простое видео, нужно действительно открыть сотни этих файлов?
Отдельно заинтересовала графа FD (думал что это файловый дескриптор). Там всякие cwd, rtd, mem, del, txt. а ближе к концу вида «0r, 1w, 2w, 3r. 26u. » и т.д. Что это означает? Я читал, что файловый дескриптор это целое число. Значит, это не файловый дескриптор?
Еще интересно что значат числа вроде «253,1» и «0,12» в графе device.
Еще нашел какую-то команду:
List File Descriptors in Kernel Memory
Но что-то не то выдает. Хотелось получить файловый дескриптор одного из файлов, вызванных процессом vlc, например.
Хотелось получить файловый дескриптор одного из файлов, вызванных процессом vlc, например.
А зачем? Это просто небольшое число. Обычно от 5 до 15.
Чтобы убедиться, у всех ли файлов он есть, уникальный ли он. Пока я что-то ни одной команды не нашел, чтобы посмотреть дескриптор, читаю man, как советовали выше.
Это просто небольшое число. Обычно от 5 до 15.
Про дескрипторы 0, 1 и 2 я уже прочитал в вики. С этими числами я уже сталкивался в теме перенаправления ввода-вывода в консоли. Думал что это какие-то особенные дескрипторы, а все остальные уникальны, вроде PID’ов. Но вот ты говоришь что это не так, осталось только найти способ проверить.
А зачем? Это просто небольшое число. Обычно от 5 до 15.
А существует ли практическая польза от этих знаний? Наверно где-то в программировании используется номер дескриптора?
чтобы плеер запустил простое видео
ну ты чел. хотел бы я посмотреть, как ты пишешь «простую» реализацию «простого» декодера h264, многопоточного и все дела. а потом собственно весь плеер с реализацией всех возможностей что он предоставляет
Неужели, чтобы плеер запустил простое видео, нужно действительно открыть сотни этих файлов?
Скорее всего открыты shared библиотеки, необходимые для запуска и работы приложения
Пытаюсь разобраться в файловых дескрипторах. Читаю разные статьи, пока не очень понятно как потрогать эти самые дескрипторы.
С какой целью интересуетесь? Тяжело внятно объяснить, не ударившись в программирование.
Сотни файлов типа dir, reg, chr, fifo, unix, a_inode. Что это такое?
Это разные типы. dir — понятно, каталог, reg — regular file (обычный файл), a_inode — анонимный (т.е. без соответствующего ему файла на диске) inode, и т.д. Кроме первых двух это уже «внутренности» системы.
Там всякие cwd, rtd, mem, del, txt… а ближе к концу вида «0r, 1w, 2w, 3r…26u…» и т.д. Что это означает?
cwd — это current working directory (текущий каталог), rtd — корневой, mem — это файлы, отображённые в память (см. mmap), и т.д. См. man lsof .
Еще интересно что значат числа вроде «253,1» и «0,12» в графе device.
Устройства в Linux однозначно идентифицируются парой чисел major-minor. Если упрощённо, то первое — это тип устройства, а второе — его индекс. Т.е. пара 253,1 означает «устройство типа 253 номер 1».
Неужели, чтобы плеер запустил простое видео, нужно действительно открыть сотни этих файлов?
Плеер — это довольно сложная программа, которой нужно взаимодействовать как с самой собой (между разными её компонентами), так и со средой, в которой она работает: графическая система, менеджер сессии (чтобы экран не гасился во время воспроизведения) и т.д. Чтобы не плодить 100500 специфических способов общения на каждый частный случай, всё строится поверх существующего файлового и сетевого API — отсюда и множество открытых файлов.
Rootlexx ★★★★ ( 20.01.20 19:17:20 MSK )
Последнее исправление: Rootlexx 20.01.20 19:18:26 MSK (всего исправлений: 1)
Ты зря начал с такой сложной программы, как видеоплеер. там и звук и аппаратное скорение декодирования и аппаратное ускорение вывода и сеть и интерфейс и ещё куча всего.
# cat < /dev/zero >/dev/null & [1] 19228 # lsof -p `pidof cat` lsof: WARNING: can't stat() tracefs file system /sys/kernel/debug/tracing Output information may be incomplete. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME cat 19228 legolegs cwd DIR 253,16 12288 1721345 /home/legolegs cat 19228 legolegs rtd DIR 253,8 4096 2 / cat 19228 legolegs txt REG 253,8 52120 790266 /usr/bin/cat cat 19228 legolegs mem REG 253,8 217750512 940018 /usr/lib/locale/locale-archive cat 19228 legolegs mem REG 253,8 5591560 787730 /usr/lib64/libc-2.29.so cat 19228 legolegs mem REG 253,8 356392 786496 /usr/lib64/ld-2.29.so cat 19228 legolegs 0r CHR 1,5 0t0 3077 /dev/zero cat 19228 legolegs 1w CHR 1,3 0t0 3075 /dev/null cat 19228 legolegs 2u CHR 136,4 0t0 7 /dev/pts/4 # kill $! [1]+ Terminated cat < /dev/zero >/dev/null #
legolegs ★★★★★ ( 20.01.20 19:47:57 MSK )
Последнее исправление: legolegs 20.01.20 19:50:09 MSK (всего исправлений: 1)
- файловый дескриптор — это просто целое неотрицательное число, идентифицирующее поток ввода-вывода для процесса. Поток ввода-вывода — это в простейшем случае открытый файл, но сюда же попадают и сетевые сокеты, и пайпы.
lsof показывает больше, чем список дескрипторов — например, он показывает области памяти, полученные в результате mmap() (работа с файлом через отображение этого файла в память и работу с памятью). У таких областей памяти в столбце FD вместо дескриптора указана строка mem .
Там же показана текущая рабочая директория процесса ( cwd ), корневая директория процесса ( rtd ).
У обычных дескрипторов в этой колонке пишется номер дескриптора и режим, в котором он открыт (r — read, w — write, u — read+write). - дескрипторы могут быть связаны с разными типами файлов. Это отображается в столбце TYPE. Как я уже писал выше, это могут быть обычные файлы ( REG , regular file), пайпы ( FIFO ), юниксовые сокеты ( unix ), сетевые сокеты ( IPv4 ), символьные устройства ( CHR , character device), и т.д. Смотри в мане полный (на самом деле нет 🙂 ) список. В списке не описан тип a_inode . Если процесс работает с inotify, ему тоже возвращаются объекты-дескрипторы, они имеют тип a_inode (anonymous inode, вероятно).
- в моей бубунте vlc это динамический бинарник. Соответственно, в списке открытых файлов — все динамические библиотеки, которые нужны для его запуска; они обычно заммаплены (FD=mem).
Дальше идут нумерованные дескрипторы, в моём случае это:- 3 стандартных (0, 1, 2)
- две пары дескрипторов, связанных с одним и тем же пайпом (один на запись, другой на чтение, зачем — хз, возможно, для межпотокового взаимодействия)
- некоторое количество юниксовых сокетов, связанных с DM и около того (pulseaudio, dbus-daemon, mate-session)
- некоторое количество дескрипторов от inotify
- пара символьных устройств — /dev/urandom и /dev/dri/card0 (для direct rendering, вестимо)
- и, наконец-то, дескриптор, связанный с проигрываемым на данный момент файлом.
- числа в графе device — major и minor numbers — идентификаторы устройства, на котором лежит указанный файл.
- файловый дескриптор имеет смысл только в контексте процесса, работающего с вводом-выводом, у разных процессов одни и те же файловые дескрипторы могут быть (и будут!) связаны с разными файлами и прочими потоками ввода-вывода.
Чтобы оставить только обычные дескрипторы, используй команду lsof -a -d 0-9000 -p $(pidof vlc) .
tiandrey ★★★★★ ( 20.01.20 20:14:39 MSK )
Последнее исправление: tiandrey 20.01.20 20:16:24 MSK (всего исправлений: 1)
cwd — это current working directory (текущий каталог), rtd — корневой, mem — это файлы, отображённые в память (см. mmap), и т.д. См. man lsof.
(например, «0r», «1w», «26u») — это как раз то, что вас интересует. Число — дескриптор, символ — режим, в котором открыт файл: на чтение, на запись или оба.
Получается, что дескриптор есть не у всего?
90% того что находится в графе/столбце FD — это как раз «mem». И еще несколько записей вроде cwd, rtd, txt, dex.
И только где-то в конце последние 20-30 файлов имеют эти числа. Могу предположить, что файлы, которые находятся в памяти (mem) не имеют дескриптора? У файлов-каталогов его тоже нет?
Когда приложение запрашивает ОС открыть файл, то ОС такие запросы нумерует чтобы не тягаться с именами файлов. Когда-то давно это давало жуткую экономию. Этот номер собственно и есть файловым дескриптором.
первые три файла ОС открывает по собственной инициативе и присваивает им номера 0, 1, 2. Поэтому номера присваиваемые запросам самого приложения начинаются с 3. Запрос на открытие пользовательского файла идет после того как приложение запросило файлы нужные ему самому, ну там ресурсы, скины, кодеки и всякое такое. Поэтому номер для файла пользователя начинается где-то от 5. Хотя, впринцыпе, приложение может запросить любой номер для любого файла.
Прочитай уже маны к lsof. Не всё, что отображает lsof это файловые дескрипторы.