ZetCode

Linux touch Command

last modified October 23, 2026

The touch command updates the access and modification timestamps of files, and creates the files that do not exist. It is best known as the quickest way to create an empty file, but setting timestamps to a specific date is just as useful: for testing, for build tools such as make, and for finding files changed after a certain moment.

The syntax is touch [options] file.... The examples use GNU touch from coreutils 9.1, with the time zone set to Central European Time.

Creating empty files

When a file does not exist, touch creates it with a size of zero bytes.

touch notes.txt
ls -l notes.txt
touch report.txt todo.txt
touch day{1..3}.log
ls

touch accepts any number of files. The brace expansion day{1..3}.log is performed by the shell, which passes three file names to touch. New files get the permissions given by the umask, usually rw-r--r--.

$ touch notes.txt
$ ls -l notes.txt
-rw-r--r-- 1 jano jano 0 Oct 23 19:48 notes.txt
$ touch report.txt todo.txt
$ touch day{1..3}.log
$ ls
day1.log
day2.log
day3.log
hello.c
Makefile
notes.txt
report.txt
todo.txt

File timestamps

Every file has several timestamps, which the stat command shows.

stat notes.txt

Access (atime) is the last time the content was read, Modify (mtime) the last time the content was changed, and Change (ctime) the last time the content or metadata, such as permissions or owner, was changed. Birth is the creation time, available on newer file systems. ls -l shows the modification time. touch sets atime and mtime; ctime and the birth time cannot be set directly. Note that many systems mount file systems with relatime, so the access time is not updated on every read.

$ stat notes.txt
  File: notes.txt
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: 0,65	Inode: 2658334     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    jano)   Gid: ( 1000/    jano)
Access: 2026-10-23 19:48:32.970578519 +0200
Modify: 2026-10-23 19:48:32.970578519 +0200
Change: 2026-10-23 19:48:32.970578519 +0200
 Birth: 2026-10-23 19:48:32.970578519 +0200

Updating the timestamp of an existing file

For an existing file, touch sets the access and modification times to the current time and leaves the content alone.

ls -l agenda.txt
touch agenda.txt
ls -l agenda.txt
cat agenda.txt

The modification time moves from October 20 to now, and the content is unchanged. This is the original purpose of touch: to make a file look recently modified, for example to force make to rebuild something.

$ ls -l agenda.txt
-rw-r--r-- 1 jano jano 14 Oct 20 14:00 agenda.txt
$ touch agenda.txt
$ ls -l agenda.txt
-rw-r--r-- 1 jano jano 14 Oct 23 19:48 agenda.txt
$ cat agenda.txt
meeting at 10

Setting a specific date

The -d option sets the timestamps to a given date instead of the current time. It accepts the same free-form date strings as the date command.

touch -d "2026-01-15 08:30" report.txt
touch -d "yesterday 18:00" todo.txt
touch -d "3 hours ago" day1.log
touch -d @1767225600 day2.log
ls -l --time-style=long-iso report.txt todo.txt day1.log day2.log

Absolute dates, relative expressions such as yesterday and 3 hours ago, and Unix timestamps prefixed with @ are accepted. The Unix timestamp 1767225600 is midnight on January 1, 2026 in UTC, which is 01:00 in our time zone. The --time-style option of ls shows full dates for all files.

$ touch -d "2026-01-15 08:30" report.txt
$ touch -d "yesterday 18:00" todo.txt
$ touch -d "3 hours ago" day1.log
$ touch -d @1767225600 day2.log
$ ls -l --time-style=long-iso report.txt todo.txt day1.log day2.log
-rw-r--r-- 1 jano jano 0 2026-10-23 16:48 day1.log
-rw-r--r-- 1 jano jano 0 2026-01-01 01:00 day2.log
-rw-r--r-- 1 jano jano 0 2026-01-15 08:30 report.txt
-rw-r--r-- 1 jano jano 0 2026-10-22 18:00 todo.txt

The -t option

The -t option takes a timestamp in the fixed POSIX format [[CC]YY]MMDDhhmm[.ss].

