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...
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
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
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
-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
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
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
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
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.txtstat -c '%i %h %n' todo.txt tasks.txt notes.txt
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' .
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"
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
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 -cformats are GNU. A script that must run on macOS too needs the BSD form (stat -f), or usefind -printf/lswith care, or detect the platform.In
-cformats,%nis the file name, not a newline. Use--printfwith\nwhen you want line breaks.ctimeis not the creation time. The creation time, where available, is theBirthline (%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' fileisstat -f '%z' fileon BSD/macOS. The format letters differ too (%zis size on BSD, change time on GNU).GNU
stat -fmeans "filesystem status"; on BSD/macOS-fintroduces a format string.
Options worth knowing
A selection, described in our own words. For the full list, see stat(1) or stat --help.
| Option | What it does |
|---|---|
-c, --format FORMAT | Print only FORMAT, with a newline, for each file. |
--printf FORMAT | Like -c but interprets backslash escapes and adds no newline. |
-L, --dereference | Follow symlinks and describe the target. |
-f, --file-system | Describe the filesystem the file is on. |
-t, --terse | Print all fields on one line, for parsing. |
--cached MODE | Control use of cached attributes on network filesystems. |
Related
lsList the contents of directories, or the details of individual files.touchUpdate a file's timestamps, creating it empty if it does not exist.fileGuess what kind of data a file holds by looking at its contents, not its name.duShow how much disk space files and directories use, totalled per directory.findWalk a directory tree and print, or act on, every file that matches a set of tests.