opscape

Files and directories

stat

Show a file's metadata (size, permissions, owner, inode, timestamps), or print chosen fields in your own format.

stat [OPTION...] FILE...

11 of 11 examples run in Debian 13.7 on 2026-10-31 · coreutils 9.7-3 · manual: stat(1)

stat prints everything the filesystem records about a file: type, size, blocks allocated, inode, link count, permissions in both octal and symbolic form, owner, group and up to four timestamps (access, modify, change, and birth where the filesystem supports it).

Its default output is for reading. For scripts, -c FORMAT (or --printf) prints just the fields you name, with no parsing of ls output needed: stat -c %s file is the size in bytes, %a the octal mode, %U the owner, %y the modification time.

The three classic timestamps are often confused. Modify (mtime) changes when the content changes. Change (ctime) changes when the content or the metadata (permissions, owner, name) changes, and cannot be set by hand. Access (atime) is when it was last read, but most systems update it lazily (relatime), so do not rely on it.

Examples

Everything about one file

stat notes.txt
explain
output
  File: notes.txt
  Size: 190       	Blocks: 1          IO Block: 512    regular file
Device: 0,602	Inode: 10039263    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     dev)   Gid: ( 1000/     dev)
Access: 2026-10-25 05:30:44.000000000 +0000
Modify: 2026-10-25 05:30:44.000000000 +0000
Change: 2026-10-31 20:21:05.980060477 +0000
 Birth: 2026-10-31 20:21:05.962060015 +0000

Size is in bytes, Blocks counts 512-byte units actually allocated, and Access: (0664/...) shows the mode in octal and symbolic form. Modify is days ago, but Change and Birth are just now: the sandbox created this copy of the file seconds before the example ran and then set its modification time back.

Print just the size in bytes

stat -c %s access.log
explain
output
2309

-c replaces the whole report with your format. %s is the size, a reliable alternative to cutting columns out of ls -l.

Several fields in one line

stat -c '%A %a %U:%G %s %n' notes.txt scripts/greet.sh
explain
output
-rw-rw-r-- 664 dev:dev 190 notes.txt
-rwxrwxr-x 775 dev:dev 37 scripts/greet.sh

%A is the symbolic mode, %a the octal mode, %U:%G owner and group names, %n the file name. The format is applied to each file in turn.

Modification time, human and epoch

stat -c '%y | %Y | %n' todo.txt
explain
output
2026-10-24 21:28:49.000000000 +0000 | 1792877329 | todo.txt

%y is the readable modification time with nanoseconds and offset; %Y is the same moment as seconds since 1970, which is easy to compare in shell arithmetic.

Why ctime changes when mtime does not

stat --printf 'mtime %y\nctime %z\n' todo.txt | cut -d. -f1
sleep 1
chmod 600 todo.txt
stat --printf 'mtime %y\nctime %z\n' todo.txt | cut -d. -f1
output
mtime 2026-10-24 21:28:49
ctime 2026-10-31 20:21:06
mtime 2026-10-24 21:28:49
ctime 2026-10-31 20:21:07

--printf understands \n, unlike -c, where %n would mean the file name. The fixture's mtime is days old, while ctime is the moment the sandbox copied the file into place. After the permission change, mtime is untouched but ctime moved again: ctime records metadata changes too.

What kind of file is this

stat -c '%-14F %n' notes.txt data link-to-notes /dev/null
explain
output
regular file   notes.txt
directory      data
symbolic link  link-to-notes
character special file /dev/null

%F describes the file type in words. %-14F pads it to at least 14 characters, left-aligned, so the names line up; the longer character special file simply pushes its name further right.

Stat a symlink or what it points to

stat -c '%F %s' link-to-notes
stat -L -c '%F %s' link-to-notes
output
symbolic link 9
regular file 190

Without -L, stat describes the link itself (9 bytes: the length of notes.txt). With -L, it follows the link and reports the target file.

Find out whether two names are the same file

Setup run before this example
ln todo.txt tasks.txt
stat -c '%i %h %n' todo.txt tasks.txt notes.txt
explain
output
9814398 2 todo.txt
9814398 2 tasks.txt
9814374 1 notes.txt

%i is the inode number and %h the hard link count. todo.txt and tasks.txt share an inode and have 2 links: they are hard links to one file.

Information about the filesystem instead

stat -f -c 'type=%T block size=%S' .
explain
output
type=overlayfs block size=131072

-f reports on the filesystem that holds the file. %T is its type in words; this sandbox runs in a container, whose root is an overlay filesystem. %S is the fundamental block size the filesystem uses for its block counts.

How many seconds ago a file changed

echo "$(( $(date +%s) - $(stat -c %Y logs/app.log) )) seconds since app.log changed"
explain
output
407441 seconds since app.log changed

%Y gives the mtime as an epoch number and date +%s gives now, so shell arithmetic produces the age. The number varies with when the page was built.

A file that does not exist

stat nosuch.txt
explain
outputexit 1
stat: cannot statx 'nosuch.txt': No such file or directory

stat reports the error and exits with 1, which makes it usable as an existence check, though [ -e file ] is simpler.

Common pitfalls

  • stat -c formats are GNU. A script that must run on macOS too needs the BSD form (stat -f), or use find -printf/ls with care, or detect the platform.

  • In -c formats, %n is the file name, not a newline. Use --printf with \n when you want line breaks.

  • ctime is not the creation time. The creation time, where available, is the Birth line (%w/%W).

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • The biggest difference on this page: GNU stat -c '%s' file is stat -f '%z' file on BSD/macOS. The format letters differ too (%z is size on BSD, change time on GNU).

  • GNU stat -f means "filesystem status"; on BSD/macOS -f introduces a format string.

Options worth knowing

A selection, described in our own words. For the full list, see stat(1) or stat --help.

OptionWhat it does
-c, --format FORMATPrint only FORMAT, with a newline, for each file.
--printf FORMATLike -c but interprets backslash escapes and adds no newline.
-L, --dereferenceFollow symlinks and describe the target.
-f, --file-systemDescribe the filesystem the file is on.
-t, --tersePrint all fields on one line, for parsing.
--cached MODEControl use of cached attributes on network filesystems.

Related