打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Guide to Linux Find Command Mastery

原文:http://www.oracle.com/technology/pub/articles/calish-find.html

By Sheryl Calish

A quick introduction to the most powerful—as well as confusing—aspects of this ubiquitous command.

Published July 2008

The Linux findcommand is simultaneously one of the most useful and confounding of allLinux commands. It is difficult because its syntax varies from thestandard syntax of other Linux commands. It is powerful, however,because it allows you to find files by filename, by file type, by user,and even by time stamp. With the find command, not only areyou able to locate files with any combination of these attributes, butyou can also perform actions on the files it finds.

The purpose of this article is to simplify the task of learning and using the findcommand by giving you an overview of its purpose and potential. At thesame time, it will provide a basic tutorial and reference for some ofthe most powerful but confusing aspects of the find command.

[Note: The version of find used for this article is the GNU version, so some details may vary for other versions of find.]

Basic Format

To begin, let’s look at the basic structure of the find command:

find   start_directory  test  options   criteria_to_matchaction_to_perform_on_results                       
In the following command, find will start looking in the current directory, denoted by the “.”, for any file with the “java” extension in its name:
find . -name  "*.java"   

Here’s an abbreviated listing of what it found:

find . -name  "*.java"./REGEXPvalidate/src/oracle/otnsamples/plsql/ConnectionManager.java./REGEXPvalidate/src/oracle/otnsamples/plsql/DBManager.java..

[Note:If you cut and paste from this article to run the find command, you mayneed to replace the double quotes (“”) using your own keyboard forproper results.]

The following command will do thesame thing. In either case, you need to escape the wildcard characterto be sure it passes to the find command and is not interpreted by theshell. So, put your search string in quotes, or precede it with abackslash:

find . -name  \*.java

Althoughall arguments to find are optional, the search will begin by default inthe current directory if you do not specify where to begin searching.If you do not specify a test condition, an option, or a value to bematched your results will be either incomplete or indiscriminating.
 
Running the following three find commands will all yield the sameresults—a full listing of all files in the current directory and allsubdirectories including hidden files:

findfind .find . -print

This is similar torunning an ls command with the -la options. If you want the output ofthe above commands to contain the full pathnames, perhaps for a backup,you would need to specify the full path for the starting directory:

find /home/bluher -name \*.java/home/bluher/plsql/REGEXPvalidate/src/oracle/otnsamples/plsql/ConnectionManager.java/home/bluher/plsql/REGEXPvalidate/src/oracle/otnsamples/plsql/DBManager.java/...

Youcan also specify more than one starting directory in a search string.If run as a user with appropriate privileges, the following commandwill descend into the /usr, /home, and then /tmp directories to lookfor all jar files:  

find /usr /home  /tmp -name "*.jar"

Ifyou don’t have the appropriate permissions, however, you will generateerror messages as you begin to look through many system directories.The following is an example:

find:  /tmp/orbit-root: Permission denied

You can avoid a cluttered output by appending your search string as follows:

find /usr /home  /tmp -name "*.jar" 2>/dev/null

This sends all error messages to the null file, thereby providing cleaner output.

By default, find is case sensitive. For a case-insensitive find, substitute the -iname test for the -name test.

find downloads  -iname "*.gif"downloads/.xvpics/Calendar05_enlarged.gifdownloads/lcmgcfexsmall.GIF
You can also search for files by types other than filename. Forinstance, you can find all the subdirectories in a directory with thefollowing command:
find . -type d          

You can find all the symbolic links in your /usr directory with the following command:

find /usr -type l

Thiswill probably yield a list of more than 3,000 links. Either of thefollowing commands, run with root privileges, will yield a list oflinks in the /usr directory and the file to which it points:

# find /usr/bin  -type l  -name "z*" -exec ls  -l {} \;lrwxrwxrwx 1 root  root 8 Dec 12 23:17 /usr/bin/zsh -> /bin/zshlrwxrwxrwx 1 root  root 5 Dec 12 23:17 /usr/bin/zless -> zmorelrwxrwxrwx 1 root  root 9 Dec 12 23:17 /usr/bin/zcat -> /bin/zcat
find /usr/bin -type  l  -name "z*" -ls

