Знать, какой процесс делает ввод / вывод без iotop

12

В Linux я хочу знать, какой процесс использует пропускную способность моего дискового ввода-вывода.

Я знаю, что могу использовать, iotopно у меня есть машина, которая по разным причинам iotopне может быть установлена.

Как я могу вручную получить эту информацию? (Как iotopсебя продвигает?)

Totor
источник

Ответы:

15

Файл /proc/<pid>/ioпредставляет то, что вам нужно. Это немного скриптовая работа, чтобы получить вывод, похожий на iotop. Обратитесь к документации ядра Linux к /proc/<pid>/ioзначениям файла:

rchar

Счетчик ввода / вывода: chars read Количество байтов, которые эта задача вызвала для чтения из хранилища. Это просто сумма байтов, которые этот процесс передал read () и pread (). Он включает в себя такие вещи, как tty IO, и не зависит от того, требовался ли фактический ввод-вывод физического диска (чтение могло быть выполнено из pagecache)

WCHAR

Счетчик ввода / вывода: записанные символы Число байтов, вызванных или заданных этой задачей на диске. Подобные предостережения применимы здесь как с rchar.

[...]

read_bytes

Счетчик ввода / вывода: чтение байтов Попытка подсчитать количество байтов, которое этот процесс действительно вызвал для извлечения из уровня хранения. Выполнено на уровне submit_bio (), поэтому оно является точным для файловых систем с блочной поддержкой.

write_bytes

Счетчик ввода / вывода: записано байтов Попытка подсчитать количество байтов, которое этот процесс вызвал для отправки на уровень хранения. Это делается во время загрязнения страницы.

Теперь вы можете использовать этот небольшой bashскрипт:

#!/bin/bash

if [ "$(id -u)" -ne 0 ] ; then
  echo "Must be root" 2>&1
  exit 1
fi

delay=2
lista=$(for p in $(pgrep "."); do echo -n "$p "; grep ^rchar /proc/$p/io 2>/dev/null; done)

while :; do

  echo "-----"
  listb=$(for p in $(pgrep "."); do echo -n "$p "; grep ^rchar /proc/$p/io 2>/dev/null; done)

  echo "$lista" | while read -r pida xa bytesa; do
    [ -e "/proc/$pida" ] || continue
    echo -en "$pida:\t"
    bytesb=$(echo "$listb" | awk -v pid=$pida '$1==pid{print $3}')
    echo "$((($bytesb - $bytesa) / $delay)) b/s"
  done | sort -nk2 | tail
  sleep $delay
  listb=$lista
done

Он создает два списка с задержкой в ​​2 секунды ( $delay: может быть увеличен или уменьшен) между ними, а затем сравнивает списки и вычисляет различия. 10 процессов с наибольшим количеством операций ввода / вывода печатаются с их полосой ввода / вывода за последние 2 секунды. Если вы хотите записать ввод / вывод вместо чтения ввода / вывода, просто отредактируйте grepкоманду в списках wcharвместо rchar:

lista=$(for p in $(pgrep "."); do echo -n "$p "; grep ^wchar /proc/$p/io 2>/dev/null; done)
listb=$(for p in $(pgrep "."); do echo -n "$p "; grep ^wchar /proc/$p/io 2>/dev/null; done)
хаос
источник