35

I'm trying to output the amount of free disk space on the filesystem /example.

If I run the command df -k /example I can get good information about available disk space in kb but only by being human and actually looking at it.

I need to take this data and use it somewhere else in my shell script. I initially thought about using cut but then my script wont be portable to other disks as free disk space will vary and cut will not produce accurate results.

How can I get output of just the free disk-space of example in kb?

fedorqui
  • 275,237
  • 103
  • 548
  • 598
Whoppa
  • 949
  • 3
  • 13
  • 23

5 Answers5

64

To get the output of df to display the data in kb you just need to use the -k flag:

df -k

Also, if you specify a filesystem to df, you will get the values for that specific, instead of all of them:

df -k /example

Regarding the body of your question: you want to extract the amount of free disk space on a given filesystem. This will require some processing.

Given a normal df -k output:

$ df -k /tmp
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda1        7223800 4270396   2586456  63% /

You can get the Available (4th column) for example with awk or cut (previously piping to tr to squeeze-repeats (-s) for spaces):

$ df -k /tmp | tail -1 | awk '{print $4}'
2586456
$ df -k /tmp | tail -1 | tr -s ' ' | cut -d' ' -f4
2586456

As always, if you want to store the result in a variable, use the var=$(command) syntax like this:

$ myUsed=$(df -k /tmp | tail -1 | awk '{print $4}')
$ echo "$myUsed"
2586456

Also, from the comment by Tim Bunce you can handle long filesystem names using --direct to get a - instead, so that it does not print a line that breaks the engine:

$ df -k --direct /tmp
Filesystem     1K-blocks    Used Available Use% Mounted on
-                7223800 4270396   2586456  63% /
Community
  • 1
  • 1
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Thank you! This is exactly what I needed. I appreciate you taking the time to give me an answer rather than just down vote like the others :( +1 for you! – Whoppa Oct 31 '13 at 10:15
  • Yes I tried too but the site is telling me I need to wait another 10 minutes to accept an answer. – Whoppa Oct 31 '13 at 10:17
  • 1
    You can use `cut` instead of `awk` in this case. No need to use a tank to kill a fly :) – Idriss Neumann Oct 31 '13 at 10:17
  • 1
    @IdrissNeumann yes, I agree, maybe I like `awk` too much :D Updated with `cut` version, although it needs an extra pipe to squeeze the spaces. – fedorqui Oct 31 '13 at 10:20
  • Yes but wouldnt this take away portability? Because the length of the free disk-space could greatly vary on different file systems. So using cut would not accurately capture it unless I knew the exactly beginning and end index of the third arg. If theres a way to do this I'd love to know how! – Whoppa Oct 31 '13 at 10:20
  • 1
    oh you can specify the arg to cut with -f flag. I didn't know that, thanks! – Whoppa Oct 31 '13 at 10:21
  • 5
    The `tail -1` then counting fields isn't safe because `df` may wrap put a newline after the filesystem name if it's long (e.g., for me `/dev/mapper/vg_1-lv_root`). A workaround is to use the `--direct` option which reports the filestem as `-`. – Tim Bunce Jan 02 '15 at 13:00
  • The question asks for 'free space' but the answer here reports the use space. Fix by using field 4 instead of field 3. – Tim Bunce Jan 02 '15 at 13:01
  • If the script is just trying to get a rough figure then try `--block-size=1G` to work in smaller GB values rather than very large KB values – Tim Bunce Jan 02 '15 at 13:08
  • @TimBunce thanks a lot for the valuable comments. Just updated accordingly! – fedorqui Jan 06 '15 at 12:03
14

You can use stat(2) command to display free blocks and also to find out how large each block is, e.g.

stat -f --printf="%a %s\n" /

will display number of free blocks (%a) on a given file system (/) followed by a block size (%s). To get size in kB, you can use bc(1) command as in the following example:

stat -f --printf="%a * %s / 1024\n" / | bc

Finally, to put this into a variable is just a matter of using backtick substitution (or $() as in the first answer):

SOMEVAR=`stat -f --printf="%a * %s / 1024\n" / | bc`
sgros
  • 181
  • 1
  • 3
10

Show interesting columns only

 df /example --total -k -h  --output=source,avail
  • --total = grand total at the end
  • -k = block size 1K
  • -h = human readable
  • --output=[FIELD_LIST] column list to show separated by ","

Not totally standard (I have seen --output is available at least on Ubuntu and RHEL), in this case Awk and others just to remove columns are not necessary.

9

This is another solution:

df --output=avail -m /example | tail -1

output:

6415

Alberto Rojas
  • 549
  • 5
  • 5
  • 2
    Your solution can be further modified to `df --output=avail -m /example | tail -1 | tr -d ' '` to remove the space in front of the output. – Rounak Feb 05 '20 at 17:15
  • This is nice because it provides a purely numerical value. – Jesse Nickles Dec 03 '21 at 18:50
  • The free space returned by "df --output=avail -m /example | tail -1" is different from when you run the command "df /example" – Dorcioman Sep 16 '22 at 11:31
0

i created small script which will fetch the filesystem used space and will convert the total used space size in GB.

df -Th | grep -vE "tmpfs|nfs|boot|overlay|vfat|cifs"| awk '{print $4}'|sed 's/.$//'| grep -vw "^Use"| paste -s -d+|bc