kmail.at
contact

elsewhere

EnglishEN
← learning

linux · difficulty ◆

touch — create empty files and rewrite timestamps

Give the filesystem a poke: touch creates a file from thin air or stamps a precise time on one that already exists.

The fastest way to make 'file not found' vanish — and the tool every build system quietly weaponizes against stale timestamps.

AI-generated draft · reviewed and editedThis text was generated with AI as a first draft, then reviewed and edited by the author, who holds editorial responsibility for it.

2026-09-21 · 4 min read

$ touch

What it does

touch does two jobs. With no flags it creates a file if it doesn't exist, and if it does exist it updates that file's modification time to right now — without touching its contents. With the -a/-m/-d/-t/-r flags it becomes a precise timestamp editor: you can set only the access time, only the modification time, or pin both to an exact moment. Under the hood it's a thin wrapper around the utimensat() syscall, which is why it's instant even on enormous files — it never reads or writes the data, just the metadata.

Why it matters

Makefiles and build tools decide what to rebuild by comparing file mtimes — so a wrong timestamp means a build that silently recompiles everything or skips work it should redo. Touch is how you fix that by hand: bump a header so dependents rebuild, backdate a config to stop a daemon from reloading it. It's also the standard trick for stubbing out nonexistent files when testing scripts, and for creating a batch of empty placeholder files in a directory without a text editor in sight. A five-letter command that fixes builds and unblocks tests is worth knowing cold.

Example

$ $ touch server.pid
$ ls -l server.pid
$ stat -c '%n  size=%s  mtime=%y' server.pid
$ touch server.pid
$ ls -l server.pid
-rw-rw-r-- 1 kmail kmail 0 Sep 21 09:01 server.pid
$ stat -c '%n  size=%s  mtime=%y' server.pid
server.pid  size=0  mtime=2026-09-21 09:01:08.756841359 +0200

The headline use: a fresh, zero-byte file that didn't exist a second ago — verified live on this box. Pidfiles and lock files are born exactly like this.

$ $ echo 'port = 8080' > app.conf
$ touch app.conf
$ stat -c 'mtime=%y' app.conf
$ echo 'port = 8080' > app.conf
$ touch app.conf
$ stat -c 'mtime=%y' app.conf
mtime=2026-09-21 09:01:08.759841403 +0200

Touching an existing file updates its mtime but leaves the contents untouched — that's the whole point when you need a build tool to think a file just changed.

$ $ touch -m -d '2024-01-15 08:30:00' backup.tar
$ ls -l --time-style=full-iso backup.tar
$ touch -m -d '2024-01-15 08:30:00' backup.tar
$ ls -l --time-style=full-iso backup.tar
-rw-rw-r-- 1 kmail kmail 0 2024-01-15 08:30:00.000000000 +0100 backup.tar

-m limits the change to modification time; -d accepts human-readable dates. Handy for making an archive sort logically when your restore order depends on 'newest first'.

$ $ touch -t 202601011200.00 deploy.log
$ ls -l --time-style=full-iso deploy.log
$ touch -t 202601011200.00 deploy.log
$ ls -l --time-style=full-iso deploy.log
-rw-rw-r-- 1 kmail kmail 0 2026-01-01 12:00:00.000000000 +0100 deploy.log

-t takes the compact [[CC]YY]MMDDhhmm[.ss] form — no quotes around the value needed. Great for backdating logs out of a buggy deployment window.

$ $ touch -c not-here.file
$ echo "exit=$?"
$ touch a.log b.log c.log && ls a.log b.log c.log
$ touch -c not-here.file
exit=0
$ touch a.log b.log c.log && ls a.log b.log c.log
a.log
b.log
c.log

-c (aka --no-create) won't create files that don't exist — still exit 0, so it's safe in scripts. Multiple names? touch makes them all in one call, no loop needed.

$ $ echo hi > base.txt
$ touch -r base.txt newfile.txt
$ stat -c 'mtime=%y' base.txt newfile.txt
$ echo hi > base.txt
$ touch -r base.txt newfile.txt
$ stat -c 'mtime=%y' base.txt newfile.txt
base.txt mtime=2026-09-21 09:01:08.764841475 +0200
newfile.txt  mtime=2026-09-21 09:01:08.764841475 +0200

-r copies timestamps from a reference file. One-liner to sync a whole tree's times to a master file, verified: both now share base.txt's mtime.

Common flags

touch FILE
Create the file if absent; otherwise update mtime (and atime) to now. The zero-argument default.
-a
Update only the access time (atime), leaving mtime alone — a read-side metadata stamp.
-m
Update only the modification time (mtime) — the one build systems actually compare.
-c / --no-create
Don't create a file that doesn't exist. Still exits 0, so it's safe to use blindly in scripts.
-d "DATE"
Set both timestamps to a human-readable date, e.g. "2024-01-15 08:30:00" or "yesterday". GNU coreutils parses it.
-t [[CC]YY]MMDDhhmm[.ss]
Set timestamps from a compact numeric form, e.g. -t 202601011200.00 — no quotes required.
-r REF_FILE
Copy the timestamps from another file instead of supplying them from scratch.
-h / --no-dereference
Affect the symbolic link itself instead of the file it points at — useful only on systems that can store a symlink's timestamps. Without it, `touch link` re-stamps the target, which is the behaviour most people expect and occasionally the wrong one.

History

A relic of Unix's empty-file convention

touch is younger than the rest of the file toolbox: it is not in the First Edition manual of 1971, and it first appears in Research Unix V7 in January 1979, alongside make, awk, sed and tar. In the era before databases, an empty file doubling as a marker or a lock was a normal pattern, and touch was how you minted one. The name is literal: you poke the file's timestamps, the way you'd touch something to check it's still there, without moving its contents.

From AT&T utility to build-system linchpin

Stuart Feldman's make (1976) formalized the rule that a target needs rebuilding if any prerequisite is newer than it is — which made file timestamps the backbone of compiling for decades. touch grew from a novelty into the escape hatch that make, makefiles, and later build caches all lean on: force a rebuild, suppress one, or fix a clock skew that made make rebuild the world. GNU coreutils (still maintained today, version 9.4 on this box) kept it as near-identical to the original as a 47-year-old command gets.

Fun facts

Pros & cons

pros

  • + Creates empty placeholder files in one word — no editor, no redirects, no loops
  • + Precise timestamp control for fixing builds, tests, and archive ordering
  • + Instant even on huge files, because it never touches the data — only metadata

cons

  • − Rewrites timestamps silently with no undo or log, so mistakes are easy to make
  • − The date -t format is cryptic and easy to get wrong (that's why -d exists)
  • − Can't edit the birth time / ctime, and its metadata-only nature surprises people expecting content changes

Takeaways

  1. 1`touch file` creates an empty file; `touch existing` bumps its mtime without changing contents.
  2. 2Use `touch -d '2024-01-15 08:30:00'` for human-readable timestamps and `-t` for compact numeric input.
  3. 3`-c` suppresses creating missing files, so it's safe to call in scripts against optional paths.
  4. 4Force a rebuild of everything with `touch` on your sources, or backdate one file to stop a daemon reload.
  5. 5`-r ref` copies one file's timestamps to another — a one-liner to sync a tree's mtimes.

Related commands