Чи може PS відображати лише Linux, які не є ядрами в Linux?


Відповіді:


37

Це слід зробити (під Linux):

ps --ppid 2 -p 2 --deselect

kthreadd(PID 2) має PPID 0 ( на Linux 2.6+ ), але psне дозволяє фільтрувати за PPID 0; таким чином, ця обробка.


Приємно, але наскільки гарантовано це kthreaddзавжди PID 2?
l0b0

@ l0b0 Я поняття не маю :-) Ви можете зробити це в два етапи: Визначте PID kthreadd, а потім побудуйте відповідний psвиклик. Наскільки гарантовано, що ця річ завжди буде називатися "kthreadd"? Безпечне рішення було б складніше, запустити psнормально і проаналізувати вихід, можливо зробити кілька тестів.
Hauke ​​Laging

2
Принаймні, в Linux 2.4 на аркуші x86 ці процеси мали ppid 1, тому їх не можна було розрізнити.
Стефан Шазелас

1
бути схожим на "ps -ef" do "ps --ppid 2 -p 2 --deselect -f" і робити це як "ps aux" do "ps --ppid 2 -p 2 --deselect u"
Пітер

1
@Totor Я перевірив і схоже, що це xпрапор, який не працює з цим. ps au --ppid 2 -p 2 --deselectпрацює добре.
Sankalp

9

Один із способів розпізнати процеси ядра - це те, що вони не використовують жодної пам’яті користувача, тому поле 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}'

Як і моє рішення, воно також буде включати процеси зомбі.
Stéphane Chazelas

1
@StephaneChazelas Добре, я додав умову до фільтра.
Жил "ТАК - перестань бути злим"

9

На практиці я виявив досить таку фразу:

ps auxf | grep -v ]$

Він фільтрує рядки, що закінчуються дужками, що може призвести до пропуску небажаних записів, але це малоймовірно. В обмін це досить легко запам’ятати і відносно швидко набрати.

Деякі процеси, такі як avahi-daemon, додають у дужки інформацію про ім’я процесу (ім'я хоста у випадку avahi-daemon) і будуть відфільтровані за допомогою цієї команди.


8

Однією з особливостей цих процесів є те, що вони не підкріплені виконуваним файлом, так що ви можете це зробити ( в 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результатів на основі цих квадратних дужок не є надійною можливістю.


Я вважаю, це нестандартний синтаксис оболонки.
Тотор

1
@Totor, як я вже сказав, перший - zshсинтаксис. Другий - це стандартний синтаксис POSIX shpsі findта cutі paste). Звичайно /proc, POSIX не визначається.
Стефан Шазелас

Приймаю цю відповідь, оскільки вона універсальна (дякую за редагування). Однак відповідь Хоуке Лаґінга також досить приємна і відверта, доки ви не маєте справу з ядром 2.4.
Тотор

@Totor, відповідь Хоуке також має перевагу в тому, що він не вимагає привітання суперпользователя. Моя відповідь працює з ядрами 2.4 і 2.6 / 3, але я вважаю, що це не гарантує, що вона працюватиме в 4.x все одно.
Стефан Шазелас

Хм, ти маєш рацію, я не думав про привілеї root. Це може призвести до помилок, оскільки ви все одно отримуєте відповідь, коли ви не кореняться, але це інакше (тому ви повинні бути обережними, вважаючи їх, скажімо wc -l). Ну, тоді я прийму відповідь Хауке Лейґґінга , і я дам вам позицію. ;)
Тотор

1

Ви також можете просто розібрати psвихід і шукати назви процесів, які не містяться в дужках:

ps aux | awk '$NF!~/^\[.+\]$/'

Трохи менш ненадійний спосіб отримати список користувачів, які вас цікавлять: awk -F: '$7 ~ home { print $1 }' /etc/passwd- але ви все одно отримаєте процеси, які згадують будь-яке таке ім’я користувача, і ви залишите тимчасовий файл лежати. Я відкликаю свою акцію, але тільки тому, що ваше третє рішення є розумним.
Кіт Томпсон

Ба, ти до кінця маєш рацію, @KeithThompson видалив інших, вони цього не варті. Чи можете ви допомогти мені очистити (зараз) застарілі коментарі?
terdon

2
Зверніть увагу, що $NFце останнє слово командного рядка у ps auxвиведенні. Неядерні процеси можуть бути [...]там. Як я вже говорив у своїй відповіді, [xxx]позначення є не тому, що вони є процесами ядра, а тому, що вони не мають командного рядка (жодного аргументу), який також дозволений для неядерних процесів.
Стефан Шазелас

1

Для тих, хто намагається це зробити у зайнятій скриньці, де psсильно спрощено, а вихід відрізняється, цей варіант чудової відповіді Гілла працює добре:

ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'

Відповідно до відповіді Гілла, методологія тут полягає у пошуку процесів, які не використовують жодної пам’яті користувача (`vsz col == 0), та відфільтруванні процесів зомбі (стовпець статусу не '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

0

Якщо вам потрібні лише підрахунки ... У мене була подібна потреба фільтрувати ядра проти користувачів, але мені потрібні були лише відповідні підрахунки кожного. Це було моє рішення:

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]++. Після всіх приростів я маркую і друкую в END { }блоці значення (тобто підрахунки) для p [0] та p [1] .


0

Те, що ти шукаєш, друже, не так 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) для перевірки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.