- How to Find Out Who is Using a File in Linux
- If You Appreciate What We Do Here On TecMint, You Should Consider:
- Изучаем процессы в Linux
- Содержание
- Введение
- Атрибуты процесса
- Жизненный цикл процесса
- Рождение процесса
- Состояние «готов»
- Состояние «выполняется»
- Перерождение в другую программу
- Состояние «ожидает»
- Состояние «остановлен»
- Завершение процесса
- Состояние «зомби»
- Забытье
- Благодарности
- Linux / UNIX List Open Files for Process
- UNIX List Open Files For Process
- FreeBSD list open files per process
- Linux List Open Files For Process
- Using lsof to display the processes using the most file handles
- Conclusion
How to Find Out Who is Using a File in Linux
In this article, we will explain how to find out who is using a particular file in Linux. This will help you know the system user or process that is using an open file.
We can use the lsof command to know if someone is using a file, and if they are, who. It reads kernel memory in its search for open files and helps you list all open files. In this case, an open file may be a regular file, a directory, a block special file, a character special file, a stream, a network file and many others – because in Linux everything is a file.
Lsof is used on a file system to identify who is using any files on that file system. You can run lsof command on Linux filesystem and the output identifies the owner and process information for processes using the file as shown in the following output.
To list user specific opened files, run the following command replace tecmint with the actual user name.
Another important use of lsof is to find out the process listening on a specific port. For example identify the process listening on port 80 using the following command.
Note: Since lsof reads kernel memory in its search for open files, rapid changes in kernel memory may result into unpredictable outputs. This is one of the major downsides of using lsof command.
For more information, look at the lsof man page:
That’s all! In this article, we have explained how to know who is using a particular file in Linux. We have shown how to identify the owner and process information for processes using an open file. Use the feedback form below to reach us for any questions or comments.
If You Appreciate What We Do Here On TecMint, You Should Consider:
TecMint is the fastest growing and most trusted community site for any kind of Linux Articles, Guides and Books on the web. Millions of people visit TecMint! to search or browse the thousands of published articles available FREELY to all.
If you like what you are reading, please consider buying us a coffee ( or 2 ) as a token of appreciation.
We are thankful for your never ending support.
Источник
Изучаем процессы в Linux
В этой статье я хотел бы рассказать о том, какой жизненный путь проходят процессы в семействе ОС Linux. В теории и на примерах я рассмотрю как процессы рождаются и умирают, немного расскажу о механике системных вызовов и сигналов.
Данная статья в большей мере рассчитана на новичков в системном программировании и тех, кто просто хочет узнать немного больше о том, как работают процессы в Linux.
Всё написанное ниже справедливо к Debian Linux с ядром 4.15.0.
Содержание
Введение
Системное программное обеспечение взаимодействует с ядром системы посредством специальных функций — системных вызовов. В редких случаях существует альтернативный API, например, procfs или sysfs, выполненные в виде виртуальных файловых систем.
Атрибуты процесса
Процесс в ядре представляется просто как структура с множеством полей (определение структуры можно прочитать здесь).
Но так как статья посвящена системному программированию, а не разработке ядра, то несколько абстрагируемся и просто акцентируем внимание на важных для нас полях процесса:
- Идентификатор процесса (pid)
- Открытые файловые дескрипторы (fd)
- Обработчики сигналов (signal handler)
- Текущий рабочий каталог (cwd)
- Переменные окружения (environ)
- Код возврата
Жизненный цикл процесса
Рождение процесса
Только один процесс в системе рождается особенным способом — init — он порождается непосредственно ядром. Все остальные процессы появляются путём дублирования текущего процесса с помощью системного вызова fork(2) . После выполнения fork(2) получаем два практически идентичных процесса за исключением следующих пунктов:
- fork(2) возвращает родителю PID ребёнка, ребёнку возвращается 0;
- У ребёнка меняется PPID (Parent Process Id) на PID родителя.
После выполнения fork(2) все ресурсы дочернего процесса — это копия ресурсов родителя. Копировать процесс со всеми выделенными страницами памяти — дело дорогое, поэтому в ядре Linux используется технология Copy-On-Write.
Все страницы памяти родителя помечаются как read-only и становятся доступны и родителю, и ребёнку. Как только один из процессов изменяет данные на определённой странице, эта страница не изменяется, а копируется и изменяется уже копия. Оригинал при этом «отвязывается» от данного процесса. Как только read-only оригинал остаётся «привязанным» к одному процессу, странице вновь назначается статус read-write.
Состояние «готов»
Сразу после выполнения fork(2) переходит в состояние «готов».
Фактически, процесс стоит в очереди и ждёт, когда планировщик (scheduler) в ядре даст процессу выполняться на процессоре.
Состояние «выполняется»
Как только планировщик поставил процесс на выполнение, началось состояние «выполняется». Процесс может выполняться весь предложенный промежуток (квант) времени, а может уступить место другим процессам, воспользовавшись системным вывозом sched_yield .
Перерождение в другую программу
В некоторых программах реализована логика, в которой родительский процесс создает дочерний для решения какой-либо задачи. Ребёнок в данном случае решает какую-то конкретную проблему, а родитель лишь делегирует своим детям задачи. Например, веб-сервер при входящем подключении создаёт ребёнка и передаёт обработку подключения ему.
Однако, если нужно запустить другую программу, то необходимо прибегнуть к системному вызову execve(2) :
или библиотечным вызовам execl(3), execlp(3), execle(3), execv(3), execvp(3), execvpe(3) :
Все из перечисленных вызовов выполняют программу, путь до которой указан в первом аргументе. В случае успеха управление передаётся загруженной программе и в исходную уже не возвращается. При этом у загруженной программы остаются все поля структуры процесса, кроме файловых дескрипторов, помеченных как O_CLOEXEC , они закроются.
Как не путаться во всех этих вызовах и выбирать нужный? Достаточно постичь логику именования:
- Все вызовы начинаются с exec
- Пятая буква определяет вид передачи аргументов:
- l обозначает list, все параметры передаются как arg1, arg2, . NULL
- v обозначает vector, все параметры передаются в нуль-терминированном массиве;
- Далее может следовать буква p, которая обозначает path. Если аргумент file начинается с символа, отличного от «/», то указанный file ищется в каталогах, перечисленных в переменной окружения PATH
- Последней может быть буква e, обозначающая environ. В таких вызовах последним аргументом идёт нуль-терминированный массив нуль-терминированных строк вида key=value — переменные окружения, которые будут переданы новой программе.
Семейство вызовов exec* позволяет запускать скрипты с правами на исполнение и начинающиеся с последовательности шебанг (#!).
Есть соглашение, которое подразумевает, что argv[0] совпадает с нулевым аргументов для функций семейства exec*. Однако, это можно нарушить.
Любопытный читатель может заметить, что в сигнатуре функции int main(int argc, char* argv[]) есть число — количество аргументов, но в семействе функций exec* ничего такого не передаётся. Почему? Потому что при запуске программы управление передаётся не сразу в main. Перед этим выполняются некоторые действия, определённые glibc, в том числе подсчёт argc.
Состояние «ожидает»
Некоторые системные вызовы могут выполняться долго, например, ввод-вывод. В таких случаях процесс переходит в состояние «ожидает». Как только системный вызов будет выполнен, ядро переведёт процесс в состояние «готов».
В Linux так же существует состояние «ожидает», в котором процесс не реагирует на сигналы прерывания. В этом состоянии процесс становится «неубиваемым», а все пришедшие сигналы встают в очередь до тех пор, пока процесс не выйдет из этого состояния.
Ядро само выбирает, в какое из состояний перевести процесс. Чаще всего в состояние «ожидает (без прерываний)» попадают процессы, которые запрашивают ввод-вывод. Особенно заметно это при использовании удалённого диска (NFS) с не очень быстрым интернетом.
Состояние «остановлен»
В любой момент можно приостановить выполнение процесса, отправив ему сигнал SIGSTOP. Процесс перейдёт в состояние «остановлен» и будет находиться там до тех пор, пока ему не придёт сигнал продолжать работу (SIGCONT) или умереть (SIGKILL). Остальные сигналы будут поставлены в очередь.
Завершение процесса
Ни одна программа не умеет завершаться сама. Они могут лишь попросить систему об этом с помощью системного вызова _exit или быть завершенными системой из-за ошибки. Даже когда возвращаешь число из main() , всё равно неявно вызывается _exit .
Хотя аргумент системного вызова принимает значение типа int, в качестве кода возврата берется лишь младший байт числа.
Состояние «зомби»
Сразу после того, как процесс завершился (неважно, корректно или нет), ядро записывает информацию о том, как завершился процесс и переводит его в состояние «зомби». Иными словами, зомби — это завершившийся процесс, но память о нём всё ещё хранится в ядре.
Более того, это второе состояние, в котором процесс может смело игнорировать сигнал SIGKILL, ведь что мертво не может умереть ещё раз.
Забытье
Код возврата и причина завершения процесса всё ещё хранится в ядре и её нужно оттуда забрать. Для этого можно воспользоваться соответствующими системными вызовами:
Вся информация о завершении процесса влезает в тип данных int. Для получения кода возврата и причины завершения программы используются макросы, описанные в man-странице waitpid(2) .
Передача argv[0] как NULL приводит к падению.
Бывают случаи, при которых родитель завершается раньше, чем ребёнок. В таких случаях родителем ребёнка станет init и он применит вызов wait(2) , когда придёт время.
После того, как родитель забрал информацию о смерти ребёнка, ядро стирает всю информацию о ребёнке, чтобы на его место вскоре пришёл другой процесс.
Благодарности
Спасибо Саше «Al» за редактуру и помощь в оформлении;
Спасибо Саше «Reisse» за понятные ответы на сложные вопросы.
Они стойко перенесли напавшее на меня вдохновение и напавший на них шквал моих вопросов.
Источник
Linux / UNIX List Open Files for Process
H ow do I list all open files for a Linux or UNIX process using command line options? How can I show open files per process under Linux?
Both Linux and Unix-like operating systems come with various utilities to find out open files associated with the process.
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | Yes |
Requirements | None |
Est. reading time | 3 minutes |
UNIX List Open Files For Process
First use the ps command command to get PID of process, enter:
$ ps -aef | grep
Next pass this PID to pfiles command under Solaris Unix:
$ pfiles
$ pfiles 3533
See pfiles command documentation> for more information or type the following man command:
% man pfiles
FreeBSD list open files per process
On FreeBSD use the fstat command along with the ps command:
# ps aux | grep -i openvpn # filter outputs using the grep command #
# fstat -p
# fstat -p 1219
We can count open files count for openvpn process as follows using the wc command:
# fstat -p 1219 | grep -v ^USER | wc -l
The -p option passed to the fstat to report all files open by the specified process.
FreeBSD pstat command in action
Linux List Open Files For Process
First you need to find out PID of process. Simply use any one of the following command to obtain process id:
# ps aux | grep
$ ps -C
For example, find out PID of firefox web-browser, enter:
$ ps -C firefox -o pid=
Output:
To list opne files for firefox process, enter:
$ ls -l /proc/7857/fd
Sample output:
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
For privileged process use the sudo command and to count open files use the wc command on Linux as follows:
# Get process pid
sudo ps -C Xorg -o pid
sudo ls -l /proc/$
# Say pid is 9497 for Xorg, then
sudo ls -l /proc/9497/fd | wc -l
We can use bash for loop as follows too:
Listing Open Files on Linux
Using lsof to display the processes using the most file handles
The lsof command list open files under all Linux distributions or UNIX-like operating system. Type the following command to list open file for process ID 351:
$ lsof -p 351
In this example display and count all open files for top 10 processes on Linux operating systems or server:
# lsof | awk ‘
## force numeric sort by passing the ‘-n’ option to the sort ##
# lsof | awk ‘
- lsof – Run the lsof to display all open files and send output to the awk
- awk ‘
‘ – Display first field i.e. process name only - uniq -c – Omit duplicate lines while prefix lines by the number of occurrences
- sort -r – Reverse sort
- head – Display top 10 process along with open files count
Conclusion
Now you know how to find open files per process on Linux, FreeBSD, and Unix-like systems using various command-line options. See how to increase the system-wide/user-wide number of available (open) file handles on Linux for more information.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Источник