Lesson 8 | Using xargs and helpful utilities with find |
Objective | Use the find command, its predicates, and other utilities to create more targeted finds. |
Using xargs Utilities
Question: How can I use the find command, its predicates, and other utilities to create more targeted finds in Unix?
The find command is a versatile tool in Unix-like operating systems that allows users to locate files and directories based on specified conditions, or predicates. These predicates can be combined with other utilities to create more sophisticated and targeted queries. Here are several ways you can harness the full potential of find:
- Search by filename and file type: Use -name or -iname (case-insensitive) predicate to find a file by its name, and -type to specify the file type.
Example: To find all .txt files (case-insensitive) in the /home/user directory:
[root@ip-171-32-8-154 ROOT]# find / -name http-protocol.jsp
/opt/apache-tomcat-10.0.23/webapps/ROOT/advanced-perl/module1/http-protocol.jsp
- Find files with specific permissions: The -perm predicate is used for this purpose.
Example: To find the file named http-protocol.jsp on your Tomcat Installation.
[root@ip-172-31-9-155 ROOT]# find / -name http-protocol.jsp
/opt/apache-tomcat-10.0.23/webapps/ROOT/advanced-perl/module1/http-protocol.jsp
- Search by owner or group: The -user and -group predicates allow you to find files owned by a specific user or group.
Example: To find all files owned by the user username:
find /home/user -type f -user username
- Find files modified within a specific time period: Use -mtime, -atime or -ctime for this. The time is specified in days.
Example: To find all files in the /home/user directory modified in the last 2 days:
find /home/user -type f -mtime -2
- Combine predicates: You can use logical operators such as -a (and), -o (or), and ! (not) to combine predicates and refine your search.
Example: To find all .txt files in /home/user directory that have been modified in the last 2 days:
find /home/user -type f -name "*.txt" -a -mtime -2
- Use of the -exec or -execdir predicate: These predicates allow you to execute a command on each file found.
Example: To find all .txt files in the /home/user directory and delete them:
find /home/user -type f -name "*.txt" -exec rm {} \;
- Using find with other Unix utilities: The find command can be piped (|) into other Unix utilities for further processing.
Example: To find all .txt files in the /home/user directory and count them:
find /home/user -type f -name "*.txt" | wc -l
In summary, the find command's power comes from the flexibility provided by its predicates and its ability to interface with other Unix utilities. By understanding and leveraging these predicates, you can create highly targeted queries to locate exactly what you need.
Helpful Utilities with find
The
xargs command is used to modify the behavior of other commands so that they read their arguments from standard input instead of the command line. It is usually used in a
pipe[1].
For example:
wc Example
For example,
who | wc -l
would take the output of the who command and use that as the input for the
wc -l
command.
This would give you the number of users currently logged in.
find . –type d –print | xargs ls –l
The find
command in this example searches for all directories below the current directory (.
).
It generates a list of these files. The xargs
command passes this list as arguments to the ls –l
command, yielding a directory listing of all subdirectories of (.
).x
Another interesting and useful argument for the find command is the -ok
argument. This argument allows you to issue any command, then be prompted by the system before it executes the command. For example:
find / –atime +365 -ok rm {} /;
would find all files on the system (
/
) accessed more than 365 days ago (
-atime +365
) and would then prompt you to confirm that you want to remove (
rm
) the files. The syntax for using this argument is
-ok command {} /;
where
command
is any UNIX command.
Other handy tricks
Just like you can use the pipe command (
|
), you can use the redirect command (
>
) to take the results from a find or list, then place it into a text file. For example:
ls –l > listfile
would place the output of the listing into a file named listfile.
Three other handy commands are
wc, head, and tail.
Do not forget the
grep command.
It searches the named input files for lines containing a match to the given pattern.
The paragraph below discusses using the
xargs
command and other utilities in conjunction with the
find
command.
Creating more targeted finds
For your convenience, here are the steps you followed to solve the system administration scenarios:
- You are logged on as user1, and are in your home directory. Use the
ls -l
command to view the files.
Solution:
ls -l
- Notice the large number of files and directories. Instead of spending time sifting through this huge list, issue a command that lists the 10 newest files.
Solution: ls -t | head
- List the three oldest files in your home directory.
Solution:
ls -t | tail -3
- In conducting a quick audit of the /etc/ directory, you discover a new file that is publicly writable. You now wish to learn about other publicly writable files on your entire system. To enable the most thorough search, assume root privileges.
Solution: Type su
and enter the root password.
- Now that you have assumed root privileges, issue a
find
command that searches the entire system for all publicly writable files (that is, files that have write permission in the "other" block). Although in a real UNIX environment, the order of the find
predicates don't matter, for this simulation use the permissions predicate first followed by the type predicate. Do not forget to end the command with the print predicate.
Solution: find / -perm -002 -type f -print
- Your assistant has created a new directory in /usr/bin, but he is now unavailable. You need to identify the directory he created quickly. Issue a
find
command that discovers how many subdirectories exist in /usr/bin.
Make sure that you use -print
at the end of your command.
Solution: find /usr/bin -type d -print
- A user with the account name user2 has gotten lost in her /home/user2 subdirectory. Before she called you, she created a file, but now she can't find it. She knows that the file was created today. Issue a
find
command that lists all the files user2 owns that were created in the last day. For the purposes of this simulation, specify the user predicate first, followed by the predicate that allows you to search for modification time, and then end your find
command with the -print
predicate. Finally, use the redirect operator to save this list into a text file named lost in the user's home directory.
Solution: find /home/user2/ -user user2 -mtime -1 -print > /home/user2/lost
- You are still root, and are in the /home/user1 directory. You wish to confirm that the lost file was created and that it has the correct contents. Use the
head
command to read the lost file you created in the /home/user2 directory.
Solution: head /home/user2/lost
- User2 can find her file by studying the file named lost. Now, you wish to search for and delete all empty text files in user2’s home directory. Issue a
find
command that searches for empty text files in the /home/user2 subdirectory. Don't forget to end the find
command with the -print
predicate.
Solution: find /home/user2 -size 0 -print
- Now, modify the command you just entered so the system will find the empty files and then prompt you to see if you wish to delete each file.
Solution: find /home/user2 -size 0 -print -ok rm {} \;
- Type
y
to delete the file named lostfile
.
- Type
n
to keep the file named readme
.
- Type
n
to keep the file named september141995
.
- Exit the root subshell.
[1]pipe: A pipe is a way of using the output of one command as the input for another command and is designated by the character |.