#linux #bash #swap
Нужен скрипт, выводящий список процессов, использующих swap. Должно быть отсортировано по объёму памяти процесса, находящемуся в swap
Ответы
Ответ 1
Скрипт: #!/bin/bash for proc_dir in /proc/* do if [ -d "$proc_dir" ] then pid=$(basename "$proc_dir") if [[ $pid =~ ^-?[0-9]+$ ]] then if grep -q "VmSwap" $proc_dir/status then swap_usage_nums=$(cat $proc_dir/status | grep VmSwap | awk '{ print $2 }') if (( swap_usage_nums > 0 )) then swap_usage_unit=$(cat $proc_dir/status | grep VmSwap | awk '{ print $3 }') cmdline=$(cat $proc_dir/cmdline | sed -e "s/\x00/ /g";) echo "${swap_usage_nums}${swap_usage_unit} $cmdline" fi fi fi fi done | sort -h -r Пример работы: 4400kB /usr/bin/ruby -C/var/lib/pcsd -I/usr/share/pcsd -- /usr/share/pcsd/ssl.rb & > /dev/null & 3960kB /usr/bin/telegraf -config /etc/telegraf/telegraf.conf -config-directory /etc/telegraf/telegraf.d 2492kB /usr/sbin/apache2 -k start 2492kB /usr/sbin/apache2 -k start 2492kB /usr/sbin/apache2 -k start 2492kB /usr/sbin/apache2 -k start 2472kB /usr/sbin/apache2 -k start 1884kB /usr/sbin/apache2 -k start 1872kB /usr/share/journalbeat/bin/journalbeat -e -c /etc/journalbeat/journalbeat.yml -path.home /usr/share/journalbeat -path.config /etc/journalbeat -path.data /var/lib/journalbeat -path.logs /var/log/journalbeat 1300kB /lib/systemd/systemd-udevd 1220kB /usr/sbin/rsyslogd -n 1132kB /usr/local/bin/node_exporter --collector.arp --collector.buddyinfo --collector.conntrack --collector.cpu --collector.cpufreq --collector.diskstats --collector.entropy --collector.filefd --collector.filesystem --collector.hwmon --collector.loadavg --collector.logind --collector.meminfo --collector.meminfo_numa --collector.mountstats --collector.netclass --collector.netdev --collector.netstat --collector.processes --collector.sockstat --collector.stat --collector.systemd --collector.textfile --collector.time --collector.uname --collector.vmstat --no-collector.bcache --no-collector.bonding --no-collector.drbd --no-collector.edac --no-collector.infiniband --no-collector.interrupts --no-collector.ipvs --no-collector.ksmd --no-collector.mdadm --no-collector.nfs --no-collector.nfsd --no-collector.ntp --no-collector.perf --no-collector.pressure --no-collector.qdisc --no-collector.runit --no-collector.supervisord --no-collector.tcpstat --no-collector.timex --no-collector.wifi --no-collector.xfs --no-collector.zfs --web.listen-address=[::]:9090 --collector.diskstats.ignored-devices=^(ram|loop|fd)\d+$ --collector.filesystem.ignored-mount-points=^/(sys|proc|dev|run)($|/) --collector.textfile.directory=/var/lib/node_exporter/textfile_collector/ 980kB /usr/sbin/keepalived 896kB /usr/sbin/keepalived 848kB /usr/sbin/keepalived 832kB /usr/bin/redis-server 127.0.0.1:6380 828kB /usr/bin/redis-server 127.0.0.1:6381 816kB /usr/bin/redis-server 127.0.0.1:6379 804kB /usr/bin/redis-sentinel *:26379 [sentinel] 660kB /usr/sbin/sshd -D 644kB /sbin/init 536kB ha_logd: write process 532kB ha_logd: read process 504kB /sbin/rpcbind -f -w 412kB /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 106:110 372kB /lib/systemd/systemd-logind 372kB /lib/systemd/systemd-journald 336kB ssh-agent -s 332kB ssh-agent -s 332kB ssh-agent -s 272kB /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation 204kB /usr/sbin/cron -f 152kB /sbin/agetty --noclear tty1 linux 148kB /sbin/iscsid 140kB /usr/sbin/acpid Возможные изменения будут тутОтвет 2
grep -HP "VmSwap:[ \t]+[1-9]" /proc/[0-9]*/status |\ sed -r 's/(.*)status:VmSwap:[ \t]+([^\t ]+)[ \t]+([a-zA-Z]+)/printf "%-20s | %s\n" "size: \2\3" "command: `cat \1cmdline`"/g' |\ /bin/bash |\ sort -t':' -k '2,2' -nr Теперь более подробно: #Ищем все процессы у которых значение swap не начинается с 0, следовательно не пустое grep -HP "VmSwap:[ \t]+[1-9]" /proc/[0-9]*/status Далее #Форматируем вывод, удаляя не нужные данные с помощью sed, группу замены рассмотрим отдельно sed -r 's/(.*)status:VmSwap:[ \t]+([^\t ]+)[ \t]+([a-zA-Z]+)/.../g' #Группа замены: "делаем форматированным вывод, что бы избежать явного цикла, #просто подготавливаем команды для передачи интерпретатору, подставляя для каждого printf "%-20s | %s\n" "size: \2\3" "command: `cat \1cmdline`" Далее #Передаем в интерпретатор подготовленные команды и получаем нужный результат #отсортированный по максимальному значению используемой памяти в swap разделе. /bin/bash |\ sort -t':' -k '2,2' -nr Замеры по таймингу выполнения: 1-й предложенный вариант - real 0m4.828s 2-й предложенный вариант - real 0m1.268s Мой вариант - real 0m0.122sОтвет 3
Ваш скрипт работает, но можно короче и без башизмов: #!/bin/sh for piddir in $(ls -d /proc/[0-9]*) do c="$(test -e "${piddir}/cmdline" && cat "${piddir}/cmdline" | sed -e 's/\x00//g')" u="$(test -e "${piddir}/status" && awk '$1 == "VmSwap:" && $2 > 0 { print $2 $3; }' "${piddir}/status")" test "$u" != "" && echo "$u $c" done | sort -h -r
Комментариев нет:
Отправить комментарий