Linux stat Command: Display Detailed File Metadata

stat is a command that shows detailed information about the size, permissions, owner, inode, number of hard links, allocated blocks, and various timestamps of a file or directory. It allows you to check more metadata than ls -l and is also useful for shell scripts because you can output only the desired fields in a consistent format.

In this article, we explain how to read the default output of GNU Coreutils' stat, the differences between atime/mtime/ctime/Birth, symbolic links, file system information, and how to use --format.

What is the stat command?

stat retrieves the status information managed by the file system, that is, metadata, rather than the contents of the file. You just need to specify the file or directory you want to check as an argument.

stat report.txt
stat /etc
stat /usr/bin/bash

It has a different purpose from the file command, which reads the file directly to analyze its contents. file guesses the format, whereas stat shows file system information such as size, permissions, ownership, timestamps, and inode.

Basic Syntax and Usage

stat [option] file...

You can specify not only a single file but also multiple paths at once.

stat file1.txt file2.txt
stat src tests
stat "annual report.pdf"

For filenames starting with a hyphen, specify them after -- so they are not misinterpreted as options.

stat -- -sample.txt

You can check the version of GNU stat and supported options with the following command.

stat --version
stat --help
info '(coreutils) stat invocation'

How to Read Basic Output

When you run stat on a regular file, you will see information similar to the following. Actual values and some fields may vary depending on the file system and operating system.

  File: report.txt
  Size: 4096       Blocks: 8          IO Block: 4096   regular file
Device: 8,1        Inode: 1234567     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/ user)   Gid: ( 1000/ user)
Access: 2026-09-21 10:15:30.000000000 +0900
Modify: 2026-09-21 10:14:02.000000000 +0900
Change: 2026-09-21 10:14:02.000000000 +0900
 Birth: 2026-09-20 19:42:11.000000000 +0900

Each item has the following meaning.

Item Meaning
File The name of the file or directory being queried.
Size The logical size of the file, usually displayed in bytes.
Blocks The number of blocks allocated to the file. Sparse files or compressed file systems may show a large difference between the logical size and actual allocation.
IO Block Recommended block size information for efficient input/output.
Device The number identifying the device to which the file belongs.
Inode This is the inode number that identifies the file metadata within the file system.
Links The number of hard links pointing to the same inode.
Access Shows permissions and file type in octal and symbolic form.
Uid, Gid The numeric ID and name of the owner user and group.
Access, Modify, Change, Birth Timestamps regarding access, content modification, status change, and creation.

Difference between ls -l and stat

Comparison items ls -l stat
Main Purpose Quickly compare multiple files in list form. Check detailed metadata of the specified file.
Basic time Mainly displays the modification time briefly. Displays access, modification, status change, and creation times separately.
inode and blocks You need to add options to see some information. Shows inode, number of links, allocated blocks, etc., in the default output.
Script output Parsing human-readable lists can be unstable depending on the environment. You can directly specify the necessary fields with --format.
File system information Not provided directly. Use -f to display the file system status where the file is located.

When browsing names, sizes, and permissions of multiple files, ls -l is convenient, and if you need accurate fields of a single file or values for automation, stat is suitable.

Understanding file size and allocated blocks

Checking logical size

The default output Size is the total number of bytes that the file represents. To output only the needed value, use %s.

stat -c '%s' disk.img
stat -c '%n: %s bytes' file1 file2

The Size of a directory is not the sum of all the files within it. It is the size of the directory itself that stores the directory entries. To check the total usage of the contents, use du.

Calculating allocated space

%b outputs the number of allocated blocks, and %B outputs the size in bytes of a single block.

stat -c 'size=%s blocks=%b block-size=%B' disk.img

The approximate allocated byte count can be calculated with %b × %B. Sparse files may have actual allocated space that is much smaller than the logical size, and with features like file system compression or shared blocks, it is difficult to determine physical storage usage from this value alone.

Checking permissions and ownership

Outputting octal permissions and symbolic permissions

%a outputs octal permissions, and %A outputs human-readable permissions including the file type.

stat -c '%a %A %n' script.sh

The output can be in the following form.

755 -rwxr-xr-x script.sh

Displaying owner and group

%U and %G display the username and group name, while %u and %g display the numeric UID and GID.

stat -c 'owner=%U(%u) group=%G(%g)' report.txt

In environments where the name corresponding to a numeric ID cannot be found, the name field may be displayed differently.

Checking inode and hard links

Displaying inode number

%i displays the inode number that identifies the file within the file system.

stat -c '%i %n' report.txt

Inode numbers are not globally unique across file system boundaries. To compare whether files are the same, you must consider the device information along with the inode.

Checking the Number of Hard Links

%h is the number of hard links pointing to that inode.

