For df to calculate totals use the --totals option. If you want the totals only over some select drives specify them as arguments.
Examples (and output form my computer)
This is the total for all local mounts:
$ df --total -hl
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 14G 12G 2,1G 85% /
none 490M 660K 489M 1% /dev
none 497M 1,5M 495M 1% /dev/shm
none 497M 260K 496M 1% /var/run
none 497M 0 497M 0% /var/lock
/dev/sda1 3,7G 418M 3,3G 12% /fastdisk
total 19G 12G 7,3G 62%
Restricting to a few drives (note that if the specified path is not an exact mount point, the closest containing mount point is used [see note at end]):
$ df -hl --total /home /fastdisk
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 14G 12G 2,1G 85% /
/dev/sda1 3,7G 418M 3,3G 12% /fastdisk
total 17G 12G 5,3G 69%
or using dev names:
$ df -hl --total /dev/sda1 /dev/sdb1
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 3,7G 418M 3,3G 12% /fastdisk
/dev/sdb1 14G 12G 2,1G 85% /
total 17G 12G 5,3G 69%
Further customization
If you want to list all mounts except the ‘special’ ones, you can use the -x option to exclude by partition type. (Use the -T option to show the types.)
Personally, for interactive use, I use the following bash alias (added to ~/.bash_aliases) to exclude the ‘non-physical’ mounts.
alias df='df -h -x devtmpfs -x tmpfs -x debugfs'
Note
Specifying paths within mount points can sometime yield results different form specifying the exact path to the mount point. For example, on my laptop I use sshfs to mount my (local) file-server.
df -h ~/.server-root/ ~/.server-root/disks/A ~/.server-root/disks/B
Filesystem Size Used Avail Use% Mounted on
johan@server:/ 185G 58G 118G 33% /home/johan/.server-root
johan@server:/ 1,9T 637G 1,2T 35% /home/johan/.server-root
johan@server:/ 1,8T 1,1T 757G 59% /home/johan/.server-root
The server root (/) is mounted at ~/.server-root. However, on the server, disks are mounted on /disks/*, which df (on the laptop) does not ‘know’ about.
Evidently df can list the disk usage on the different mounts on the server, if given proper paths. However, it shows the same “Filesystem“ and “Mounted on“ for all the paths, since (i believe) that is the only mount point (relating to this sshfs mount) in the local kernel mount table.
Another thing: Not really related to the question, but related to a previous answer to the question.
Adding up the numbers with an awk script (or similar) like some previously posted answers do is not a good idea when using the -h flag. This is because special handling is required. You can not just do size+=$2; for a field that is 418M on one row and 12G on another and get something useful out of it…
For an example with awk, adding 500M to 10.2G yields
$ echo -e '500M\n10.2G' | awk '{size+=$1;} END{print size;}'
510.2
510.2 of what?
There is clearly a problem here. So, just as a tip to remember, when doing (automated) calculation on the output of df (and others that can use ‘human readable’ numbers). Make sure that you do not use the -h flag and that the input to the calculation script is, instead, normalized (for example to bytes, blocks, KBs, or whatever) and do the ‘display scaling’ at the end. It is not to hard, in most scripting and programming languages, to add something like:
If value < threshold Then
print (value),"B"
Else If value < 1024*threshold Then
print (value/1024),"kB"
Else If value < 1024*1024*threshold Then
print (value/1024/1024),"MB"
(and so on...)
where value is in bytes and threshold is a value on the order of 1000. The upshot of this method is that you can easily tune it to produce printed values (excluding the prefix) in a desired range and with a number of significant digits to your choosing. Compared to the case with standard utilities with -h switches, where the format is often fixed.
Of course, this calculation can often be made more efficient and/or elegant, but that is a question for the specific language it is written in. Frankly, if it is used in a user script that is run only now and then to interactively view some information, efficiency is not really a concern.