Thesecond, shorter command, however, will yield a long file list withdirectory and inode information as well. We will discuss the use of the-exec and -ls actions later in this article.

Other filetypes that find can locate include

• b—block (buffered) special
• c—character (unbuffered) special
• p—named pipe (FIFO)
• s—socket

Using root as the starting point for a findcommand can slow down your system significantly. If you really must runsuch a command, you might run it during low-use time or overnight. Youcan redirect the output to a file using the following syntax:

find  /   -print > masterfilelist.out

Ifyou find you have erroneously entered a find command that producescopious unwanted output, just interrupt the command by pressing CTRL-C,which stops the most recently executed command.

On anenterprise network with multiple file systems, it is especially goodpractice to restrict the files that find looks for. Use as many of theoptions and tests as necessary to reduce the load on your system. Twoof the most useful options for this purpose are -xdev and -mount. Theynarrow the search by preventing find from descending into directorieson other file systems such as MS-DOS, CD-ROM, or AFS. This restrictsthe search to the same type of file system as the startdirectory.

Userson a dual boot system can play with these options if the mount commandis run. Assuming that a Windows partition is involved, you could mountit with something like the following command:

mount -t vfat  /dev/sda1 /mnt/msdos

Theactual command that you use will depend on how your system is set up.You can verify that the partition was mounted by running df or byexecuting the following command:

find /mnt/msdos  -name "*.txt" 2> /dev/null

Youshould see a long list of files on the MS Windows partition. Now runthe following command with either the -mount or -xdev option:

find / -name  "*.txt" -mount 2> /dev/null

or

find / -name  "*.txt" -xdev 2> /dev/null

Another possibility is to explicitly tell find which file system to look in using the -fstype test, as in this example:

find / -name  "*.txt" -fstype vfat 2> /dev/null

Finding Time

The find command has several options that are used to search for files based on your system’s time stamps. These time stamps include

mtimethe time that the contents of a file were last modified
atime—the time that a file was read or accessed
ctime—the time that a file’s status was changed

Whilethe meaning of mtime and atime is pretty self-evident, ctime requiresmore explanation. Because the inode maintains metadata on each file,the inode data will change if the metadata related to the file ischanged. This could be caused by a range of actions, including thecreation of a symbolic link to the file, changing the permissions on afile, or moving the file. Because the contents of the file are notbeing read or modified in these cases, themtime and atime will notchange, but the ctime will change. 

Each of these time options needs to be used with a value n, which is specified as -n, n, or +n.

• -n returns less than n
• +n returns greater than n
• n, by itself,returns exactly n matches

Let’s look at some examples to make this clearer. The following command will find all the files modified within the last hour:

find . -mtime -1./plsql/FORALLSample./plsql/RegExpDNASample/plsql/RegExpSample

Running the same command with 1 instead of -1 finds all the files that were modified exactly one hour ago:

find . -mtime 1 

Theabove command may not yield any results, because it asks for an exactmatch. The following command looks for the files that were modifiedmore than an hour ago:

find . -mtime +1 
Bydefault, -mtime, -atime, and -ctime refer to the last 24 hours. If,however, they are preceded by the daystart option, the 24-hour periodwill begin with the start of the current day. You can also look fortime stamps that have changed in less than an hour using mmin, amin,and cmin.

If you run the following immediately after logging into your account, you will find all files read less than 1 minute ago:

find . -amin -1./.bashrc/.bash_history./.xauthj5FCx1

It should be noted that locating a file with the find command itself changes that file’s access time as part of its metadata.

Youcan also find files that have been modified or accessed in comparisonto a specific file with the options -newer, -anewer, and –cnewer. Thisis similar to -mtime, -atime, and –ctime.
 
