Часто бывает полезным узнать разного рода параметры уже запущенных процессов, а так же манипулировать ими. Ниже мы рассмотрим несколько разных примеров по работе с процессами.
Если говорить проще, то много информации нам может предоставить файловая система procfs
procfs — виртуальная файловая система, используемая в UNIX-like операционных системах. procfs позволяет получить доступ к информации о системных процессах из ядра, она необходима для выполнения таких команд как ps, w, top. Обычно её монтируют на /proc. procfs создает двухуровневое представление пространств процессов. На верхнем уровне процессы представляют собой директории, именованные в соответствии с их pid.
Некоторые файлы и директории из ProcFS:
- /proc/PID/cmdline – аргументы командной строки (где PID – идентификатор процесса или self);
- /proc/PID/environ – переменные окружения для данного процесса;
- /proc/PID/status – статус процесса;
- /proc/PID/fd – директория, содержащая символьные ссылки на каждый открытый файловый дескриптор;
- /proc/cpuinfo – информация о процессоре (производитель, модель, поколение и т.п.);
- /proc/cmdline – параметры, передаваемые ядру при загрузке;
- /proc/uptime – количество секунд, прошедших с момента загрузки ядра и проведенных в режиме бездействия;
- /proc/version – содержит информацию о версии ядра, компилятора и другую информацию, связанную с загруженным ядром.
Примечание.
Если перейти в каталог в /proc и посмотреть на размеры файлов в нём, то все они окажутся нулевыми. Дело в том, что в действительности все эти файлы не существуют.
Ниже приведём несколько примеров использования procfs
1) Текущий рабочий каталог процесса:
# ls -la /proc/3165/cwd
lrwxrwxrwx 1 clamav clamav 0 Авг 18 16:07 /proc/3165/cwd -> /var/lib/clamav
где 3165 – номер pid’a процесса.
2) Вывести все переменные процесса:
# cat /proc/3165/environ | strings
ReceiveTimeout=30
CONSOLE=/dev/console
SELINUX_INIT=YES
TERM=linux
rootmnt=/root
PidFile=/var/run/clamav/freshclam.pid
NotifyClamd=/etc/clamav/clamd.conf
LogTime=no
INIT_VERSION=sysvinit-2.86
init=/sbin/init
DNSDatabaseInfo=current.cvd.clamav.net
AllowSupplementaryGroups=false
PATH=/sbin:/usr/sbin:/bin:/usr/bin
LogSyslog=false
DatabaseMirror=database.clamav.net db.local.clamav.net
runlevel=2
RUNLEVEL=2
PWD=/
VERBOSE=no
DatabaseOwner=clamav
CompressLocalDatabase=no
previous=N
PREVLEVEL=N
LogVerbose=false
MaxAttempts=5
ScriptedUpdates=yes
Foreground=false
Checks=24
SHLVL=3
HOME=/
DatabaseDirectory=/var/lib/clamav/
LogFacility=LOG_LOCAL6
UpdateLogFile=/var/log/clamav/freshclam.log
LogFileMaxSize=0
ConnectTimeout=30
Debug=false
_=/sbin/start-stop-daemon
3) Удалили файл, используемый процессом. Как восстановить файл?
Попробовать поискать файл в каталоге /proc/{PID}/fd
Но почему так можно делать? Дело в том, что при удалении файла, который всё-таки открыт процессом файл перестал быть виден в файловой системе, но не исчез, и окончательно удалён он будет только когда закроется последний ссылающийся на него дескриптор. Каталог /proc/{PID}/fd содержит символьные ссылки на все открытые процессом PID дескрипторы.
4) Связь между /proc и sysctl (взято с www.linuxcenter.ru)
Sysctl использует файлы в /proc/sys как индивидуальные переменные, которые могут быть изменены. Например, файл в /proc/sys, который представляет максимальное количество заголовков файлов в системе, /proc/sys/fs/file-max, представлен как fs.file-max. Этот пример требует некоторых дополнительных пояснений в записи sysctl. Так как sysctl может только изменять переменные в директории /proc/sys, то часть имени переменной обозначающая директорию отбрасывается. Другое изменение касается слэшей, которые заменяются на точки. Вот два простых правила для преобразования файлов в /proc/sys и переменных в sysctl:
– Отбросьте /proc/sys от начала.
– Замените слэши на точки в имени файла.
Эти два правила позволят вам преобразовать любой файл в /proc/sys в любое имя переменной в sysctl. Обычное преобразование имени файла в переменную:
/proc/sys/dir/file --> dir.file
dir1.dir2.file --> /proc/sys/dir1/dir2/file
Вы можете увидеть все переменные, доступные для изменения, используя команду sysctl -a. Переменные могут также быть изменены с помощью sysctl, которая выполняет ту же работу что и echo. Эта запись объясняет это:
sysctl -w dir.file="value"
Используя пример с file-max, мы можем изменить это значение на 16384, используя один из двух методов:
sysctl -w fs.file-max="16384"
или
echo "16384" > /proc/sys/fs/file-max
5) Максимальное количество процессов.
По умолчанию их 32768. Узнать текущее значение можно так:
# sysctl kernel.pid_max
kernel.pid_max = 32768
Изменить это число можно так:
#sysctl kernel.pid_max=256000
kernel.pid_max = 256000
Но! Это возможно только на 64-битных системах. Такое ограничение связано с разрядностью 32-битного числа, которое не может превышать 32768. А поскольку эти лимиты определены как тип int, то соответственно действует такое ограничение.
Если же вы попробуете изменить, то получите такое сообщение:
# sysctl kernel.pid_max=327600
error: "Invalid argument" setting key "kernel.pid_max"
6) Утилита lsof
Это утилита, служащая для вывода информации о том, какие файлы используются теми или иными процессами.
Ниже будет продемонстрировано несколько полезных примеров работы этой утилиты.
– Список всех открытых файлов
$lsof
Показывает все открытые файлы текущего пользователя (если root – тогда все файлы) всеми процессами.
– Какие процессы используют файл file
#lsof /path/to/file
Можно указать несколько файлов через пробел, тогда получите суммарный список процессов.
– Какие процессы/файлы использует пользователь user
#lsof -u user
Если хотите узнать информацию по нескольким пользователям, разделите их имена запятой.
Для групп используйте конструкцию ‘-g groupname’
– Какие процессы открыты программой prog_name
#lsof -c prog_name
Можно указывать неполное имя. lsof будет искать по указанному буквосочетанию. Если нужно узнать информацию для нескольких приложений, разделяйте их имена пробелом и перед каждым именем должно идти ‘-c’
– Какие файлы открыты pid’ом NNN
#lsof -p NNN
– Список всех открытых интернет сокетов
#lsof -i
Если нужно посмотреть только tcp сокеты, то после ‘i’ через пробел добавляем tcp. Аналогично и для udp.
Так же можно посмотреть и список всех unix сокетов:
#lsof -U
– Просмотр ресурсов в realtime
Можно задать период обновления информации, например, 1 секунда:
#lsof -r 1 -u username
будет обновлять информацию об использованных юзером username процессах, каждую секунду.
– Вывод только pid’ов
По умолчанию, выводится таблица с колонками. Но если требуется вывести только сами pid’ы, можно воспользоваться такой командой:
#lsof -t -u username
7) Поиск всех pid’ов процесса.
Есть одна замечательная утилита pidof, которая позволяет найти все pid’ы связанные с определённым процессом. К примеру, найдём все pid’ы apache2:
# pidof apache2
9370 9369 9368 9367 9364 9362 9314 9280 9277 9268 4940
В большинстве дистрибутивов это обычный симлинк на /sbin/killall5:
#file /bin/pidof
/bin/pidof: symbolic link to `../sbin/killall5'