< Previous | Contents | Next >
A Return To The Playground
It’s time to put find to some (almost) practical use. We’ll create a playground and try out some of what we have learned.
First, let’s create a playground with lots of subdirectories and files:
[me@linuxbox ~]$ mkdir -p playground/dir-{001..100}
[me@linuxbox ~]$ touch playground/dir-{001..100}/file-{A..Z}
[me@linuxbox ~]$ mkdir -p playground/dir-{001..100}
[me@linuxbox ~]$ touch playground/dir-{001..100}/file-{A..Z}
Marvel in the power of the command line! With these two lines, we created a playground directory containing 100 subdirectories each containing 26 empty files. Try that with the GUI!
The method we employed to accomplish this magic involved a familiar command (mkdir), an exotic shell expansion (braces) and a new command, touch. By combining mkdir with the -p option (which causes mkdir to create the parent directories of the specified paths) with brace expansion, we were able to create 100 subdirectories.
The touch command is usually used to set or update the access, change, and modify times of files. However, if a filename argument is that of a nonexistent file, an empty file is created.
In our playground, we created 100 instances of a file named file-A. Let’s find them:
[me@linuxbox ~]$ find playground -type f -name 'file-A'
[me@linuxbox ~]$ find playground -type f -name 'file-A'
Note that unlike ls, find does not produce results in sorted order. Its order is deter- mined by the layout of the storage device. We can confirm that we actually have 100 in- stances of the file this way:
[me@linuxbox ~]$ find playground -type f -name 'file-A' | wc -l
100
[me@linuxbox ~]$ find playground -type f -name 'file-A' | wc -l
100
Next, let’s look at finding files based on their modification times. This will be helpful when creating backups or organizing files in chronological order. To do this, we will first create a reference file against which we will compare modification time:
[me@linuxbox ~]$ touch playground/timestamp
[me@linuxbox ~]$ touch playground/timestamp
This creates an empty file named timestamp and sets its modification time to the cur- rent time. We can verify this by using another handy command, stat, which is a kind of souped-up version of ls. The stat command reveals all that the system understands
about a file and its attributes:
[me@linuxbox ~]$ stat playground/timestamp
File: `playground/timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me) Access: 2016-10-08 15:15:39.000000000 -0400
Modify: 2016-10-08 15:15:39.000000000 -0400
Change: 2016-10-08 15:15:39.000000000 -0400
[me@linuxbox ~]$ stat playground/timestamp
File: `playground/timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me) Access: 2016-10-08 15:15:39.000000000 -0400
Modify: 2016-10-08 15:15:39.000000000 -0400
Change: 2016-10-08 15:15:39.000000000 -0400
If we touch the file again and then examine it with stat, we will see that the file’s times have been updated.:
[me@linuxbox ~]$ touch playground/timestamp
[me@linuxbox ~]$ stat playground/timestamp
File: `playground/timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me) Access: 2016-10-08 15:23:33.000000000 -0400
Modify: 2016-10-08 15:23:33.000000000 -0400
Change: 2016-10-08 15:23:33.000000000 -0400
[me@linuxbox ~]$ touch playground/timestamp
[me@linuxbox ~]$ stat playground/timestamp
File: `playground/timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me) Access: 2016-10-08 15:23:33.000000000 -0400
Modify: 2016-10-08 15:23:33.000000000 -0400
Change: 2016-10-08 15:23:33.000000000 -0400
Next, let’s use find to update some of our playground files:
[me@linuxbox ~]$ find playground -type f -name 'file-B' -exec touch '{}' ';'
[me@linuxbox ~]$ find playground -type f -name 'file-B' -exec touch '{}' ';'
This updates all files in the playground named file-B. Next we’ll use find to identify the updated files by comparing all the files to the reference file timestamp:
[me@linuxbox ~]$ find playground -type f -newer playground/timestamp
[me@linuxbox ~]$ find playground -type f -newer playground/timestamp
The results contain all 100 instances of file-B. Since we performed a touch on all the files in the playground named file-B after we updated timestamp, they are now “newer” than timestamp and thus can be identified with the -newer test.
Finally, let’s go back to the bad permissions test we performed earlier and apply it to
[me@linuxbox ~]$ find playground \( -type f -not -perm 0600 \) -or \(
-type d -not -perm 0700 \)
[me@linuxbox ~]$ find playground \( -type f -not -perm 0600 \) -or \(
-type d -not -perm 0700 \)
This command lists all 100 directories and 2600 files in playground (as well as timestamp and playground itself, for a total of 2702) because none of them meets our definition of “good permissions.” With our knowledge of operators and actions, we can add actions to this command to apply new permissions to the files and directories in our playground:
[me@linuxbox ~]$ find playground \( -type f -not -perm 0600 -exec chmod 0600 '{}' ';' \) -or \( -type d -not -perm 0700 -exec chmod 0700 '{}' ';' \)
[me@linuxbox ~]$ find playground \( -type f -not -perm 0600 -exec chmod 0600 '{}' ';' \) -or \( -type d -not -perm 0700 -exec chmod 0700 '{}' ';' \)
On a day-to-day basis, we might find it easier to issue two commands, one for the direc- tories and one for the files, rather than this one large compound command, but it’s nice to know that we can do it this way. The important point here is to understand how the opera- tors and actions can be used together to perform useful tasks.