« Back to Linux file systems

Understanding the output of the stat command

The stat command can be used to show file statistics, such as file size, ownership, type, and several timestamps. It is a great addition to ls. Time to let it work for us!

Basic example

If we use the command on our /etc/passwd file, we might get output like below.

# stat /etc/passwd
  File: /etc/passwd
  Size: 3387      	Blocks: 8          IO Block: 4096   regular file
Device: 10303h/66307d	Inode: 47186412    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 15:17:01.121123879 +0200
Modify: 2024-03-04 14:01:44.569913427 +0100
Change: 2024-03-04 14:01:44.577913496 +0100
 Birth: 2024-03-04 14:01:44.569913427 +0100

Explanation of the fields

Let’s have a look at all the fields and understand what the shared information means.

File

The field File is the file name. Nothing really exciting here.

Size

The field Size represents the file size. This value is in bytes and similar to the output of a command like ls.

Blocks

The field Blocks is the first one where things get more interesting. It represents the number of reserved blocks to store data and meta-data about the file. It is related to the field IO Block that defines the size of a block to read or write from disk. The big difference is that a block is 512 bytes (sector size), where the IO block is usually 4096 bytes. In other words, those 8 blocks make up the 4096 bytes (4KiB) in total.

When an empty file is created, the number of blocks is zero. When just a little bit of data is stored, you would normally expect the block to increase to one. But as the file system uses IO blocks of 4096 bytes, it needs 8 blocks.

Type

Behind the IO Block, our example states regular file. One might expect this output after the field File, but instead it listed at the second line. The value could be one of these types:

  • block special file
  • character special file
  • directory
  • fifo
  • port
  • regular file
  • regular empty file
  • semaphore
  • shared memory object
  • socket
  • symbolic link
  • timed memory object

Device

The Devicee field is the device displayed. The format is hexadecimal and refers to the device on which the file resides.

Inode

Not really surprising, but the field Inode refers to inode within the file system. The value is normally unique, unless there are multiple hard links to the same inode. Or, in other words, if there are more file names that point to the exact same data.

The field Links is related to the field above. It shows how many files point to this inode. If it is showing 1, then there is only one file name pointing to this inode.

Access

With the field Access we get a familiar output of the ls command. Both in an octal and human readable format.

Uid and Gid

The field Uid refers to the owner (User ID), and Gid to the group (Group ID). Both displayed as a number and the user or group name.

Time stamps

Access time

Another line that starts with ‘Access:’, but this time referring to the access time. If you read the content of a file, then this attribute will be updated.

Modify time

The modify time refers to the time the actual contents of the file was changed.

Change time

Often the change and modification time are the same or very close. The change time is updated when meta-data of the file is updated. When we alter the content of a file, the access time, modification time, and change time are updated.

Birth time

As the name implies, the birth time is the moment of when a file was initially created. This value should normally only be set once.

Testing stat on a practice file

Let’s create an empty file and check the file information:

# touch test
# stat test
  File: test
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: 10303h/66307d	Inode: 22968322    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ michael)   Gid: ( 1000/ michael)
Access: 2024-05-08 20:35:31.526876522 +0200
Modify: 2024-05-08 20:35:31.526876522 +0200
Change: 2024-05-08 20:35:31.526876522 +0200
 Birth: 2024-05-08 20:35:31.526876522 +0200

We can see in the output that we have a ‘regular empty file’. The file size is zero, but so is the number of blocks! That is surprising, as the creation of a file needs to be stored somewhere, right? In this case the information is stored in the block of the inode. As there is no data in the file, no IO blocks had to be claimed. All timestamps are the same, which is to be expected as we created the file and performed no other actions with it.

Let’s add a bit of text to the file:

# echo "test" > test
# stat test
  File: test
  Size: 5         	Blocks: 8          IO Block: 4096   regular file
Device: 10303h/66307d	Inode: 22968322    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ michael)   Gid: ( 1000/ michael)
Access: 2024-05-08 20:35:31.526876522 +0200
Modify: 2024-05-08 20:35:52.199129382 +0200
Change: 2024-05-08 20:35:52.199129382 +0200
 Birth: 2024-05-08 20:35:31.526876522 +0200

Now the number of blocks went to 8, as expected. The file size is no 4, but 5 bytes. Wondering why? Run ‘hexdump -c’ on the file to find the answer.

Relevant commands in this article

Like to learn more about the commands that were used in this article? Have a look, for some there is also a cheat sheet available.

  • hexdump
  • stat

Feedback

Small picture of Michael Boelen

This article has been written by our Linux security expert Michael Boelen. With focus on creating high-quality articles and relevant examples, he wants to improve the field of Linux security. No more web full of copy-pasted blog posts.

Discovered outdated information or have a question? Share your thoughts. Thanks for your contribution!

Mastodon icon