• -newer refers to files whose contents have been modified more recently
• -anewer refers to files that have been read more recently
• -cnewer refers to files whose status has changed more recently

To find all the files in your home directory that have been edited in some way since the last tar file, use this command:

find . -newer  backup.tar.gz

Finding Files by Size

The -size option finds files that meet the size criteria specified. To find all user files larger than 5MB, use

find / -size  +5000000c 2> /dev/null/var/log/lastlog/var/log/cups/access_log.4/var/spool/mail/bluher

The“c” at the end reports our results in bytes. By default, find reportssize as the number of 512-byte blocks. We could also see the results asthe number of kilobytes if we replace the “c” with a “k” or as thenumber of two-byte words if we use a “w”.

The -sizeoption is frequently used to search for all zero-byte files and movethem to the /tmp/zerobyte folder. The following command does just that:

find test -type f  -size 0 -exec mv {} /tmp/zerobyte \;

The-exec action allows find to perform any shell command on the files itencounters. You will see many more examples of its use later in thisarticle. The curly brackets allow each of the empty files to be moved.

The option -empty can also be used to find empty files:

find test -empty       test/footest/test

Finding by Permission and Ownership

Thefind command can be indispensable for monitoring the security of yoursystem. You can look for files with wide open permissions usingsymbolic or octal notation as follows:

find . -type f  -perm a=rwx -exec ls -l {} \; 

or

find . -type f  -perm 777 -exec ls -l {} \;-rwxrwxrwx 1 bluher  users 0 May 24 14:14 ./test.txt

Inthe above and the following commands in this section, we are using the-exec ls -l action so you can see the actual permissions of the filesreturned. The command will find files that are writable by both the“other” and the group:

find plsql -type f  -perm -ug=rw -exec ls -l {} \; 2>/dev/null

or

find plsql -type f  -perm -220 -exec ls -l {} \; 2>/dev/null-rw-rw-rw- 1 bluher users 4303  Jun  7   2004 plsql/FORALLSample/doc/otn_new.css-rw-rw-rw- 1 bluher users 10286 Jan  12  2005  plsql/FORALLSample/doc/readme.html-rw-rw-rw- 1 bluher users 22647 Jan  12  2005  plsql/FORALLSample/src/config.sql..
This next command will find files that are writable by the user, the group, or both: 
find plsql -type f  -perm /ug=rw -exec ls -l {} \; 2>/dev/null, or,find plsql -type f  -perm /220 -exec ls -l {} \; 2>/dev/null-rw-r--r-- 1 bluher users 21473  May  3 16:02 plsql/regexpvalidate.zip-rw-rw-rw- 1 bluher users 4303  Jun  7   2004 plsql/FORALLSample/doc/otn_new.css-rw-rw-rw- 1 bluher users 10286 Jan  12  2005  plsql/FORALLSample/doc/readme.html-rw-rw-rw- 1 bluher users 22647 Jan  12  2005  plsql/FORALLSample/src/config.sql

You may see the following command cited on the Web and in older manuals:

find . -perm +220  -exec ls -l {} \; 2> /dev/null 

The + symbol does the same as the / symbol, although it is now deprecated in newer versions of GNU findutils.

To find all files on your system that are world writable, use the following command:

find / -wholename  '/proc' -prune  -o  -type f -perm -0002 -exec ls -l {} \;-rw-rw-rw- 1 bluher users 4303  Jun  7   2004/home/bluher/plsql/FORALLSample/doc/otn_new.css-rw-rw-rw- 1 bluher users 10286 Jan  12  2005  /home/bluher/plsql/FORALLSample/doc/readme.html...

Thefourth permission will be discussed in just a bit, but the “2” in thelast field is the “other” field in the file permissions, also known asthe write bit. We used a dash before the permission mode of 0002 toindicate that we want to see files with the write permission set forothers, regardless of what other permissions are set.

