Как я могу контролировать использование процессора пользователем?

15

Мне нужно контролировать использование процессора пользователями двух серверов (Ubuntu и CentOS). Например:

user1     5%
user2    10%
...

Есть ли такой инструмент topили htopкоторый может это сделать?

Amged Rustom
источник
Вам нужно, чтобы верх отображался в реальном времени? В противном случае вы можете рассмотреть top -u userи перенаправить результат в файл, а затем отслеживать другого пользователя. Затем у вас будет монитор использования proc для ваших пользователей через заданный интервал.
Лоран С.
Когда вы говорите, монитор в течение какого периода? Время от времени или постоянно?
SLM
Я надеюсь, что смогу контролировать пользователей в режиме реального времени, как топ.
Amged Rustom

Ответы:

17

Вот скрипт для печати общего использования ЦП для каждого пользователя, вошедшего в данный момент , showPerUserCPU.sh :

own=$(id -nu)
cpus=$(lscpu | grep "^CPU(s):" | awk '{print $2}')

for user in $(who | awk '{print $1}' | sort -u)
do
    # print other user's CPU usage in parallel but skip own one because
    # spawning many processes will increase our CPU usage significantly
    if [ "$user" = "$own" ]; then continue; fi
    (top -b -n 1 -u "$user" | awk -v user=$user -v CPUS=$cpus 'NR>7 { sum += $9; } END { print user, sum, sum/CPUS; }') &
    # don't spawn too many processes in parallel
    sleep 0.05
done
wait

# print own CPU usage after all spawned processes completed
top -b -n 1 -u "$own" | awk -v user=$own -v CPUS=$cpus 'NR>7 { sum += $9; } END { print user, sum, sum/CPUS; }'

А вот немного измененная версия для печати использования ЦП всеми доступными пользователями (но пропуская тех, у которых загрузка ЦП равна нулю), showAllPerUserCPU.sh :

own=$(id -nu)
cpus=$(lscpu | grep "^CPU(s):" | awk '{print $2}')

for user in $(getent passwd | awk -F ":" '{print $1}' | sort -u)
do
    # print other user's CPU usage in parallel but skip own one because
    # spawning many processes will increase our CPU usage significantly
    if [ "$user" = "$own" ]; then continue; fi
    (top -b -n 1 -u "$user" | awk -v user=$user -v CPUS=$cpus 'NR>7 { sum += $9; } END { if (sum > 0.0) print user, sum, sum/CPUS; }') &
    # don't spawn too many processes in parallel
    sleep 0.05
done
wait

# print own CPU usage after all spawned processes completed
top -b -n 1 -u "$own" | awk -v user=$own -v CPUS=$cpus 'NR>7 { sum += $9; } END { print user, sum, sum/CPUS; }'

Первый столбец представляет имя пользователя, второй столбец - совокупное использование ЦП, а третий столбец - нормализованное использование ЦП в соответствии с количеством ядер ЦП.

Существует также связанный скрипт для отображения общего использования памяти для каждого пользователя: showPerUserMem.sh

Для мониторинга в реальном времени просто периодически выполняйте эти сценарии с помощью watchкоманды.

Для сортировки по загрузке процессора направьте вывод в sort -k2 -nr.

SCAI
источник
1
почему вы смешиваете переменную bash env с переменной сценария, значит, $ USER уже существует, даже все переменные caps - это env, не так ли?
Рахул Патил
Я не думаю, что все прописные переменные должны быть переменными среды. Но я согласен, что перезапись уже существующих переменных не очень хороший стиль.
Scai
1
Обычно плохая идея использовать UPPERCASE в bash по той причине, о которой упоминал Рахул. Еще хуже, когда вы используете имя переменной, которая уже существует как окружающая среда (n bash, $USERэто уже ваше имя пользователя, так что это то же самое, что и id -nuкоманда, которую вы используете. Я отредактировал ваше сообщение, чтобы изменить это.
terdon
Использование переменных верхнего регистра в сценариях оболочки, безусловно, неплохая идея, поскольку девять из десяти сценариев в моем /etc/init.d/каталоге тоже делают это. Следует избегать перезаписи существующих переменных среды.
Scai
1
Я добавил версию, чтобы включить каждого пользователя, а не только тех, кто в данный момент вошел в систему.
scai