Как я могу попросить ps
отображать только пользовательские процессы, а не потоки ядра?
Посмотрите на этот вопрос, чтобы понять, что я имею в виду ...
Как я могу попросить ps
отображать только пользовательские процессы, а не потоки ядра?
Посмотрите на этот вопрос, чтобы понять, что я имею в виду ...
Ответы:
Это должно сделать (под Linux):
ps --ppid 2 -p 2 --deselect
kthreadd
(PID 2) имеет PPID 0 ( в Linux 2.6+ ), но ps
не позволяет фильтровать PPID 0; таким образом это обходной путь.
kthreadd
, а затем построить соответствующий ps
вызов. Насколько гарантировано, что эта вещь будет «всегда» называться «kthreadd»? Безопасное решение было бы более сложным, работало бы ps
нормально и анализировало выходные данные, возможно, сделайте несколько тестов.
x
флаг, который не работает с этим. ps au --ppid 2 -p 2 --deselect
работает нормально.
Один из способов распознать процессы ядра - это то, что они не используют какую-либо пользовательскую память, поэтому поле vsz равно 0. Это также ловит зомби (спасибо Стефану Чазеласу за это наблюдение), которые могут быть удалены в зависимости от их статуса.
ps axl | awk '$7 != 0 && $10 !~ "Z"'
Чтобы перечислить только PID:
ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
На практике я нашел следующую идиому:
ps auxf | grep -v ]$
Он фильтрует строки, заканчивающиеся скобками, что может привести к пропуску нежелательных записей, но это очень маловероятно. В обмен на это довольно легко запомнить и относительно быстро набрать.
Некоторые процессы, такие как avahi-daemon, добавляют к своим именам процессов информацию в скобках (имя хоста в случае avahi-daemon) и будут отфильтрованы этой командой.
Одна из особенностей этих процессов заключается в том, что они не поддерживаются исполняемым файлом, так что вы можете сделать ( в zsh ):
ps /proc/[0-9]*/exe(^-@:h:t)
Или с любой оболочкой POSIX:
ps -p "$(find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3 | paste -sd , -)"
Это проверка процессов, чья /proc/<pid>/exe
ссылка на файл.
Но это означает, что вы должны быть суперпользователем, чтобы иметь возможность проверять состояние /proc/<pid>/exe
символической ссылки.
Изменить : Как это происходит, процессы зомби (по крайней мере) удовлетворяют тому же условию, поэтому, если вы не хотите, чтобы они были исключены, вам придется добавить их обратно. Подобно:
ps -p "$(
{ find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3
ps -Ao pid=,state= | sed -n 's/ Z//p'
} | paste -sd , -)"
Обратите внимание, что ps -f
имена этих процессов отображаются в квадратных скобках не потому, что они являются процессами ядра, а потому, что они имеют пустое значение argv[]
(поэтому ps показывает имя процесса вместо argv[0]
этого). У вас также может быть процесс в пространстве пользователя с пустым, argv[]
а у вас может быть имя процесса с argv[0]
формой, [some-string]
поэтому фильтрация ps
вывода на основе этих квадратных скобок не является надежной опцией.
zsh
синтаксис. Второй - это стандартный синтаксис POSIX sh
(и, ps
и, find
и, cut
и paste
). Конечно, /proc
это не указано в POSIX.
wc -l
). Ну, тогда я приму ответ Хауке Лагинга и дам вам голос. ;)
Вы также можете просто проанализировать ps
вывод и найти имена процессов, которые не заключены в квадратные скобки:
ps aux | awk '$NF!~/^\[.+\]$/'
awk -F: '$7 ~ home { print $1 }' /etc/passwd
- но вы все равно получите процессы, которые упоминают любое такое имя пользователя, и оставите временный файл без дела. Я отзову свое отрицательное голосование, но только потому, что ваше третье решение разумно.
$NF
это последнее слово командной строки в ps aux
выводе. Неядерные процессы могут быть [...]
там. Как я сказал в своем ответе, [xxx]
нотация не потому, что они являются процессами ядра, а потому, что у них нет командной строки (без аргументов), которая также допускается для процессов, не связанных с ядром.
Для любого, кто пробует это в busybox, где ps
сильно упрощено и вывод отличается, этот вариант отличного ответа Жиля хорошо работает:
ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'
Согласно ответу Жиля, методология здесь состоит в том, чтобы найти процессы, которые не используют пользовательскую память (`vsz col == 0), и отфильтровать процессы зомби (статус col не равен 'Z').
Выходные столбцы могут быть легко отрегулированы при условии, что номера полей awk на основе 1 настроены соответствующим образом. Посмотрите варианты, которые ваш ps имеет, введя фиктивное значение, и оно сообщит вам. Например:
$ ps -o foo
ps: bad -o argument 'foo', supported arguments: user,group,comm,args,pid,ppid,pgid,tty,vsz,stat,rss
Если вам нужны только подсчеты ... У меня была аналогичная необходимость фильтровать ядро и пользовательские процессы, но мне нужны были только соответствующие подсчеты для каждого. Это было мое решение:
ps -eo vsize | awk '{p[$1==0]++} END {printf "%-16s %6d\n%-16s %6d\n%-16s %6d\n", "Kernel processes", p[1], "User processes", p[0], "Total processes", p[0]+p[1]}'
Образец вывода :
Kernel processes 353
User processes 52
Total processes 405
Объяснение : Я использую хак, что процессы VSZ = 0 можно считать процессами ядра. Итак awk
, я оцениваю сравнение VSZ (с ps -eo vsize
), равно ли оно нулю. Результатом сравнения будет либо логическое значение 0, либо 1. Я создаю массив p[]
, и, когда я запускаю список процессов, если это процесс ядра, я увеличиваю его p[1]++
. В противном случае, как пользовательский процесс, я увеличиваю p[0]++
. После всех приращений я помечаю и печатаю значения (то есть подсчитывает) для p [0] и p [1] в END { }
блоке.
То, что вы ищете, друг мой, нет ps
, но pstree
.
Сначала определите первый процесс ядра. Его PID обычно равен 1 в системе без systemd и 2 в systemd.
Затем используйте эту команду:
$ pstree -p <1 or 2> | grep -o '([0-9]\+)' | grep -o '[0-9]\+'
Выбранный ответ (один с ✅) использует другую команду:
$ ps --ppid 2 -p 2 --deselect
Проблема этой ps
команды в том, что она включает в себя только прямых потомков, но не всех потомков. Команда pstree
включает в себя всех потомков. Вы можете сравнить и посчитать вывод этих двух команд (простой способ использования | wc
) для проверки.
kthreadd
всегда PID 2?