df
Report free space, per filesystem
df reports free space per filesystem, and du adds up the size of
files. That is the whole difference between them, and it is why they disagree: df asks the
kernel, and du walks a tree and can only count what it is allowed to see.
Give it a path and it answers about whatever filesystem that path is on, so df -h . is usually
the fastest way to find out whether the thing you are about to write will fit. Give it nothing
and it lists every mounted filesystem, most of which on a modern Debian system are tmpfs
pseudo-filesystems that hold no files you put there.
Two ways a disk fills up
Space is one. The other is the inode table, which holds one entry per file and is fixed when the
filesystem is created. Exhaust it and writes fail with No space left on device while df -h
still reports gigabytes free. Only df -i shows it, and it is a cheaper thing to learn
before you need it than during.
Sample files used on this page
Every example below was run against these files. Recreate them to follow along.
two filesystems with sizes this page chose the setup script mounts two tmpfs filesystems with a fixed size and a fixed inode count, so every figure below is one it set rather than a property of the machine running it. /srv/backups holds a single 40M file called site-backup.tar; /srv/small is empty and has 32 inodes, few enough to run out of in one example.
Type Size Inodes Mounted on
tmpfs 100M 4.9K /srv/backups
tmpfs 10M 32 /srv/small
Reading the output
df takes a path and answers about the filesystem that path is on. Without one it reports every mounted filesystem, which on a real machine is a long list.
List every mounted filesystem
df -h
What most people type, and the one form this page cannot show you: the list is whatever your machine has mounted, at whatever size, and half of it is pseudo-filesystems the kernel keeps for itself. Every other example here names a path, and naming one is the better habit anyway.
Ask how much room is left
df -h /srv/backups
-h prints sizes people can read. Six columns: the device, its total size, how much is used, how much is available, that as a percentage, and where it is mounted.
Show output
Filesystem Size Used Avail Use% Mounted on
tmpfs 100M 40M 60M 40% /srv/backups
See what it prints without -h
df /srv/backups
Blocks of 1024 bytes, the default, and almost never what you want at a prompt. In a script it is: the numbers compare directly, with no unit to strip off the end first.
Show output
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 102400 40960 61440 40% /srv/backups
Ask about the directory you are in
cd /srv/backups; df -h .
The shortest useful form. Before unpacking an archive or starting a build, this is the check that takes a second.
Show output
Filesystem Size Used Avail Use% Mounted on
tmpfs 100M 40M 60M 40% /srv/backups
Ask about several at once
df -h /srv/backups /srv/small
The paths are reported in the order given, a row each. Put two paths on the same filesystem and you get a single row, because df reports filesystems and not paths.
Show output
Filesystem Size Used Avail Use% Mounted on
tmpfs 100M 40M 60M 40% /srv/backups
tmpfs 10M 0 10M 0% /srv/small
Point it at a file rather than a directory
df -h /srv/backups/site-backup.tar
The answer is about the filesystem holding the file, not the file. df never reports on a file's own size, and asking it to is the usual reason somebody ends up wanting du instead.
Show output
Filesystem Size Used Avail Use% Mounted on
tmpfs 100M 40M 60M 40% /srv/backups
Show what kind of filesystem it is
df -T /srv/backups
-T inserts a Type column. Useful when you are trying to work out whether the thing you are looking at is a real disk or one of the pseudo-filesystems the kernel mounts for itself.
Show output
Filesystem Type 1K-blocks Used Available Use% Mounted on
tmpfs tmpfs 102400 40960 61440 40% /srv/backups
Add up several filesystems
df -h --total /srv/backups /srv/small
--total appends a summary row. The Mounted on column is a dash there, because a total is not mounted anywhere.
Show output
Filesystem Size Used Avail Use% Mounted on
tmpfs 100M 40M 60M 40% /srv/backups
tmpfs 10M 0 10M 0% /srv/small
total 110M 40M 70M 37% -
Find which mount point holds a file
df --output=target /srv/backups/site-backup.tar
--output=target narrows the report to the mount point alone. Handy when a path runs through several symlinks and you want to know where it really lands.
Show output
Mounted on
/srv/backups
Choosing the columns and the units
Pick the columns you want
df --output=source,fstype,size,pcent,target -h /srv/backups
--output replaces the default set with the fields you name, in the order you name them. The field names are not the column headings: source is the device, target is the mount point, and pcent is Use%.
Show output
Filesystem Type Size Use% Mounted on
tmpfs tmpfs 100M 40% /srv/backups
Cut it down to the two figures you care about
df --output=target,avail -h /srv/backups /srv/small
Where it is and how much is left. Narrow output like this is easier to read at a glance and easier to feed to something else than the full six columns.
Show output
Mounted on Avail
/srv/backups 60M
/srv/small 10M
Report in megabytes
df -B M /srv/backups
-B sets the block size, so the numbers are all in one unit rather than each in whichever unit fits. That makes a column of them comparable, where -h gives you 900M next to 1.1G and leaves the arithmetic to you.
Show output
Filesystem 1M-blocks Used Available Use% Mounted on
tmpfs 100M 40M 60M 40% /srv/backups
Ask for kilobytes explicitly
df -k /srv/backups
-k is -B K and matches the default on Debian. Worth writing out in a script, because the default is a setting and POSIXLY_CORRECT changes it to 512-byte blocks.
Show output
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 102400 40960 61440 40% /srv/backups
Use the portable output format
df -P /srv/backups
-P is the POSIX output format, and its guarantee is one line per filesystem however long the device name is. POSIX specifies 512-byte blocks for it; GNU df keeps 1024 unless POSIXLY_CORRECT is set, so the heading names the size rather than leaving you to assume one.
Show output
Filesystem 1024-blocks Used Available Capacity Mounted on
tmpfs 102400 40960 61440 40% /srv/backups
Report in powers of 1000
df --si /srv/backups
--si divides by 1000 where -h divides by 1024, so the same filesystem reads 105M rather than 100M. Disk manufacturers use the first convention and the kernel uses the second, and this flag is where that argument shows up on your own machine.
Show output
Filesystem Size Used Avail Use% Mounted on
tmpfs 105M 42M 63M 40% /srv/backups
Show only the size columns
df -h --output=size,used,avail /srv/backups
No device and no mount point. Worth knowing that --output drops the columns you leave out rather than hiding them, so the widths change with the fields you ask for.
Show output
Size Used Avail
100M 40M 60M
Ask the same question about inodes
df --output=itotal,iused,iavail,ipcent /srv/small
The inode fields have their own names, all beginning with i. Mixing them with the block fields in one --output works and gives you a wide row that answers both questions at once.
Show output
Inodes IUsed IFree IUse%
32 1 31 4%
Test whether two paths are on one filesystem
df --output=source /srv/backups /srv/backups/site-backup.tar | sort -u
sort -u leaves the heading and a single device, so both paths are on the same filesystem. A second device would mean a mv between them is a copy and a delete rather than a rename, so one is instant and the other takes as long as the file is big.
Show output
Filesystem
tmpfs
Get a bare number for a script
df --output=avail -B M /srv/backups | tail -1 | tr -d ' M'
--output with one field, tail -1 to drop the heading, and tr to strip the unit and the padding. Fix the unit with -B or the comparison is against text: -h gives you 60M one day and 1.2G the next.
Show output
60
Get the percentage the same way
df --output=pcent /srv/backups | tail -1 | tr -d ' %'
The form a monitoring script wants, and it needs no -B, since a percentage carries no unit to vary. Compare it as a number and alert above whatever threshold you can actually act on.
Show output
40
Space free, and still no space left
A filesystem has two things it can run out of. Every figure below comes from /srv/small, which has 10M of space and room for 32 files.
Count the inodes instead of the bytes
df -i /srv/small
-i reports the inode table rather than the blocks. One entry is already used, for the mount point's own directory.
Show output
Filesystem Inodes IUsed IFree IUse% Mounted on
tmpfs 32 1 31 4% /srv/small
Fill the table up
cd /srv/small
for i in $(seq 1 40); do touch "file$i" 2>/dev/null; done
ls | wc -l
Forty attempts and thirty-one files, because the directory itself holds the thirty-second inode. The failures were silent here only because the loop discards them.
Show output
31
Watch a write fail on a filesystem with space free
cd /srv/small
for i in $(seq 1 40); do touch "file$i" 2>/dev/null; done
touch one-more.txt
No space left on device, on a filesystem that has used none of its 10M. The message is the same one you get for a genuinely full disk, and it is the reason this failure wastes so much time: everything you check first says there is room.
Show output
touch: cannot touch 'one-more.txt': No space left on device
Ask both questions and see them disagree
cd /srv/small
for i in $(seq 1 40); do touch "file$i" 2>/dev/null; done
df -h . | tail -1
df -i . | tail -1
Nought per cent of the space and a hundred per cent of the inodes. Run df -i before anything else when a write fails and df -h looks healthy: it is one command and it either explains the problem or rules it out.
Show output
tmpfs 10M 0 10M 0% /srv/small
tmpfs 32 32 0 100% /srv/small
See df and du disagree about the same filesystem
dd if=/dev/zero of=/srv/small/tmpfile bs=1M count=5 status=none
exec 3< /srv/small/tmpfile
rm /srv/small/tmpfile
du -sh /srv/small
df -h /srv/small | tail -1
A deleted file that a process still has open. du walks the directory and finds nothing, because the name is gone; df asks the kernel, which cannot release the blocks until the last descriptor closes. On a real machine this is usually a log file somebody deleted without restarting the service that writes it.
Show output
0 /srv/small
tmpfs 10M 5.0M 5.0M 50% /srv/small