Set File Timestamps with touch Without Creating Surprises
By the end of this guide, you will be able to update a file's timestamps, set a reproducible date, copy timestamps from another file, and check the result with stat. The examples use GNU coreutils 9.4, installed here as /usr/bin/touch.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell and permission to modify the files you name. The work takes about five minutes. No command below needs elevated privileges when you use files you own. Use sudo only when the target is deliberately in a protected location, and check the path before doing so.
1. Make a safe test file
Choose a scratch directory, then create a file with an explicit name. A missing file is created as an empty file by default, which is useful for placeholders but an easy mistake to make when a path is misspelt.
mkdir -p "$HOME/touch-demo"
cd "$HOME/touch-demo"
touch example.txt
stat -c 'path=%n size=%s access=%x modify=%y' example.txt
Expected output is one line whose path is example.txt, whose size is 0, and whose access and modify times are close to now. stat formats the timestamps for you; the exact values depend on the clock and filesystem.
If example.txt already exists, touch changes its timestamps and leaves its contents alone. If that is not what you want, use -c before naming the file.
Checkpoint: prevent accidental creation
Use --no-create when checking or refreshing a path that must already exist.
touch --no-create example.txt
touch --no-create missing.txt
test ! -e missing.txt && echo 'missing.txt was not created'
The second command does nothing because missing.txt is absent. This is a good default for scripts that should not turn a typo into a new empty file. A failed or unchanged command normally produces no output, so the explicit test is the verification here.
2. Set both timestamps to a known date
Pass a human-readable date to --date. This changes both the access and modification times unless you also select one with -a or -m.
touch --date='2020-01-02 03:04:05' example.txt
stat -c 'access=%x modify=%y' example.txt
Both displayed values should begin with 2020-01-02 03:04:05, subject to the timestamp precision shown by the filesystem. The date string is interpreted in the local time zone unless it includes a zone such as UTC.
--date accepts a flexible date language, including relative expressions. That flexibility is convenient interactively but can make scripts ambiguous. Use a complete, fixed date and time when another process needs a reproducible result.
3. Change only one timestamp
Use -m for the modification time or -a for the access time. The other timestamp is left alone.
touch -m --date='2021-02-03 04:05:06' example.txt
stat -c 'after modify-only: access=%x modify=%y' example.txt
touch -a --date='2022-03-04 05:06:07' example.txt
stat -c 'after access-only: access=%x modify=%y' example.txt
After the first command, the modification time should show the 2021 value while access remains from the earlier step. After the second, access should show the 2022 value while modification remains at 2021. Filesystems can record timestamps with different precision, so compare the displayed values rather than expecting nanoseconds everywhere.
Checkpoint: copy timestamps from a reference file
When the desired time already exists on another file, --reference avoids retyping it.
touch --date='2023-04-05 06:07:08' reference.txt
touch --reference=reference.txt example.txt
stat -c '%n modify=%y' reference.txt example.txt
The two modification times should match. The reference file is read; its contents are not copied. By default, both access and modification times are taken from the reference. If you need only one, combine the option with -a or -m.
4. Use the compact numeric format when required
The -t option takes [[CC]YY]MMDDhhmm[.ss]. For example, this sets 2 January 2024 at 03:04:05.
touch -t 202401020304.05 numeric.txt
stat -c 'modify=%y' numeric.txt
--date and -t deliberately accept different formats. Do not mix an ISO-looking string into -t, and do not assume that a short numeric value means the same thing in every context.
Common traps and boundaries
- Creating a file by mistake: the default creates a missing path. Use
-cor--no-createwhen creation is not part of the job. - Changing content:
touchdoes not write file data. It does change metadata, so tools that watch modification times may react. - Permissions: you generally need write access to the file or its containing directory, depending on the operation and filesystem. A permission error is not fixed safely by adding
sudowithout checking the path. - Symbolic links: without
-h,touchfollows a link and affects its referenced file.-hrequests changing the link itself, but this is useful only on systems that can change symlink timestamps. - Standard output as a file name: a file argument of
-is special to GNUtouch; it refers to the file associated with standard output. Avoid it unless that behaviour is intentional.
Recovery and undo
Timestamp changes do not have a universal undo operation. If you know the previous time, set it again with --date or copy it from a trustworthy reference using --reference. If you only want the normal current timestamps, run touch again, but remember that this changes both access and modification times unless you select one.
# Restore a known value; replace the placeholder with the real timestamp.
touch --date='YYYY-MM-DD HH:MM:SS' example.txt
stat -c 'path=%n access=%x modify=%y' example.txt
Do not use a made-up recovery date when timestamps are evidence for an audit, build, backup or synchronisation process. Find the original value in the relevant log, reference file or backup metadata first.
Done means
- You know whether the target may be created, and used
--no-createwhen it may not. - You selected both timestamps, access only, modification only, a reference file, or a fixed date deliberately.
- You checked the result with
statand accounted for filesystem precision. - You avoided
sudounless the protected target and path were confirmed.