#! /bin/bash #---------------------------------------------------------------------- # Description: watch raw input output per block device stats in real time # Author: Artem S. Tashkinov # Created at: Sat Apr 6 18:34:33 2013 # Computer: localhost.localdomain # System: Linux 3.8.7-ic on i686 # # Copyright (c) 2013 Artem S. Tashkinov All rights reserved. # Sat Aug 24 19:59:32 2013 - implemented read/write interval counters # Sun Aug 25 23:51:14 2013 - made refreshing three times faster # Thu Feb 4 18:59:41 2016 - exit on pressing q/Q, read refresh rate from console # 2020-03-27 18:04:40 - fix finding the root in /proc/cmdline - remove an extra space, add -w instead # - sort devices numerically # 2021-10-23 04:51:04 - add nvme support # #---------------------------------------------------------------------- shopt -s nullglob export LANG=en_US.UTF-8 rr=2 trap "exit 0" TERM export TOP_PID=$$ qexit() { read -n 1 -t 0.5 -s char if [ "$char" = "q" -o "$char" = "Q" ]; then echo "Bye" kill -s TERM $TOP_PID fi } if [ -n "$1" ]; then if [ "$1" -eq "$1" ] 2>/dev/null; then rr="$1" else echo "[$1] is not a number, setting refresh rate to $rr" sleep 3 fi fi dsrc=/sys/block cd $dsrc || die "$dsrc not found" declare -A intr intw blkr blkw while :; do clear date | tr -d '\n' echo " [ refresh rate: ${rr} seconds ]" echo "Device Read bytes Written bytes Interval read Interval written Mount point" for i in sd* md* nvme*; do # adjust for your environment # for j in $i/$i* $i; do for j in $i/$i[0-9] $i/$i[0-9][0-9] $i/$i[0-9][0-9][0-9] $i/nvme*n*p* $i; do # at most 999 partitions dev=${j##*/} test -z "$dev" && dev="$j" # when iterating $i itself read blkr blkw < <(awk '{print $3" "$7}' $j/stat) # let's speed up this a bit blkr["$dev"]=$blkr blkw["$dev"]=$blkw test -z "${intr[$dev]}" && intr[$dev]=0 test -z "${intw[$dev]}" && intw[$dev]=0 intr[$dev]=$((${blkr[$dev]}-${intr[$dev]})) intw[$dev]=$((${blkw[$dev]}-${intw[$dev]})) test "${blkr[$dev]}" == "${intr[$dev]}" && intr[$dev]=0 # Don't show when iterating for the first time test "${blkw[$dev]}" == "${intw[$dev]}" && intw[$dev]=0 printf "%-10s %'17d %'17d %'14d %'14d " $dev $((blkr[$dev]*512)) $((blkw[$dev]*512)) $((intr[$dev]*512)) $((intw[$dev]*512)) mntp=`awk '/^\/dev\/'$dev' /{print $2}' /proc/mounts` if [ -z "$mntp" ]; then # FIXME: this won't work for partitons mounted via UUID/LABEL grep -qw "root=/dev/$dev" /proc/cmdline && mntp="/" fi echo "$mntp" intr["$dev"]=${blkr["$dev"]} intw["$dev"]=${blkw["$dev"]} done echo done qexit < /dev/stdin & sleep $rr done