Theabove command also introduces three new concepts. Using -wholenametests for the file pattern “/proc”, if that pattern is found, -prune prevents find from descending into that directory. The Boolean “-o”enables find to process the rest of the command for other directories.As there is an implicit and operator (-a)  that is assumed between each expression, expressions following the andwill not be evaluated if the expression on the left evaluates to false;hence the need for the -o operator. The Boolean -not, !, is alsosupported by find, as is the use of parentheses to force precedence.

Systemadministrators frequently use find to search for regular files ofspecific users or groups using the name or ID of that user or group:

[root] $  find / -type f -user bluher -exec ls -ls {}  \;

Here is a severely abbreviated sample of the output of such a command:

4 -rw-r--r-- 1 bluher users 48  May  1 03:09  /home/bluher/public_html/.directory4 -rw-r--r-- 1 bluher users 925  May  1 03:09 /home/bluher/.profile

You can also use find to look for a file by group:

[root] $ find /  -type f -group users
find / -type d -gid  100

Thiscommand will yield a list of directories owned by group ID 100. To findthe appropriate uid or gid,  you can run the more or cat command on the/etc/passwd or /etc/group file.

Beyond finding filesof specific known users and groups, you may also find it useful to lookfor files lacking either of these. This next command identifies filesthat do not have a listing in the /etc/passwd or /etc/group file:

find / -nouser -o  -nogroup

Theabove command might not actually yield results on your system. It couldbe used, however, to identify files without a user or group, perhapsafter moving files around.

OK, now we can address that extra leading permission mentioned at the beginning of this section.

TheSGID and SUID are special access right flags that can be assigned tofiles and directories on a UNIX-based operating system. They are set toallow ordinary users on a computer system access to execute binaryexecutables with temporarily elevated privileges.

find /  \( -perm -2000 -o -perm -4000 \) -ls167901   12 -rwsr-xr-x   1 root     root         9340 Jun 16  2006 /usr/bin/rsh167334   12 -rwxr-sr-x   1 root     tty         10532 May  4  2007 /usr/bin/wall

Inthe above command, you can see the use of escaped parentheses. You canalso see the differences in permissions. The first file has the SGIDpermission set, and the second file has the SUID permission set. Thefinal action in the above command works like find with the -exec ls-dils action.

Controlling find

Unlikemany commands in Linux, find does not require the -r or -R option inorder to descend into the subdirectories. It does this by default.However, you may want to limit this behavior at times. For that reason,the options -depth, -maxdepth, and -mindepth and the action -prune maycome in handy.

We have already seen how useful -prune can be, so let’s take a look at the -depth, -maxdepth, and -mindepth options.

The-maxdepth and -mindepth options allow you to specify how far down thedirectory tree you want find to search. If you want find to look injust one level of the directory, you would use the maxdepth option.

Youcan see the effects of -maxdepth by running the following command tolook for log files in the top three levels of the directory tree. Thiswill produce considerably less output than when run without it.

find / -maxdepth 3  -name "*log"

You can also tell find to look in directories at least three levels down the directory tree:

find / -mindepth 3  -name "*log"

The-depth option ensures that a directory is evaluated before its contentsare evaluated. The following command provides an example:

find -name "*test*" -depth./test/test./test./localbin/test./localbin/test_shell_var./localbin/test.txt./test2/test/test./test2/test./test2

The World of find

Wehave looked at some of the more useful and somewhat obscure abilitiesof the find command, but there are additional tasks that find canperform. For instance, there are options that make find compatible with older UNIX versions and other operating systems andthat allow you to perform actions such as printing output to multiplefiles. After reading this article, you now have the background tounderstand the man page on find, and I encourage you to explore this powerful and useful tool.

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux文件查找命令find (两篇文章) - ottoCho的暂时荒废的技术博客 - ...
Linux:How To Find Largest Files /Directories In A Directory ? IT Sprite
CURL Command in Linux [21 Practical Examples]
CMake Cross Compiling
Availability and description of the File Checksum Integrity Verifier utility
Logs under /var/stm/logs/os in HPUX
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服