stat -c 'inode=%i links=%h name=%n' original.txt copy-link.txt

If the device and inode of two paths are the same, they may be hard links pointing to the same file data. Symbolic links have separate inodes, so they are not judged in the same way.

Differences Between atime, mtime, ctime, and Birth

The timestamp names are similar, but the events they record are different. In particular, it is important not to mistake ctime for the creation time.

Time Meaning Examples that Can Be Changed
atime The last access time of the file data. File read. However, depending on mount options and cache policies, it may not be updated each time.
mtime The last time the file content was modified. Writing file data or changing the content length.
ctime The last time the inode status information was changed. Changes in permissions, owner, number of links, name changes, etc. Not the creation time.
Birth The time the file was created. Recorded once at creation if supported and does not change with normal status changes.

Print human-readable time

%x, %y, %z, and %w print atime, mtime, ctime, and Birth in a human-readable format, respectively.

stat -c 'atime=%x
mtime=%y
ctime=%z
birth=%w' report.txt

On file systems that do not support Birth or cannot obtain its value, %w may be displayed as a hyphen.

Output in seconds since the Epoch

Uppercase %X, %Y, %Z, %W output the respective times in seconds since the Unix Epoch.

stat -c 'atime=%X mtime=%Y ctime=%Z birth=%W' report.txt

When Birth is unknown, %W outputs 0. While the Epoch value is convenient for sorting or numeric comparison, the differences in time precision provided by file systems and operating systems should be considered.

Checking symbolic link information

Viewing the metadata of the link itself

By default, GNU stat does not follow symbolic links and examines the link itself.

stat current.log
stat -c '%N | inode=%i | type=%F' current.log

%N can display the file name in quotes along with its target for links.

View target metadata with -L

Using -L or --dereference checks the status of the actual target that the link points to.

stat -L current.log
stat -L -c '%n | inode=%i | type=%F | size=%s' current.log

Broken symbolic links cannot check the target, so using -L will cause an error.

Print only the desired fields

Using -c and --format

-c or --format outputs the results in the specified format and adds a line break for each file.

stat -c '%n %s %a %U:%G' file1 file2
stat --format='name=%n type=%F inode=%i' report.txt

It is safe to enclose the format string in single quotes so that the shell does not interpret it.

Compose multiple lines with --printf

--printf interprets backslash escapes but does not add automatic line breaks. Insert \n directly where necessary.

stat --printf='name=%n\nsize=%s\nmode=%a\n' report.txt

When processing multiple files, the format string should also include separators between files.

Frequently used format specifiers

Specifier Output content
%n The file name.
%N The quoted file name, and if it is a symbolic link, it may also include information about the target.
%F The file type, such as a regular file, directory, or symbolic link.
%s This is the total size (in bytes).
%b This is the number of allocated blocks.
%B This is the byte size of a block represented by %b.
%a Octal permissions.
%A Symbolic permissions including file type.
%u, %g The numeric UID and GID of the owner.
%U, %G The owner's username and group name.
%i The inode number.
%h Number of hard links.
%m The mount point the file belongs to.
%x, %X Display the last access time in a human-readable format or as Epoch seconds.
%y, %Y Display the last content modification time in a human-readable format or as Epoch seconds.
%z, %Z Display the last status change time in a human-readable format or as Epoch seconds.
%w, %W Display the creation time in a human-readable format or as Epoch seconds; if unknown, show a hyphen or 0.
%C Display the SELinux security context in supported environments.

Check file system information

View filesystem status with -f

Using -f or --file-system displays information about the file system where the path is located, rather than the file itself.

stat -f /
stat --file-system /home

You can check the file system type, total blocks, available blocks, number of inodes, and maximum file name length.

Using file system format specifiers

In -f mode, the meaning is different from the specifiers for files. For example, %T indicates the human-readable file system type, %b represents total data blocks, and %a shows the number of blocks available to regular users.

stat -f -c 'type=%T total=%b available=%a block-size=%S' /

To compare human-readable disk usage, df -h might be more convenient, and to extract only file system fields required for automation, stat -f -c is useful.

Remote file systems and cache policies

In supported versions of GNU Coreutils, you can specify the cache usage method when retrieving remote file system attributes with --cached=MODE.

Modes Action
default Whether to use cache is left to the file system's default policy.
always Use cached attributes if possible. It may be fast, but may not be up-to-date.
never Try to synchronize with the latest attributes if possible. Remote access latency may increase.
stat --cached=never /mnt/remote/report.txt

The actual guarantee level depends on remote file systems like NFS and mounting settings. Check if the installed version supports this option with stat --help.

Shell script usage examples

Branching based on file size

path='archive.tar'
size=$(stat -c '%s' -- "$path") || exit 1

