The touch
is one of the most basic Linux commands for empty file creation and for changing the file metadata timestamps. You normally don’t need to install it specifically because it comes with the Linux system.
The touch syntax command
The command syntax is:
touch [OPTION]… FILE…
The options available for the command are:
-a : For changing the access timestamp of the file
–c : Don’t create the file if it doesn’t exist
-d : Set specific timestamp with date string
-m : For changing only the modify timestamp
-h : Change the symbolic link file timestamp only instead of the referenced file
-r : Use the timestamp of another file
-t : Use timestamp format [[CC]YY]MMDDhhmm[.ss]
As many other Linux commands, all the options above can be combined in order to get the specific desired results.
In the following sections, we will use some of the touch
command options to show how do they work.
Using touch without options
The usage of the command is easy and you can run it without options to create a void file in a target path if it doesn’t exist:
$ touch test
$ ls -l
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 11:51 test
The default behaviour is to create a file if it doesn’t exists however, you may use the “-c” option with the touch
command just to modify the metadata of a target file but avoid creating the file if it doesn’t exists:
$ ls -l
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 11:51 test
$ touch -c test2
$ ls -l
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 11:51 test
As you may notice, the execution of touch command with “-c” avoided the creation of file “test2”
Changing access and modify dates in files or folders
Before explaining this use case, let’s speak about the command stat
which is useful to get the metadata information of a file.
$ ls -l
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 11:51 test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 11:51:43.324716963 +0200
Modify: 2022-06-04 11:51:43.324716963 +0200
Change: 2022-06-04 11:51:43.324716963 +0200
Birth: -
In the above block, you may see the “Modify” and the “Access” dates on the last lines of the command output. To modify only the “Access” date the “-a” option is used:
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 11:51:43.324716963 +0200
Modify: 2022-06-04 11:51:43.324716963 +0200
Change: 2022-06-04 11:51:43.324716963 +0200
Birth: -
$ touch -a test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:12:10.434278078 +0200
Modify: 2022-06-04 11:51:43.324716963 +0200
Change: 2022-06-04 12:12:10.434278078 +0200
Birth: -
On the other hand, if you just want to change the “Modify” date, then the “-m” option is used:
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:12:10.434278078 +0200
Modify: 2022-06-04 11:51:43.324716963 +0200
Change: 2022-06-04 12:12:10.434278078 +0200
Birth: -
$ touch -m test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:12:10.434278078 +0200
Modify: 2022-06-04 12:15:47.783780249 +0200
Change: 2022-06-04 12:15:47.783780249 +0200
Birth: -
[fse@fse ~]$
If you run the touch command without options, then the command will change both “Access” and “Modify” dates:
$ date
Sat Jun 4 12:19:17 CEST 2022
$ ls -l
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 12:15 test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:12:10.434278078 +0200
Modify: 2022-06-04 12:15:47.783780249 +0200
Change: 2022-06-04 12:15:47.783780249 +0200
Birth: -
$ touch test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:19:33.904423756 +0200
Modify: 2022-06-04 12:19:33.904423756 +0200
Change: 2022-06-04 12:19:33.904423756 +0200
Birth: -
How about the folders? Well, they cannot be created with touch
, nevertheless, it’s metadata can be modified anyway:
$ date
Sat Jun 4 13:07:54 CEST 2022
[fse@fse ~]$ ls -l
total 0
drwxrwxr-x. 2 fse fse 6 Feb 27 2011 files
$ stat files
File: ‘files’
Size: 6 Blocks: 0 IO Block: 4096 directory
Device: fd00h/64768d Inode: 356130 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 13:04:20.405194702 +0200
Modify: 2011-02-27 15:15:33.000000000 +0100
Change: 2022-06-04 13:04:35.094432650 +0200
Birth: -
$ touch files
$ ls -l
total 0
drwxrwxr-x. 2 fse fse 6 Jun 4 13:08 files
$ stat files
File: ‘files’
Size: 6 Blocks: 0 IO Block: 4096 directory
Device: fd00h/64768d Inode: 356130 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 13:08:07.708876753 +0200
Modify: 2022-06-04 13:08:07.708876753 +0200
Change: 2022-06-04 13:08:07.708876753 +0200
Birth: -
As you may appreciate, the touch command by default will set access and modify dates with the current date but, what if you want to place a specific date? This will be explained in the next section.
Setting a specific access or modify date in a file
Until now, we have explored how to change the timestamp dates with the current date but, one of the interesting usages of touch is to change those metadata timestamps to a custom date. In order to do that, the options “-d”, “-t” or “-r” are used depending of what date format you want to pass.
In the following example, the touch
command will change the access date only to a specific custom date using a date string (-d option):
$ date
Sat Jun 4 12:26:58 CEST 2022
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:19:33.904423756 +0200
Modify: 2022-06-04 12:19:33.904423756 +0200
Change: 2022-06-04 12:19:33.904423756 +0200
Birth: -
$ touch -a -d "2015-01-27 11:27:27.000000000" test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2015-01-27 10:27:27.000000000 +0100
Modify: 2022-06-04 12:19:33.904423756 +0200
Change: 2022-06-04 12:29:10.845802781 +0200
Birth: -
The same can be done with the modify timestamp but, in this example, we’ll use the “-t” option:
$ date
Sat Jun 4 12:34:18 CEST 2022
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2015-01-27 11:27:27.000000000 +0100
Modify: 2022-06-04 12:19:33.904423756 +0200
Change: 2022-06-04 12:29:32.678159145 +0200
Birth: -
$ touch -m -t 201102271515.33 test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2015-01-27 11:27:27.000000000 +0100
Modify: 2011-02-27 15:15:33.000000000 +0100
Change: 2022-06-04 12:36:12.207680457 +0200
Birth: -
$ ls -l
total 0
-rw-rw-r--. 1 fse fse 0 Feb 27 2011 test
An alternate to get a specific date is to get it from another file by using the option “-r”. So, in the next block both access and modify timestamps will be override with the same values as the other file:
$ date
Sat Jun 4 12:42:19 CEST 2022
$ stat /etc/hosts
File: ‘/etc/hosts’
Size: 208 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 33554825 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:net_conf_t:s0
Access: 2022-06-04 10:37:50.880289006 +0200
Modify: 2022-06-04 10:37:48.794362409 +0200
Change: 2022-06-04 10:37:48.794362409 +0200
Birth: -
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2015-01-27 11:27:27.000000000 +0100
Modify: 2011-02-27 15:15:33.000000000 +0100
Change: 2022-06-04 12:36:12.207680457 +0200
Birth: -
$ touch -r /etc/hosts test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 10:37:50.880289006 +0200
Modify: 2022-06-04 10:37:48.794362409 +0200
Change: 2022-06-04 12:43:30.705840088 +0200
Birth: -
$ ls -l
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 10:37 test
As a curiosity, in all these examples you may notice that the “Change” date updates whenever the metadata has been modified with the current date value.
Update the timestamp of a symlink only
Let’s experiment with the option “-h” of the touch
command in order to modify the metadata of the symlink or softlink without affecting the referenced file:
$ date
Sat Jun 4 12:55:05 CEST 2022
$ ln -s test link
$ ls -l
total 0
lrwxrwxrwx. 1 fse fse 4 Jun 4 12:55 link -> test
-rw-rw-r--. 1 fse fse 0 Jun 4 10:37 test
$ stat link
File: ‘link’ -> ‘test’
Size: 4 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 101141037 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:55:11.021278214 +0200
Modify: 2022-06-04 12:55:09.155247740 +0200
Change: 2022-06-04 12:55:09.155247740 +0200
Birth: -
$ touch -h link
$ stat link
File: ‘link’ -> ‘test’
Size: 4 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 101141037 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:55:39.594744859 +0200
Modify: 2022-06-04 12:55:39.594744859 +0200
Change: 2022-06-04 12:55:39.594744859 +0200
Birth: -
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 10:37:50.880289006 +0200
Modify: 2022-06-04 10:37:48.794362409 +0200
Change: 2022-06-04 12:43:30.705840088 +0200
Birth: -
Otherwise, if “-h” option is not used then touch command will modify the referenced file and not the symlink:
$ date
Sat Jun 4 12:57:58 CEST 2022
$ stat link
File: ‘link’ -> ‘test’
Size: 4 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 101141037 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:55:45.951848692 +0200
Modify: 2022-06-04 12:55:39.594744859 +0200
Change: 2022-06-04 12:55:39.594744859 +0200
Birth: -
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 10:37:50.880289006 +0200
Modify: 2022-06-04 10:37:48.794362409 +0200
Change: 2022-06-04 12:43:30.705840088 +0200
Birth: -
$ touch link
$ ls -l
total 0
lrwxrwxrwx. 1 fse fse 4 Jun 4 12:55 link -> test
-rw-rw-r--. 1 fse fse 0 Jun 4 12:58 test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 101141036 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:58:25.412444237 +0200
Modify: 2022-06-04 12:58:25.412444237 +0200
Change: 2022-06-04 12:58:25.412444237 +0200
Birth: -
$ stat link
File: ‘link’ -> ‘test’
Size: 4 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 101141037 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1001/ fse) Gid: ( 1001/ fse)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-06-04 12:55:45.951848692 +0200
Modify: 2022-06-04 12:55:39.594744859 +0200
Change: 2022-06-04 12:55:39.594744859 +0200
Birth: -
Targeting multiple files with touch command
The touch
command accepts a basic file parametrisation in order to target multiple files. You can create multiple files with a list of file names:
$ touch a b c d
$ ls -tlr
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 13:17 a
-rw-rw-r--. 1 fse fse 0 Jun 4 13:17 d
-rw-rw-r--. 1 fse fse 0 Jun 4 13:17 c
-rw-rw-r--. 1 fse fse 0 Jun 4 13:17 b
Or with a fixed prefix and a variable part of the file name by using the brackets “{}”:
$ touch hello_world_{a..d}
$ touch hello_world_{1..5}
$ ls -l
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_1
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_2
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_3
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_4
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_5
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_a
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_b
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_c
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_d
But if you want to modify the metadata of the files in a target path then, bash options should be used. In the following example it will show how to modify the timestamp of all the files in a folder aided with the find
command:
$ date
Sat Jun 4 13:29:00 CEST 2022
$ ls -lR files_num
files_num/:
total 0
drwxrwxr-x. 2 fse fse 90 Jun 4 13:27 files_char
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_1
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_2
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_3
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_4
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_5
files_num/files_char:
total 0
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_a
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_b
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_c
-rw-rw-r--. 1 fse fse 0 Jun 4 13:21 hello_world_d
$ touch -d "2012-12-12 12:12:12.000000000" $(find files_num)
$ ls -lR files_num
files_num/:
total 0
drwxrwxr-x. 2 fse fse 90 Dec 12 2012 files_char
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_1
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_2
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_3
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_4
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_5
files_num/files_char:
total 0
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_a
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_b
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_c
-rw-rw-r--. 1 fse fse 0 Dec 12 2012 hello_world_d
An idea for touch command usage
You may wonder in which situation would be the touch
command be useful but, let’s say that you have a batch script that runs in a scheduled manner that processes files in a target path that were modified after a certain date. However, for any reason some files didn’t process when they should be, and the batch script reference date has been changed to a later one. You can then, leverage touch
to set a later date on those pending files so in the next batch script execution, they will be considered again.