touch Command in Linux: Complete Guide to Creating Files, Updating Timestamps, and Parameters

touch command in Linux and it perimeters

I used touch for years as nothing more than “make an empty file quickly,” and that alone justified keeping it in muscle memory. It wasn’t until I started dealing with build systems and backup scripts that I actually needed its real purpose — manipulating file timestamps precisely, sometimes without changing content at all. That’s the part of touch most people never fully explore, and it turns out to be genuinely important for anything involving make, incremental backups, or file-based caching. This guide covers both sides properly.

What Is the touch Command?

touch updates the access and modification timestamps of a file to the current time, and — unless told not to — creates the file as an empty, zero-byte file if it doesn’t already exist. It’s part of GNU coreutils and available on essentially every Linux system by default.

Basic Syntax

touch [OPTION]... FILE...

Creating a New File

$ touch newfile.txt
$ ls -l --time-style=full-iso newfile.txt
-rw-r--r-- 1 root root 0 2026-07-31 01:37:07.834235916 +0000 newfile.txt

The file is created empty, with both its access and modification timestamps set to the moment touch ran.

Updating Timestamps on an Existing File

If the file already exists, touch (with no other options) simply updates both its access and modification times to now, leaving its content completely untouched:

$ touch existing_file.txt

This is the behavior people forget about — touch doesn’t just create files, it “touches” (refreshes) the timestamp of anything that already exists, which is the actual origin of the command’s name.

Full Parameter Reference

OptionLong FormDescription
-aChange only the access time
-mChange only the modification time
-c--no-createDon’t create the file if it doesn’t already exist
-t STAMPUse a specific timestamp in [[CC]YY]MMDDhhmm[.ss] format
-d STRING--date=STRINGUse a human-readable date string (accepts flexible formats like "2 days ago", "next monday")
-r FILE--reference=FILEUse another file’s timestamp instead of specifying one manually
-h--no-dereferenceAffect a symlink itself rather than the file it points to
--time=WORDSpecify which time to change: atime/access/use or mtime/modify

-t: Setting an Exact Timestamp

$ touch -t 202501151230 newfile.txt
$ ls -l --time-style=full-iso newfile.txt
-rw-r--r-- 1 root root 0 2025-01-15 12:30:00.000000000 +0000 newfile.txt

$ stat newfile.txt | grep -E "Access|Modify"
Access: 2025-01-15 12:30:00.000000000 +0000
Modify: 2025-01-15 12:30:00.000000000 +0000

The format is [[CC]YY]MMDDhhmm[.ss] — century, year, month, day, hour, minute, and an optional seconds component. Notice both access and modification time were set identically here, since no -a/-m restriction was specified.

-a and -m: Targeting Only One Timestamp

Every file on Linux (technically, in most filesystems) tracks at least two separate timestamps: access time (when it was last read) and modification time (when its content was last changed). touch can target either independently:

$ touch -a -t 202601010000 newfile.txt
$ stat newfile.txt | grep -E "Access|Modify"
Access: 2026-01-01 00:00:00.000000000 +0000
Modify: 2025-01-15 12:30:00.000000000 +0000

$ touch -m -t 202602020000 newfile.txt
$ stat newfile.txt | grep -E "Access|Modify"
Access: 2026-01-01 00:00:00.000000000 +0000
Modify: 2026-02-02 00:00:00.000000000 +0000

Notice how the first touch -a command only changed the access time, leaving modification time as it was, and the second touch -m command only changed modification time, leaving the freshly-set access time untouched. This granularity is exactly what build systems rely on when deliberately manipulating dependency timestamps.

-d: Human-Readable Dates

For anything beyond a precise numeric stamp, -d accepts a much more natural syntax, parsed by GNU’s flexible date parser:

$ touch -d "2 days ago" newfile.txt
$ stat newfile.txt | grep Modify
Modify: 2026-07-29 01:37:07.873921553 +0000

Other accepted forms include "next friday", "2026-01-01 12:00:00", "1 hour ago", and ISO 8601 timestamps directly.

-r: Copying a Timestamp From Another File

$ touch -r file1.txt newfile.txt
$ stat newfile.txt | grep Modify
Modify: 2026-07-31 01:36:53.106235041 +0000
$ stat file1.txt | grep Modify
Modify: 2026-07-31 01:36:53.106235041 +0000

newfile.txt‘s modification time now exactly matches file1.txt‘s — useful for synchronizing timestamps across a set of related files, for example when restoring files from a backup and wanting to preserve relative ordering without knowing the exact original stamps ahead of time.

