'How to capture output of df -h --total - Bash

I am writing a script which will be used to gather information on the available and used space on different partitions across servers. I need to be able to capture the output as a variable.

For example, if the output looked like:

Filesystem                          Size  Used Avail Use% Mounted on
devtmpfs                            2.9G     0  2.9G   0% /dev
tmpfs                               2.9G  4.0K  2.9G   1% /dev/shm
tmpfs                               2.9G  488K  2.9G   1% /run
tmpfs                               2.9G     0  2.9G   0% /sys/fs/cgroup
/dev/mapper/vg_os-lv_root           3.9G  1.6G  2.1G  44% /

How could I capture 2nd row Used, Avail and Mounted on as variables?



Solution 1:[1]

I use a general way for things like that: for capturing a line, I use grep in case of a keyword, or a combination of head and tail in case of a line number. Then, I use awk for getting a certain column.

In this case, you get something like:

var_used=$(df -hk | grep "/dev/shm" | awk '{print $3}')
var_avail=$(df -hk | grep "/dev/shm" | awk '{print $4}')
var_mounted=$(df -hk | grep "/dev/shm" | awk '{print $6}')

In case you're interested in the "/dev" one, you need to grep on /dev$ (the dollar sign stands for "end-of-line").

For your information: I've mentioned the head and tail usage, but I don't show exactly how it works, for the simple reason: you seem to be interested in one particular line (like the "/dev" one), which currently is at the first line of your output. If, for any reason, this line number changes, you might need to rework your script, but using the "grep" approach this problem won't occur.

Solution 2:[2]

First i'd suggest to use special options for df to get only needed fields:

$ df -h --output=avail,used,target
Avail  Used Mounted on
 7.3G     0 /dev
 1.5G  3.2M /run
 7.0G   21G /
 7.2G  188M /dev/shm
 5.0M  4.0K /run/lock
 7.4G     0 /sys/fs/cgroup
  61G  189G /home
 1.5G   16K /run/user/125
 1.5G   60K /run/user/1000

And then use readarray(mapfile) to store data into an array:

readarray -t -s1 arr <<< $(df -h --output=avail,used,target)

Readarray options:

-s count  Discard the first COUNT lines read
-t        Remove a trailing DELIM from each line read (default newline)

Which can be accessed like this:

$ echo ${arr[0]}
7.3G 0 /dev

Split into vars:

read avail used mount <<< ${arr[0]}
$ echo $avail $used $mount
7.3G 0 /dev

Solution 3:[3]

You can use sed or alternatively head and tail to get the second line, or if you know the mount point, grep.

To parse the line, you can use awk and you split on one or more spaces and print the elements that you want out of this:

df -h --total | sed -n '2 p' | awk -F "[[:space:]]+" '{ print $3 " " $4 " " $6 }'

To assign this to a variable, do:

stats=$(df -h --total | sed -n '2 p' | awk -F "[[:space:]]+" '{ print $3 " " $4 " " $6 }')

[EDIT]: Following the suggestion in the comments:

df -h --total | awk -F "[[:space:]]+" 'NR==2{print $3 " " $4 " " $6 }'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tripleee
Solution 2
Solution 3