bitlvl
EN

ls -l and stat explainer

Paste one or more lines from ls -l, or the output of stat file. Each column is named and decoded, including the markers most people ignore.

Reading ls -l

-rwxr-xr-x. 1 root root 4096 Oct 18 12:00 script.sh
│└┬┘└┬┘└┬┘│ │  │    │    │    └────┬────┘ └───┬───┘
│ │  │  │ │ │  │    │    │         │          └ name (and -> target for symlinks)
│ │  │  │ │ │  │    │    │         └ modification time (year shown if older than 6 months)
│ │  │  │ │ │  │    │    └ size in bytes (or major, minor for devices)
│ │  │  │ │ │  │    └ group
│ │  │  │ │ │  └ owner
│ │  │  │ │ └ hard link count
│ │  │  │ └ . = SELinux context, + = ACL, @ = extended attributes (macOS)
│ │  │  └ others: r-x
│ │  └ group: r-x
│ └ owner: rwx
└ type: - file, d directory, l symlink, c char device, b block device, p pipe, s socket

Things that confuse people

  • Link count: how many directory entries point at the inode. For a directory it is 2 plus the number of subdirectories, because each subdirectory's .. counts. A file with count 3 has two other hard links somewhere.
  • Size of a directory: the size of its entry list (4096 on ext4), not the total of its contents. Use du -sh for that.
  • s, S, t, T in the permission string are the setuid, setgid and sticky bits; lower case means the underlying execute bit is also set, upper case means it is not (usually a mistake).
  • Symlink permissions are always lrwxrwxrwx and ignored; what matters is the target's.
  • Times: ls shows mtime (content changed). stat also shows atime (last read, often disabled by noatime), ctime (inode changed: chmod, chown, rename) and birth time on filesystems that keep it.

stat

stat file prints everything the inode holds: the mode in octal and symbolic form, uid/gid with names, inode number, device, block count (in 512-byte units, so a sparse file shows fewer blocks than its size would need), and the four timestamps. stat -c '%a %U %G %n' * prints just what you ask for; stat -f describes the filesystem instead.

Questions

What does the dot at the end of permissions mean?

An SELinux security context is set on the file (seen on Fedora, RHEL, CentOS). ls -Z shows it. A + instead means an access control list is present; getfacl shows it.

Why does a directory have link count 2?

Its own entry in the parent plus its “.” entry. Each subdirectory adds one more through its “..”. So a directory with link count 7 has five subdirectories.

What is the difference between mtime and ctime?

mtime changes when the content changes; ctime changes when the inode changes (content, permissions, owner, link count). You cannot set ctime with touch, which makes it useful for forensics.

How do I see hidden files and sizes in human units?

ls -lah: -a shows dotfiles, -h prints sizes as K, M, G. Add -t to sort by time and -r to reverse.