-c: Don’t Create Missing Files

By default, touch happily creates a file that doesn’t exist. Sometimes you specifically want the opposite — only update the timestamp if the file already exists, and silently do nothing otherwise:

$ touch -c doesnotexist.txt
$ ls doesnotexist.txt
ls: cannot access 'doesnotexist.txt': No such file or directory

No error, no file created — exactly the “update if present” semantics you’d want in a script that shouldn’t accidentally create stray files.

How touch Works Internally

Every file on a Linux filesystem carries metadata beyond its content, stored in its inode: size, ownership, permission bits, and (depending on the filesystem) up to three or four timestamps:

  • atime (access time) — last time the file’s content was read
  • mtime (modification time) — last time the file’s content was changed
  • ctime (change time) — last time the file’s metadata (permissions, ownership, or the file itself) was changed; this is not directly settable by touch and always reflects the actual moment of the operation
  • crtime/birth time (creation time) — supported by some newer filesystems like ext4 (with appropriate kernel/tooling support) and Btrfs, though not universally exposed by all standard tools

touch operates via the utimensat() system call (or its predecessors utime()/utimes() on older systems), which lets a process explicitly set a file’s atime and mtime to arbitrary values, subject to permission checks — you generally need to own the file, or be root, to change its timestamps arbitrarily. When creating a new file, touch first calls open() with the O_CREAT flag (and no truncation), producing an empty file, then applies the same timestamp-setting logic.

Note carefully: touch cannot set ctime to an arbitrary value — the kernel always stamps ctime with the real, current time whenever any metadata change occurs, including a touch-driven timestamp change itself. This is a deliberate design choice: ctime exists partly as a tamper-evidence mechanism, so software (including forensic tools) can trust that “this metadata was altered at this real moment,” even if mtime/atime have been deliberately backdated by an administrator or script.

Real-World Use Cases

1. Forcing a Rebuild in Make-Based Build Systems

$ touch src/main.c
$ make

make decides whether to rebuild a target by comparing modification timestamps between source and output files. Touching a source file with no actual content change is the standard way to force a rebuild without editing anything.

2. Creating Placeholder or Lock Files

$ touch /var/lock/myapp.lock

3. Preventing Log Rotation Tools From Treating a File as Empty/Missing

$ touch /var/log/myapp/current.log

4. Batch-Creating Files for Testing

$ for i in {1..10}; do touch "testfile_$i.txt"; done

5. Preserving or Restoring Timestamps After a File Operation

$ touch -r original_file.txt restored_file.txt

Useful after scripted content edits that would otherwise reset the modification time to “now,” if you want downstream tools (like incremental backup software) to treat the file as unchanged for scheduling purposes.

6. Marking a Point in Time for Later Comparison

$ touch /tmp/backup_marker
# ... later ...
$ find /data -newer /tmp/backup_marker -type f

This pattern — creating a marker file, then later using find -newer against it — is a lightweight, dependency-free way to track “everything changed since I last ran a backup,” without needing a database or external state file.

Shell Scripting and Automation

A backup script using the marker-file pattern from above:

#!/bin/bash
# incremental_backup.sh - back up only files changed since the last run
set -euo pipefail

MARKER="/var/backups/.last_run_marker"
SOURCE="/data"
DEST="/backups/incremental/$(date +%Y%m%d_%H%M%S)"

mkdir -p "$DEST"

if [[ -f "$MARKER" ]]; then
    find "$SOURCE" -type f -newer "$MARKER" -print0 | \
        xargs -0 -I{} cp --parents {} "$DEST"
else
    echo "No marker found, performing full backup instead."
    cp -a "$SOURCE" "$DEST"
fi

touch "$MARKER"
echo "Backup complete: $DEST"

Here touch "$MARKER" at the very end resets the reference point for the next run, giving a simple, robust incremental-backup mechanism without any external state tracking.

touch vs Related Commands

CommandPurpose
touchCreate empty files and/or set precise access/modification timestamps
statInspect a file’s full metadata, including all timestamps, without modifying anything
> file (shell redirection)Also creates an empty file, but truncates existing content if the file already exists — a key danger touch avoids
cp -p / cp --preserve=timestampsPreserves source timestamps when copying, rather than setting a fresh “now” timestamp
dateGenerates/parses date strings, often used to build values passed to touch -d
mkdirCreates directories, not files, but is often used alongside touch in setup scripts

The critical distinction from shell redirection (> file) is worth internalizing: touch existing_file.txt never touches content, while > existing_file.txt immediately and silently truncates it to zero bytes. Mixing these up on an existing, important file is a classic and painful mistake.

