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.
Links
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.