Як я можу попросити 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]
позначення є не тому, що вони є процесами ядра, а тому, що вони не мають командного рядка (жодного аргументу), який також дозволений для неядерних процесів.
Для тих, хто намагається це зробити у зайнятій скриньці, де 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
Якщо вам потрібні лише підрахунки ... У мене була подібна потреба фільтрувати ядра проти користувачів, але мені потрібні були лише відповідні підрахунки кожного. Це було моє рішення:
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] .
Те, що ти шукаєш, друже, не так 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?