Troubleshooting Common Issues

Problem: touch fails with “Permission denied.” You need write permission on the containing directory to create a new file, or ownership/write permission on an existing file to update its timestamps. Check with ls -ld on the parent directory and ls -l on the target file.

Problem: Timestamps don’t seem to update on a network filesystem. Some network filesystems (older NFS configurations in particular) have timestamp granularity or caching behavior that can make updates appear delayed or rounded. Verify with stat immediately after the touch and consider whether client-side caching is involved.

Problem: touch -t rejects a date string. Remember -t requires the strict [[CC]YY]MMDDhhmm[.ss] numeric format — for anything more natural-language, use -d instead, which has a much more forgiving parser.

Problem: Build system still doesn’t rebuild after touching a source file. Confirm you’re touching the file the build system actually checks, and that its clock and the build system’s clock aren’t skewed relative to each other (unusual, but possible across networked build environments or containers with clock drift) — a modification time that’s technically in the past relative to the existing output file won’t trigger a rebuild.

Performance Optimization

touch is an extremely lightweight operation — a handful of syscalls per file, no content read or write involved beyond the initial creation of an empty file. For batch operations across large numbers of files, the overhead is dominated by process/loop iteration rather than touch itself; if you’re touching thousands of files, consider whether find ... -exec touch {} + (batched) is meaningfully faster than a shell loop spawning touch once per file — it usually is, for very large counts, since it reduces process-spawn overhead.

Security Implications

Timestamp manipulation has real security and forensic relevance. Because touch -t/-d/-r can set arbitrary access and modification times, it’s technically possible to make a maliciously modified file’s mtime appear unchanged relative to surrounding files — a known technique sometimes used to obscure tampering evidence. This is exactly why ctime cannot be arbitrarily set by touch (or any userspace tool without direct filesystem manipulation) — it always reflects the real moment metadata was changed, which forensic analysis tools rely on specifically because it resists this kind of backdating.

If you’re building any kind of integrity-monitoring or backup-verification system, don’t rely solely on mtime comparisons to detect tampering — cryptographic checksums (sha256sum) and ctime comparisons together provide much stronger guarantees than mtime alone, precisely because mtime is the one timestamp trivially manipulable by anyone with write access to the file.

Compatibility Across Distributions

touch is part of GNU coreutils and behaves identically across Ubuntu, Debian, Fedora, RHEL, Arch, and openSUSE. macOS and BSD systems ship a POSIX touch with a smaller flag set — notably, the flexible -d human-readable date parsing is a GNU extension and isn’t guaranteed to work identically (or at all) on BSD-derived touch. For portable scripts, stick to -t with the strict numeric format, or -r for reference-based timestamps, both of which are POSIX-standard and consistently supported.

Best Practices

  • Use touch (not >) whenever you want to guarantee you’re not accidentally truncating an existing file’s content.
  • Prefer -r over hand-computing timestamps when you want to synchronize one file’s timestamp to match another’s.
  • Use -c in scripts where accidentally creating a new file would be undesirable.
  • Don’t rely on mtime alone for integrity or tamper detection — pair it with checksums.
  • For build-system rebuild triggers, touch the specific dependency file that the build tool actually checks, not just any file in the project.

Summary

touch is simple on the surface — create an empty file, or refresh its timestamp — but underneath it’s a precise interface to a filesystem’s timestamp metadata, supporting exact numeric stamps, flexible natural-language dates, and reference-based synchronization from another file. It shows up constantly in build systems, backup scripts, and lock-file patterns, and understanding the atime/mtime/ctime distinction (and which ones touch can and can’t control) is genuinely useful knowledge well beyond the basic “make an empty file” use case most people start with.

References

  • GNU Coreutils Manual: touch — https://www.gnu.org/software/coreutils/manual/html_node/touch-invocation.html
  • Linux man-pages project: man 1 touch — https://man7.org/linux/man-pages/man1/touch.1.html
  • Linux man-pages project: man 2 utimensat — https://man7.org/linux/man-pages/man2/utimensat.2.html
  • Ubuntu Manpage Repository — https://manpages.ubuntu.com/manpages/noble/en/man1/touch.1.html
Total
1
Shares

Leave a Reply

Previous Post
pwd command in Linux and it perimeters

pwd Command in Linux: Complete Guide to Print Working Directory and Parameters

Next Post
find command in Linux and it perimeters

find Command in Linux: Complete Guide to File Searching, Filtering, and Parameters

Related Posts