touch -t 202512312359.59 day3.log
touch -t 01020304 notes.txt
stat -c '%y %n' day3.log notes.txt

The first command sets 23:59:59 on December 31, 2025. In the second, the year is omitted, so the current year is used: January 2, 03:04. The -t format is portable to other Unix systems; POSIX -d accepts only ISO dates such as 2026-01-15T08:30:00, and the free-form strings are a GNU extension. The %y format of stat prints the modification time and %n the file name.

$ touch -t 202512312359.59 day3.log
$ touch -t 01020304 notes.txt
$ stat -c '%y %n' day3.log notes.txt
2025-12-31 23:59:59.000000000 +0100 day3.log
2026-01-02 03:04:00.000000000 +0100 notes.txt

Access and modification time separately

The -a option changes only the access time, and -m only the modification time.

touch -a -d '2026-10-22 09:00' data.csv
stat --printf 'access: %x\nmodify: %y\n' data.csv
touch -m -d '2026-10-21 17:30' data.csv
stat --printf 'access: %x\nmodify: %y\n' data.csv

Each command leaves the other timestamp as it was. The --printf option of stat interprets escape sequences such as \n, unlike -c.

$ touch -a -d '2026-10-22 09:00' data.csv
$ stat --printf 'access: %x\nmodify: %y\n' data.csv
access: 2026-10-22 09:00:00.000000000 +0200
modify: 2026-10-01 12:00:00.000000000 +0200
$ touch -m -d '2026-10-21 17:30' data.csv
$ stat --printf 'access: %x\nmodify: %y\n' data.csv
access: 2026-10-22 09:00:00.000000000 +0200
modify: 2026-10-21 17:30:00.000000000 +0200

The change time

No option of touch sets the change time. Every change of timestamps is itself a metadata change.

date '+now:    %Y-%m-%d %H:%M:%S'
stat --printf 'modify: %y\nchange: %z\n' data.csv

The modification time is the past date we set, but the change time is the moment when we ran touch. This is why the ctime is useful in forensics and backups: a file whose mtime was set back can still be recognized as recently touched.

$ date '+now:    %Y-%m-%d %H:%M:%S'
now:    2026-10-23 19:48:32
$ stat --printf 'modify: %y\nchange: %z\n' data.csv
modify: 2026-10-21 17:30:00.000000000 +0200
change: 2026-10-23 19:48:32.994579078 +0200

Copying timestamps from another file

The -r option takes the timestamps from a reference file.

touch -r report.txt copy.txt
touch -r report.txt -d '+1 day' next.txt
stat -c '%y %n' report.txt copy.txt next.txt

copy.txt gets exactly the times of report.txt. Combined with -d, a relative date is applied to the reference time, so next.txt is one day newer. This is useful to restore timestamps after editing a file with a tool that does not preserve them.

$ touch -r report.txt copy.txt
$ touch -r report.txt -d '+1 day' next.txt
$ stat -c '%y %n' report.txt copy.txt next.txt
2026-01-15 08:30:00.000000000 +0100 report.txt
2026-01-15 08:30:00.000000000 +0100 copy.txt
2026-01-16 08:30:00.000000000 +0100 next.txt

Not creating files

The -c option (no-create) updates existing files but does not create missing ones.

touch -c missing.txt; echo "exit: $?"
ls missing.txt

The missing file is silently skipped, and the exit status is still 0. The option is used when a script refreshes the timestamps of files that may or may not exist, for example touch -c *.cache.

$ touch -c missing.txt; echo "exit: $?"
exit: 0
$ ls missing.txt
ls: cannot access 'missing.txt': No such file or directory

Symbolic links

By default, touch follows symbolic links and changes the target. The -h option changes the link itself.

ln -s report.txt latest
touch -d '2026-05-01' latest
touch -h -d '2020-01-01' latest
ls -l --time-style=long-iso report.txt latest

The first touch sets the date of report.txt through the link. With -h, only the link's own timestamp changes. Note that touch on a broken link would create the missing target file; with -h, it does not.

