Linux какие файлы использует приложение
Файловая система в ОС Linux, как и в ОС Windows, представляет собой иерархическую структуру каталогов и файлов (в виде дерева), но при этом имеет ряд кардинальных отличий.
Структура каталогов
В ОС Windows жесткие диски называются латинскими буквами (С:, D:, . ), и каждый из дисков представляет собой корневой каталог с собственным деревом папок. Подключение же нового устройства приведет к появлению нового корневого каталога со своей буквой (например, F:). В ОС Linux файловая система представлена единым корневым каталогом, обозначаемым как слэш (/). Соответственно, при данной файловой структуре не диски содержат каталоги, а каталог — диски.
Подключение внешних носителей
В ОС Linux имеется процедура монтирования: когда подключается съемный носитель или диск, файл устройства будет виден в каталоге /dev (devices). Чтобы увидеть содержимое этого устройства, его нужно смонтировать в отдельную директорию /mnt. Также файловая система позволяет примонтировать его и в любое другое место, например /home.
Понятие файла
Понятие «файл» в Linux имеет несколько другое значение, нежели в Windows. «Файлом» можно назвать обычный файл, содержащий данные, и интерпретируемый программой. Директория также является «файлом», содержащим в себе ссылки на другие директории или файлы с данными. Файлы устройства указывает на драйвер, благодаря которому система взаимодействует с физическими устройствами. Имеются и многие другие типы файлов.
Принцип установки программ
Если в Windows программы, зачастую, хранят все данные в одной папке, например в «C:Program FilesProgramName», то в Linux файлы программы разделяются по каталогам в зависимости от типа. Например, исполняемые файлы в /bin, библиотеки в /lib, файлы конфигураций в /etc, логи и кэш в /var.
Регистр имен
Также стоит отметить чувствительность файловой системы Linux к регистру. Файлы Temp.txt и temp.txt будут интерпретироваться как разные файлы и могут находиться в одной директории, в отличие от ОС Windows, который не различает регистр имен. То же правило действует и на каталоги — имена в разных регистрах указывают на разные каталоги.
Назначение каждой директории регламентирует «Стандарт иерархии файловой системы» FHS (Filesystem Hierarchy Standard). Ниже опишем основные директории согласно стандарту FHS:
Я привык искать проблемы в коде или в системе, пользуясь логами или показателями мониторинга, которые выводятся на симпатичных панелях управления с простым и понятным интерфейсом. Однако, если по какой-то причине данные на панель управления не поступают, или логи какой-нибудь службы недоступны, отладка усложняется. Теперь подобных проблем немного, встречаются они редко, но они, всё же, случаются. Поэтому и в наше время весьма ценно знание инструментов, которые помогают понять, что не так с неким процессом на каком-нибудь компьютере.
Когда я отлаживаю нечто, для чего нет логов или показателей мониторинга, я подключаюсь к удалённому компьютеру по ssh. Конечно, это подход ограниченный, он не так уж и прост, не соответствует модным веяниям DevOps, или всем тем современным штучкам, которых можно начитаться в интернете, но он на удивление хорошо подходит мне для того, чтобы быстро проанализировать ситуацию.
Это, на самом деле, похоже на использование команды print при отладке программ. Тут мне сразу хотелось бы уточнить, что я не SRE и не инженер по эксплуатации в сфере IT. Основная сфера моей деятельности — разработка.
Иногда мне приходится разворачивать код, который я написал, и отлаживать его, когда что-то идёт не так. Почти всегда, когда я оказываюсь в новой для себя системе, самым сложным для меня оказывается поиск чего-либо . Например — выяснить, какой порт прослушивает процесс. Или, что требуется чаще, узнать, в какой файл пишет логи некий демон. И если даже мне удаётся найти ответы на эти вопросы, воспользовавшись кучей вызовов команд ps , pstree и ls , и великим множеством обращений к команде grep , часто «ответы», которые я нахожу, либо не содержат ничего полезного, либо оказываются неверными.
Если бы то, что вы сейчас читаете, было бы выступлением Раймонда Геттингера, ведущего разработчика CPython, тут настал бы момент, когда аудитория ждёт фразы: «должен быть лучший способ».
И, на самом деле, такой способ есть. Средством, которым я постоянно пользуюсь для поиска в системе того, что мне нужно, стал отличный инструмент, который называется lsof .
Утилита lsof (её название звучит как el-soff, хотя некоторым больше нравится нечто вроде liss-off или даже el-es-o-eff) — это невероятно полезная команда, которая выводит список всех открытых файлов (LiSts all Open Files).
Команд lsof особенно хороша для поиска чего-либо, так как в Unix-подобных системах всё является файлом. Это — на удивление универсальный отладочный инструмент, который довольно легко способен заменить утилиты ps , netstat , да и некоторые другие тоже.
Опции lsof
Ветеран SRE, который занимался этим делом за десятилетия до того, как появился термин «SRE», однажды сказал мне: «Я перестал изучать опции lsof как только узнал все те, которые мне нужны. Изучи самое важное, и это будет всем, что тебе когда-либо понадобится».
Утилита lsof имеет обширный набор опций.
Если вы хотите изучит их все — man вам в помощь. Здесь же мне хотелось бы рассказать о тех, которыми обычно пользуюсь я.
▍Опция -u
Опция -u выводит список файлов, открытых конкретным пользователем. Следующий пример показывает, как можно узнать, сколько файлов держит открытыми пользователь cindy .
Обычно, если перед параметром некоей опции ставят знак «^» (крышка), который означает отрицание, это приводит к исключению файлов, соответствующих данному параметру, из вывода программы. Вот, например, как можно узнать количество файлов на компьютере, которые открыты всеми пользователями за исключением cindy .
▍Опция -U
Опция -U позволяет вывести все файлы сокетов домена Unix.
▍Опция -c
Опция -c позволяет вывести сведения о файлах, которые держат открытыми процессы, выполняющие команды, имена которых начинаются с заданных символов. Например, вот какая команда позволит увидеть первые 15 файлов, открытых всеми процессами Python, выполняющимися на компьютере.
Вот ещё интересный пример. Например, имеется некоторое количество процессов Python 2.7 и Python 3.6, при этом надо выяснить, какие файлы открыты процессами, которые не являются процессами Python 2.7. Сделать это можно так:
▍Опция +d
Опция +d позволяет выяснить, какие папки и файлы открыты в некоей директории (но не в её поддиректориях).
▍Опция -d
Пожалуй, опция -d — это одна из тех, которыми я пользуюсь чаще всего. Уступает она только опции -p . Эта опция позволяет задать список дескрипторов файлов, разделённых запятой, которые надо включить в вывод или исключить из него. Вот что говорит об этом документация:
Список исключается из вывода, если все записи в наборе начинаются со знака «^». Список будет включён в вывод, если ни одна запись не начинается с «^». Смешивание записей разных видов не разрешается.
В списке может присутствовать диапазон номеров дескрипторов файлов при условии, что ни один из его членов не пуст, оба члена являются числами, и завершающий член больше начального - то есть: «0-7» или «3-10».
Диапазоны могут быть использованы для исключения записей из вывода, если перед ними стоит префикс «^», то есть - «^0-7» исключает все дескрипторы с 0 по 7.
Вывод по нескольким номерам дескрипторов файлов объединяется в соответствии с правилами логического ИЛИ, в один набор, прежде чем к ним будет применена операция логического И.
Когда в наборе встречаются и включаемые и исключаемые члены, lsof сообщает об ошибке и завершает работу с ненулевым кодом возврата.
▍Опция -p
Не могу вспомнить, когда я не пользовался бы опцией -p , работая с lsof . Она позволяет вывести все файлы, открытые процессом с указанным при вызове команды PID.
Например, вот как в Ubuntu выглядит вывод информации обо всех файлах, открытых процессом, скажем, с PID 1.
Вывод команды lsof, вызванной с опцией -p в Ubuntu
Вот что выводится на моём MacBook Air.
Вывод команды lsof, вызванной с опцией -p на MacBook Air
▍Опция -P
Опция -P подавляет, для сетевых файлов, преобразование номеров портов в имена портов. Её полезно использовать в тех случаях, когда разрешение имён портов работает неправильно.
Эту опцию можно использовать с другой опцией — -n , которая подавляет преобразование сетевых номеров в имена хостов для сетевых файлов. Она, кроме того, полезна при неправильно работающем разрешении имён хостов.
Подавление обоих вышеупомянутых преобразований иногда может ускорить работу lsof .
▍Опция -i
Опция -i позволяет вывести сведения о файлах, интернет-адреса которых соответствуют заданному адресу. Если при вызове команды не задавать адреса, эта опция позволяет вывести сведения обо всех интернет-сокетах и сетевых файлах.
С помощью lsof можно, например, посмотреть на TCP-соединения, открытые клиентом Slack или Dropbox. Ради интереса попробуйте посмотреть, сколько соединений открывают вкладки Chrome, каждая из которых является отдельным процессом. Посмотрим на соединения, открытые Slack:
Вывод сведений о соединениях, которые открыл Slack
А вот что с помощью lsof можно узнать о TCP-сокетах, открытых клиентом Dropbox:
Вывод сведений о соединениях, которые открыл Dropbox
Lsof позволяет просматривать и сведения об UDP-соединениях с помощью команды lsof -iUDP .
Вывод сведений об UDP-соединениях
С помощью команды lsof -i 6 можно вывести список открытых соединений IPv6.
Вывод сведений об IPv6-соединениях
▍Опция -t
Комбинирование опций
Обычно lsof объединяет результаты использования нескольких опций, следуя принципу логического ИЛИ. Если задать опцию -a , результаты будут объединены по правилам логического И.
Конечно, есть несколько исключений из этого правила, тут, как обычно, рекомендовано взглянуть на документацию, но если в двух словах, то работает это так:
Обычно заданные опции списка объединяются по принципу логического ИЛИ, то есть, если указать опцию -i без указания адреса, и опцию -u foo, будет выведен список всех сетевых файлов или файлов, принадлежащих процессам, владельцем которых является пользователь «foo». Из этого правила есть несколько исключений:
- Имя пользователя или ID пользователя (UID) со знаком «^» (отрицание), заданное с опцией -u;
- Идентификатор процесса (PID) со знаком «^» (отрицание), заданный с опцией -p;
- Группа процессов (PGID) со знаком «^» (отрицание), заданная с опцией -g;
- Имя команды со знаком «^» (отрицание), заданное с опцией -c;
- Имена состояний протоколов TCP или UDP, заданные с опцией -s [p:s].
Опцию -a можно использовать для обработки вывода по принципу логического И. Например, если использовать опции -a, -U и -u foo, будет выведен список только файлов сокетов UNIX, которые принадлежат процессам, владельцем которых является пользователь «foo».
История большой победы
Пожалуй, я тут немного преувеличиваю, «победа» была не такой уж и большой, но когда случилось то, о чём пойдёт речь, lsof оказался очень кстати.
Пару недель назад мне нужно было поднять один экземпляр нового сервиса в тестовом окружении. Тестовый сервис, о котором идёт речь, не был подключён к рабочей инфраструктуре мониторинга. Я попытался выяснить, почему процесс, который был только что запущен, не зарегистрировал себя в Consul, как результат, его не могли обнаружить другие сервисы. «Так, не знаю, в чём дело, но взгляну-ка я на логи», — подумал я. Если что-то работает не так, как ожидается, я смотрю логи сервиса, работу которого пытаюсь наладить, и в большинстве случаев логи сразу указывают на корень проблемы.
Сервис, о котором идёт речь, запускался с использованием менеджера процессов и сокетов circus. Логи для процессов, работающих под circus , хранятся в специальном месте на хосте — назовём его /var/log/circusd . Более новые сервисы на хосте запускались другим менеджером, s6, который пишет логи в другое место. Затем, есть ещё и логи, которые генерирует socklog/svlogd, которые, опять же, оказываются где-то ещё. Короче говоря, в логах недостатка не было, и главная проблема заключалась в том, чтобы обнаружить, в какой дескриптор файла пишет лог мой сбойный процесс.
Так как я знал, что процесс, с проблемами которого я пытался разобраться, работает под circus , подключение с помощью команды tail к /var/log/circusd/whatever_tab_completion_suggested позволило бы мне посмотреть на потоки stdout и stderr этого процесса. Правда, просмотр лога мне не дал абсолютно ничего. Быстро стало ясно, что я читал не тот лог-файл, и действительно, при ближайшем рассмотрении оказалось, что в /var/log/circusd было два файла: stage-svcname-stderr.log и staging-svcname.stderr.log . Я тогда воспользовался для автозавершения команды клавишей Tab, и тот файл, который был выбран автоматически, оказался не тем, что был нужен мне.
Один из способов понять, какой файл был действительно использован интересующим меня процессом для логирования, заключался в использовании команды lsof -l filename , которая вывела бы сведения обо всех процессах, имеющих открытые дескрипторы файлов. Оказалось, что ни с одним из работающих процессов не было ассоциировано лог-файла, который я просматривал с помощью команды tail , что означало, что этот файл можно было безопасно удалить.
Просмотр другого файла тут же позволил выяснить, почему процесс давал сбой (при этом circus перезапускал его после сбоя, что приводило к бесконечному циклу сбоев-перезапусков).
Итоги
Чем чаще я использую команду lsof , тем больше других инструментов она заменяет и тем больше полезного позволяет мне узнать. Надеюсь, теперь у lsof есть шанс принести пользу и вам.
В этой статье вы узнаете, как вывести список открытых файлов пользователем или процессом с помощью команды lsof в Linux.
М ы думаем, что в какой-то момент вы задавались вопросом, есть ли способ показать открытые файлы процесса или пользователя. Хорошо, что ответ на этот вопрос это команда lsof.
Позвольте нам показать вам наиболее распространенное использование команды lsof.
Примеры команды l sof
Если вы используете команду lsof без каких-либо параметров и аргументов, она выведет список всех открытых файлов всеми процессами в системе.
Вывод должен быть таким:
Выводы в основном говорят сами за себя, но вы все еще можете задаться вопросом о столбцах FD и TYPE.
FD означает файловый дескриптор. Некоторые из общих значений для FD:
TYPE это не просто. Он определяет тип файла. Вот некоторые примеры:
Доверьтесь нам. Вы не захотите запускать команду lsof без аргументов.
Почему мы это говорим? Потому что он начнет заполнять ваш экран тысячами результатов.
Если мы запускаем команду lsof на сервере Ubuntu и подсчитываем количество строк с помощью команды wc, вот результат.
Да! Вот так. В системе открыто более одиннадцати тысяч файлов, открытых различными процессами.
Не беспокойтесь, команда lsof очень полезна при отладке, потому что вы можете видеть, какие процессы открывают, какие файлы и какой файл открывается каким процессом.
Если вы не вошли в систему как root, вывод команды lsof будет очень ограничен. Рекомендуется использовать sudo, если вы вошли в систему как пользователь без полномочий root.
1. Перечислите все процессы, которые открыли файл
Это просто Вам просто нужно указать путь к файлу.
2. Список всех файлов, открытых пользователем
Это удобно в многопользовательской среде. Вы можете перечислить все файлы, открытые определенным пользователем, следующим образом:
Вы также можете указать более одного пользователя, как это:
3. Список всех открытых файлов в каталоге
Если вам интересно, какие из файлов были открыты в определенном каталоге, вы можете использовать команду lsof с опцией + D.
Поиск рекурсивный. Таким образом, он перечислит все открытые файлы в указанном каталоге и все его подкаталоги.
4. Перечислите все открытые файлы процессом
В этом случае вам нужно знать идентификатор процесса (pid). Если вы знаете идентификатор процесса, вы можете использовать опцию -p команды lsof, чтобы найти файлы, открытые им.
Вы также можете указать несколько идентификаторов процессов.
5. Список всех файлов, открытых командой
6. Найти открытый пользователем и командой или процессом
Вы можете комбинировать параметры, такие как пользователь и команда, и процесс, используя вариант -, Думайте об этом как об операторе AND. Это дает вам дополнительный фильтр при попытке сузить область поиска.
Читать Разница между одинарными и двойными кавычками в Bash Shell7. Перечислите сетевые соединения и порты с помощью команды lsof
Вы также можете использовать команду lsof для поиска открытых портов или для поиска того, какой процесс использует порт.
Вы можете подать все виды открытых портов с опцией -i:
Вывод может выглядеть так:
Вы также можете указать тип сетевого подключения. Например, чтобы вывести список всех открытых портов TCP, вы можете использовать:
Чтобы узнать, какой процесс использует определенный порт, вы можете указать номер порта:
Бонусный совет: использование оператора отрицания с lsof
Вы можете использовать оператор отрицания, чтобы исключить пользователя или процесс при использовании команды lsof.
Например, вы хотите перечислить все файлы, открытые пользователем, отличным от root, используйте его следующим образом:
Команда lsof становится еще более полезной, когда вы используете ее с командой grep.
Мы надеемся, что вы узнали что-то новое с этой статьей. Если у вас есть вопросы или предложения, пожалуйста, оставьте комментарий ниже.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
В Unix-подобных системах, куда входит и Linux, существует концепция «Всё есть файл». Согласно ей, работа с системой сводится к работе с файлами. Однако файлы в системе «Линукс» бывают разные. Об этом — наша статья.
К файлам в системе Linux относят и объекты, куда мы записываем наши данные, и исполняемые файлы, и файлы специального назначения (устройств, туннелей, сокетов и пр.). Но всё это неважно, ведь мы в любом случае работаем именно с файлами, которые используются и для обычных данных, и для устройств.
Преимущество такой концепции заключается в том, что отпадает необходимость в реализации отдельного набора API для каждого устройства, в результате чего с ним способны работать все стандартные программы системы «Линукс» и API-интерфейсы.
Основные типы файлов Linux
В системе Linux файлы делят на 3 главных типа: 1) обыкновенные (для хранения информации); 2) специальные (для туннелей и устройств); 3) директории.
Теперь рассмотрим каждый из этих типов подробнее.
Обыкновенные файлы
С обычными файлами мы работаем ежедневно. Они содержат текст, изображения, инструкции для работы софта и прочие данные. Это наиболее распространённый файловый тип в системе Linux. Сюда входят: 1) текстовые файлы; 2) файлы изображений, архивов, библиотек; 3) исполняемые и другие файлы.
Для определения файлового типа в режиме списка используется утилита ls. Обычные файлы будут обозначаться чертой:
Говоря об обычных файлах в системе, обязательно упомянем форматы. Чтобы система понимала, какой утилитой открывать файлы, необходимо, чтобы они были сохранены в конкретном формате. Форматы тоже можно посмотреть, но уже с помощью команды file:
В примере выше система сообщила, что файл является исполняемым. А вот как обстоит дело в случе, если он текстовый:
Так вы можете посмореть все файловые форматы:
Специальные файлы
Файлы этого типа обеспечивают обмен информацией с ядром, работу с устройствами либо общение между утилитами. С учётом своего назначения они делятся на несколько видов: 1.Блочные. Файлы устройств, обеспечивающие буферный доступ к аппаратным компонентам. В процессе записи информации на жёсткий диск либо съёмный носитель данные не записываются сразу — это нерационально с точки зрения расходования ресурсов. Поэтому данные сначала собираются в буфере, для чего и используются блочные файлы. Они способны передавать большие блоки информации за один раз, и с их помощью файловая система и прочие утилиты получают возможность взаимодействовать с драйверами аппаратных устройств.
Если вернутся к уже упомянутой программе ls, то блочные файлы обозначаются буквой b. Давайте выведем их из /dev:
Файловые типы также умеет определять и утилита file:
2.Символьные. С их помощью обеспечивается небуферизованный доступ к ядру и аппаратным компонентам. Это значит, что они могут передавать за раз лишь один символ. В остальном, это те же файлы устройств.
Как и в случае с блочными, вы можете отсортировать их посредством ls. Для символьных файлов предусмотрена буква c (character):
3.Символические ссылки. Они указывают на другие файлы по их имени, способны указывать и на обыкновенные файлы, и на каталоги, и на другие файловые типы. Можно сказать, что они аналогичны ярлыкам в системе Windows. Обозначаются буквой l (link):
Создать символические ссылки можно посредством утилиты ln:
4.Туннели/именованные туннели. Обеспечивают настройку связи между 2-мя процессами в системе, перенаправляя вывод одного на вход другого. Туннели именованного типа тоже применяются для связи между 2-мя процессами и функционируют, как и обыкновенные туннели.
Для их обозначения существует буква p (pipe):
Для создания именованного туннеля воспользуйтесь утилитой mkfifo:
В примере выше мы создали туннель и передали в него информацию, а оболочка стала неинтерактивной. Прочитать данные можно на другом конце туннеля:
5.Файлы сокетов. Создают прямую связь между процессами в системе. Передают данные между процессами, которые запущены в различных средах либо даже на различных машинах. Означает это следующее: посредством сокетов программы могут осуществлять обмен информацией даже по сети. Работа сокета похожа на работу туннеля, но в обе стороны.
Для обозначения предусмотрена буква s:
Создадим Unix-сокет с помощью утилиты nc:
И теперь подключимся к этому сокету из другой консоли:
Связь функционирует в обоих направлениях, поэтому после нажатия Enter вся информация, которую вы будете вводить в одной из консолей, станет отправляться в другую.
Каталоги
Каталог может содержать и обычные, и специальные файлы, то есть любые файловые типы в системе Linux. Они объединяют файлы (а также другие каталоги) в группы, чтобы упростить навигацию и поиск. В системе Linux файлы организовываются в папки, начиная от корня (/).
Каталоги обозначаются буквой d (directory):
Для создания каталога используют команду mkdir :
Вывод
В статье мы рассмотрели довольно простые вещи, которые касались типов файлов в Linux. Но если вы хотите освоить администрирование операционной системы Linux на продвинутом уровне, имеет смысл ознакомиться со специализированным курсом от практикующих администраторов. Не пропустите:
Читайте также: