1

I am using command to bring back the Read MB/s.

hdparm -t /dev/sda | awk '/seconds/{print $11}'

From what I was reading it was a good idea to test three times. Add those values up and then divide by 3 for your average.

Sometimes I will have 3 to 16 drives, so I would like to create a question that ask how many drives I have installed. Then perform the hdparm on each drive... Was wondering if there was a simple way to change the SDA all the way up to SDB, SDC, SDD, etc. without typing that command so many times...

Thank you

Jaroslav Kadlec
  • 2,505
  • 4
  • 32
  • 43
LMZ
  • 25
  • 1
  • 7
  • Side note: `grep` is not necessary here, just: `hdparm -t /dev/sda | awk '/seconds/{print $11}'` – hek2mgl Apr 14 '14 at 19:14
  • Thank you for that, I will change up the code. Just looking a better way to write than writing 48 lines of that... – LMZ Apr 14 '14 at 19:22

2 Answers2

1

Bash makes it easy to enumerate all the drives:

$ echo /dev/sd{a..h}
/dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh

Then you said you wanted to average the timing output, so let's define a function to do that:

perform_timing() {
    for i in {1..3}; do hdparm -t "$1"; done |
        awk '/seconds/ { total += $11; count++ } END { print (total / count) }'
}

Then you can run it on all the drives:

for drive in /dev/sd{a..h}; do
    printf '%s: %s\n' "$drive" "$(perform_timing "$drive")"
done

Beaking it Down

The perform_timing function does two things: 1) runs hdparm three times, then 2) averages the output. You can see how the first part works by running it manually:

# for i in {1..3}; do hdparm -t "/dev/sdc"; done

/dev/sdc:
 Timing buffered disk reads: 1536 MB in  3.00 seconds = 511.55 MB/sec

/dev/sdc:
 Timing buffered disk reads: 1536 MB in  3.00 seconds = 511.97 MB/sec

/dev/sdc:
 Timing buffered disk reads: 1538 MB in  3.00 seconds = 512.24 MB/sec

The second part combines your awk code with logic to average all the lines, instead of printing them individually. You can see how the averaging works with a simple awk example:

$ printf '1\n4\n5\n'
1
4
5
$ printf '1\n4\n5\n' | awk '{ total += $1; count++ } END { print (total / count) }'
3.33333

We wrap all that logic in a function called perform_timing as a good programming practice. That lets us call it as if it were any other command:

# perform_timing /dev/sdc
512.303

Finally, instead of writing:

perform_timing /dev/sda
perform_timing /dev/sdb
...

We wrap it all in a loop, which this simplified loop should help explain:

# for drive in /dev/sd{a..c}; do printf '%s\n' "$drive"; done
/dev/sda
/dev/sdb
/dev/sdc
Michael Kropat
  • 14,557
  • 12
  • 70
  • 91
  • Thank you, it seems to be working. Can you break down the code and tell me what is going on? Still new to programing, etc. just would like to understand how things are working here. – LMZ Apr 14 '14 at 19:38
  • @user3533305 I've tried to break it down a little. Let me know if you have any more specific questions. – Michael Kropat Apr 14 '14 at 19:54
  • 1
    Awesome, thank you for helping me out and understanding the code a lot better. It means a lot! – LMZ Apr 14 '14 at 20:01
  • Ok got one more, how does "$1" get the /dev/sda, /dev/sdb, etc? – LMZ Apr 14 '14 at 20:48
  • @user3533305 the `$1` is the first function argument, which gets the value from whatever is passed, as in `perform_timing FIRST_ARGUMENT SECOND_ARGUMENT`. Maybe [start here](http://stackoverflow.com/a/6212408/27581) for more info. – Michael Kropat Apr 15 '14 at 00:06
  • Nice, it also included a link to a guide. That is what I though but was not for sure. – LMZ Apr 15 '14 at 15:32
0

Just use without any loops:

#hdparm -i /dev/sd{a..d}
marchelly
  • 15
  • 4