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.
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.
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 two-letter command that fixes builds and unblocks tests is worth knowing cold.
$ 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.
| Flag | Meaning |
|---|---|
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. |
touch has been in Unix since the very early Bell Labs days — it's in Research Unix V7 (1979) as one of the core file utilities. 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.
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 45-year-old command gets.