$ ln -s report.txt latest
$ touch -d '2026-05-01' latest
$ touch -h -d '2020-01-01' latest
$ ls -l --time-style=long-iso report.txt latest
lrwxrwxrwx 1 jano jano 10 2020-01-01 00:00 latest -> report.txt
-rw-r--r-- 1 jano jano  0 2026-05-01 00:00 report.txt

touch does not truncate

Another common way to create an empty file is a redirection. Unlike touch, it empties an existing file.

touch agenda.txt; cat agenda.txt
> agenda.txt; cat agenda.txt; ls -l agenda.txt

After touch, the content is still there. The redirection > agenda.txt (or : > agenda.txt) truncates the file to zero bytes. Use touch when an existing file must be kept, and the redirection when it should be emptied, for example a log file.

$ touch agenda.txt; cat agenda.txt
meeting at 10
$ > agenda.txt; cat agenda.txt; ls -l agenda.txt
-rw-r--r-- 1 jano jano 0 Oct 23 19:48 agenda.txt

Permissions

Setting the current time requires write permission; setting an arbitrary time requires owning the file.

ls -l shared.txt owned.txt
touch shared.txt; echo "exit: $?"
touch -d yesterday shared.txt
touch owned.txt
touch /etc/myapp.conf

Both files belong to root. The world-writable shared.txt can be touched, because anyone who can write to a file could change its mtime by writing anyway. Setting it to yesterday, however, is only allowed to the owner (and root). We cannot touch owned.txt at all, and we cannot create files in /etc, because creating a file requires write permission on the directory.

$ ls -l shared.txt owned.txt
-rw-r--r-- 1 root root 0 Oct 23 19:48 owned.txt
-rw-rw-rw- 1 root root 0 Oct 23 19:48 shared.txt
$ touch shared.txt; echo "exit: $?"
exit: 0
$ touch -d yesterday shared.txt
touch: setting times of 'shared.txt': Operation not permitted
$ touch owned.txt
touch: cannot touch 'owned.txt': Permission denied
$ touch /etc/myapp.conf
touch: cannot touch '/etc/myapp.conf': Permission denied

Timestamp markers with find

A file with a known timestamp serves as a marker for finding files changed after a point in time.

ls -l --time-style=long-iso build/app src
find src -type f -newer build/app
touch -d '2026-10-22 09:00' stamp
find src -type f -newer stamp -printf '%p changed after the stamp\n'

find -newer selects files modified more recently than the given file. The first search finds the source files changed after the last build. For the second, we create a marker with touch -d. In scripts, touch stamp at the end of a run lets the next run process only files changed since then.

$ ls -l --time-style=long-iso build/app src
-rw-r--r-- 1 jano jano    0 2026-10-23 08:00 build/app

src:
total 0
-rw-r--r-- 1 jano jano 0 2026-10-23 09:30 main.c
-rw-r--r-- 1 jano jano 0 2026-10-22 10:00 util.c
$ find src -type f -newer build/app
src/main.c
$ touch -d '2026-10-22 09:00' stamp
$ find src -type f -newer stamp -printf '%p changed after the stamp\n'
src/util.c changed after the stamp
src/main.c changed after the stamp

touch and make

make rebuilds a target when one of its prerequisites is newer. touch forces a rebuild without changing the source.

cat Makefile
make
make
touch hello.c
make

The first make compiles the program; the second has nothing to do, because the executable is newer than the source. After touch hello.c, the source looks modified, and make compiles it again. Conversely, touch hello would make the target look up to date.

$ cat Makefile
hello: hello.c
	cc -o hello hello.c
$ make
cc -o hello hello.c
$ make
make: 'hello' is up to date.
$ touch hello.c
$ make
cc -o hello hello.c

Best practices for touch

Source

GNU touch manual

In this article, we have used the touch command to create files, update and set access and modification times, copy timestamps from other files, handle symbolic links, and work with find and make. See also the date and find articles.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.