if [ "$size" -gt 104857600 ]; then
 printf '%s\n' 'The file is larger than 100 MiB.'
fi

In environments where files can change between checking and use, do not assume that metadata checked once will remain the same until subsequent operations.

Compare modification times numerically

left_mtime=$(stat -c '%Y' -- file-a)
right_mtime=$(stat -c '%Y' -- file-b)

if [ "$left_mtime" -gt "$right_mtime" ]; then
 printf '%s\n' 'file-a was modified more recently.'
fi

Relying solely on a single timestamp for backup or deployment decisions can cause problems due to clock differences, restored timestamps, or simultaneous modifications. If necessary, also use checksums or version information.

Frequently used stat commands

Command Purpose
stat file Displays all metadata of the file.
stat -L link Displays information about the target that the symbolic link points to.
stat -c '%s' file Outputs the file size in bytes.
stat -c '%a %n' file Displays the octal permissions and file name.
stat -c '%U:%G' file Displays the owner user and group.
stat -c '%i %h %n' file Displays the inode, number of hard links, and file name.
stat -c '%y' file Displays the last modification time of the content.
stat -c '%Y' file Prints the last modification time as Epoch seconds.
stat -f path Displays information about the file system containing the given path.
stat -t file Outputs in a concise, single-line format with fixed fields.

Precautions when using

ctime is not the creation time

ctime is the change time, that is, the time when the file's status information was modified. It is not an abbreviation for creation time, and the creation time can be provided in a separate Birth field.

Birth and atime are not always the expected values.

The creation time may not be supported depending on the file system, kernel, and mount method. atime may also not be updated immediately every time a file is read due to mount policies like noatime or relatime and caching.

Do not directly parse the output text.

The default output is in a human-readable format and may vary depending on the operating system, Coreutils version, and locale. For automation, select only the needed fields with -c, and consider that filenames may contain spaces or line breaks.

FAQ

How can I check only the octal permissions of a file?

Use stat -c '%a' filename. If you also need the filename, use stat -c '%a %n' filename.

What is the difference between mtime and ctime?

mtime is the time when the file content was last modified, and ctime is the time when the inode status, such as permissions, ownership, and link count, was last changed. ctime is not the file creation time.

Why is Birth shown as a hyphen?

It is because the file system or operating system in use does not provide the creation time, or stat could not obtain that value. In this case, %w outputs a hyphen, and %W outputs 0.

Is the Size of a directory the total size of all files inside it?

No. It is the storage size of the directory's own metadata. To check the total space used by files under the directory, use du -sh directory.

Related articles and official documentation

More in This Category
Linux watch Command: Run a Command Repeatedly

Linux watch Command: Run a Command Repeatedly

Learn how to use the Linux watch command to rerun a command at regular intervals and highlight changing output, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux ping Command: Test Host Reachability and Round-Trip Time

Linux ping Command: Test Host Reachability and Round-Trip Time

Learn how to test Host Reachability and Round-Trip Time with the Linux ping command, including practical examples, key options, and important precautions.

Linux ethtool Command: Inspect Network Link and Driver Settings

Linux ethtool Command: Inspect Network Link and Driver Settings

Learn how to inspect Network Link and Driver Settings with the Linux ethtool command, including practical examples, key options, and important precautions.

Linux sudo Command: Run Commands with Elevated or Another User's Privileges

Linux sudo Command: Run Commands with Elevated or Another User's Privileges

Learn how to use the Linux sudo command to run approved commands with elevated privileges or as another user, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux locate Command: Search Indexed File Paths Quickly

Linux locate Command: Search Indexed File Paths Quickly

Learn how Linux locate searches a filename database, how updatedb affects freshness, how to limit and filter matches, and when find is the better tool.

Linux split Command: Divide Large Files into Smaller Parts

Linux split Command: Divide Large Files into Smaller Parts

Learn how to divide Large Files into Smaller Parts with the Linux split command, including practical examples, key options, and important precautions.

Linux rsync Command: Synchronize Files and Directories

Linux rsync Command: Synchronize Files and Directories

Learn how to synchronize Files and Directories with the Linux rsync command, including practical examples, key options, and important precautions.

Linux last Command: Review Login and Reboot History

Linux last Command: Review Login and Reboot History

Learn how to use the Linux last command to review user login sessions, system reboots, and shutdown history, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux su Command: Switch User Accounts and Login Shells

Linux su Command: Switch User Accounts and Login Shells

Learn how to use the Linux su command to switch user accounts and start login or non-login shells, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux Tutorial / What Is Linux? Understanding the Kernel, Distributions, and Open Source

Linux Tutorial / What Is Linux? Understanding the Kernel, Distributions, and Open Source

Understand how the Linux kernel differs from a distribution, what user space and open source mean, and how to check your system's kernel and distribution versions.