Merge pull request #7234 from jessie-pang/master

20170921 Mastering file searches on Linux.md
This commit is contained in:
Xingyu.Wang 2018-01-18 09:34:50 +08:00 committed by GitHub
commit 780c868fb8
2 changed files with 234 additions and 224 deletions

View File

@ -1,224 +0,0 @@
Translating by jessie-pang
Mastering file searches on Linux
======
![](https://images.idgesg.net/images/article/2017/09/telescope-100736548-large.jpg)
There are many ways to search for files on Linux systems and the commands can be very easy or very specific -- narrowing down your search criteria to find what just you're looking for and nothing else. In today's post, we're going to examine some of the most useful commands and options for your file searches. We're going to look into:
* Quick finds
* More complex search criteria
* Combining conditions
* Reversing criteria
* Simple vs. detailed responses
* Looking for duplicate files
There are actually several useful commands for searching for files. The **find** command may be the most obvious, but it's not the only command or always the fastest way to find what you're looking for.
### Quick file search commands: which and locate
The simplest commands for searching for files are probably **which** and **locate**. Both have some constraints that you should be aware of. The **which** command is only going to search through directories on your search path looking for files that are executable. It is generally used to identify commands. If you are curious about what command will be run when you type "which", for example, you can use the command "which which" and it will point you to the executable.
```
$ which which
/usr/bin/which
```
The **which** command will display the first executable that it finds with the name you supply (i.e., the one you would run if you use that command) and then stop.
The **locate** command is a bit more generous. However, it has a constraint, as well. It will find any number of files, but only if the file names are contained in a database prepared by the **updatedb** command. That file will likely be stored in some location like /var/lib/mlocate/mlocate.db, but is not intended to be read by anything other than the locate command. Updates to this file are generally made by updatedb running daily through cron.
Simple **find** commands don't require a lot more effort, but they do require a starting point for the search and some kind of search criteria. The simplest find command -- one that searches for files by name -- might look like this:
```
$ find . -name runme
./bin/runme
```
Searching from the current position in the file system by file name as shown will also involve searching all subdirectories unless a search depth is specified.
### More than just file names
The **find** command allows you to search on a number of criteria beyond just file names. These include file owner, group, permissions, size, modification time, lack of an active owner or group and file type. And you can do things beyond just locating the files. You can delete them, rename them, change ownership, change permissions, or run nearly any command against the located files.
These two commands would find 1) files owned by root within the current directory and 2) files _not_ owned by the specified user (in this case, shs). In this case, both responses are the same, but they won't always be.
```
$ find . -user root -ls
396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./xyz -> /home/peanut/xyz
$ find . ! -user shs -ls
396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./xyz -> /home/peanut/xyz
```
The ! character represents "not" -- reversing the condition that follows it.
The command below finds files that have a particular set of permissions.
```
$ find . -perm 750 -ls
397176 4 -rwxr-x--- 1 shs shs 115 Sep 14 13:52 ./ll
398209 4 -rwxr-x--- 1 shs shs 117 Sep 21 08:55 ./get-updates
397145 4 drwxr-x--- 2 shs shs 4096 Sep 14 15:42 ./newdir
```
This command displays files with 777 permissions that are _not_ symbolic links.
```
$ sudo find /home -perm 777 ! -type l -ls
397132 4 -rwxrwxrwx 1 shs shs 18 Sep 15 16:06 /home/shs/bin/runme
396949 4 -rwxrwxrwx 1 root root 558 Sep 21 11:21 /home/oops
```
The following command looks for files that are larger than a gigabyte in size. And notice that we've located a very interesting file. It represents the physical memory of this system in the ELF core file format.
```
$ sudo find / -size +1G -ls
4026531994 0 -r-------- 1 root root 140737477881856 Sep 21 11:23 /proc/kcore
1444722 15332 -rw-rw-r-- 1 shs shs 1609039872 Sep 13 15:55 /home/shs/Downloads/ubuntu-17.04-desktop-amd64.iso
```
Finding files by file type is easy as long as you know how the file types are described for the find command.
```
b = block special file
c = character special file
d = directory
p = named pipe
f = regular file
l = symbolic link
s = socket
D = door (Solaris only)
```
In the commands below, we are looking for symbolic links and sockets.
```
$ find . -type l -ls
396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./whatever -> /home/peanut/whatever
$ find . -type s -ls
395256 0 srwxrwxr-x 1 shs shs 0 Sep 21 08:50 ./.gnupg/S.gpg-agent
```
You can also search for files by inode number.
```
$ find . -inum 397132 -ls
397132 4 -rwx------ 1 shs shs 18 Sep 15 16:06 ./bin/runme
```
Another way to search for files by inode involves using the **debugfs** command. On a large file system, this command might be considerably faster than using find. You may need to install icheck.
```
$ sudo debugfs -R 'ncheck 397132' /dev/sda1
debugfs 1.42.13 (17-May-2015)
Inode Pathname
397132 /home/shs/bin/runme
```
In the following command, we're starting in our home directory (~), limiting the depth of our search (how deeply we'll search subdirectories) and looking only for files that have been created or modified within the last day (mtime setting).
```
$ find ~ -maxdepth 2 -mtime -1 -ls
407928 4 drwxr-xr-x 21 shs shs 4096 Sep 21 12:03 /home/shs
394006 8 -rw------- 1 shs shs 5909 Sep 21 08:18 /home/shs/.bash_history
399612 4 -rw------- 1 shs shs 53 Sep 21 08:50 /home/shs/.Xauthority
399615 4 drwxr-xr-x 2 shs shs 4096 Sep 21 09:32 /home/shs/Downloads
```
### More than just listing files
With an **-exec** option, the find command allows you to change files in some way once you've found them. You simply need to follow the -exec option with the command you want to run.
```
$ find . -name runme -exec chmod 700 {} \;
$ find . -name runme -ls
397132 4 -rwx------ 1 shs shs 18 Sep 15 16:06 ./bin/runme
```
In this command, {} represents the name of the file. This command would change permissions on any files named "runme" in the current directory and subdirectories.
Put whatever command you want to run following the -exec option and using a syntax similar to what you see above.
### Other search criteria
As shown in one of the examples above, you can also search by other criteria -- file age, owner, permissions, etc. Here are some examples.
#### Finding by user
```
$ sudo find /home -user peanut
/home/peanut
/home/peanut/.bashrc
/home/peanut/.bash_logout
/home/peanut/.profile
/home/peanut/examples.desktop
```
#### Finding by file permissions
```
$ sudo find /home -perm 777
/home/shs/whatever
/home/oops
```
#### Finding by age
```
$ sudo find /home -mtime +100
/home/shs/.mozilla/firefox/krsw3giq.default/gmp-gmpopenh264/1.6/gmpopenh264.info
/home/shs/.mozilla/firefox/krsw3giq.default/gmp-gmpopenh264/1.6/libgmpopenh264.so
```
#### Finding by age comparison
Commands like this allow you to find files newer than some other file.
```
$ sudo find /var/log -newer /var/log/syslog
/var/log/auth.log
```
### Finding duplicate files
If you're looking to clean up disk space, you might want to remove large duplicate files. The best way to determine whether files are truly duplicates is to use the **fdupes** command. This command uses md5 checksums to determine if files have the same content. With the -r (recursive) option, fdupes will run through a directory and find files that have the same checksum and are thus identical in content.
If you run a command like this as root, you will likely find a lot of duplicate files, but many will be startup files that were added to home directories when they were created.
```
# fdupes -rn /home > /tmp/dups.txt
# more /tmp/dups.txt
/home/jdoe/.profile
/home/tsmith/.profile
/home/peanut/.profile
/home/rocket/.profile
/home/jdoe/.bashrc
/home/tsmith/.bashrc
/home/peanut/.bashrc
/home/rocket/.bashrc
```
Similarly, you might find a lot of duplicate configuration files in /usr that you shouldn't remove. So, be careful with the fdupes output.
The fdupes command isn't always speedy, but keeping in mind that it's running checksum queries over a lot of files to compare them, you'll probably appreciate how efficient it is.
### Wrap-up
There are lots of way to locate files on Linux systems. If you can describe what you're looking for, one of the commands above will help you find it.
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3227075/linux/mastering-file-searches-on-linux.html
作者:[Sandra Henry-Stocker][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/

View File

@ -0,0 +1,234 @@
精通 Linux 上的文件搜索
======
![](https://images.idgesg.net/images/article/2017/09/telescope-100736548-large.jpg)
在 Linux 系统上搜索文件的方法有很多,有的命令很简单,有的很详细。我们的目标是:缩小搜索范围,找到您正在寻找的文件,又不受其他文件的干扰。在今天的文章中,我们将研究一些对文件搜索最有用的命令和选项。我们将涉及:
* 快速搜索
* 更复杂的搜索条件
* 连接条件
* 反转条件
* 简单和详细的回应
* 寻找重复的文件
有很多有用的命令可以搜索文件,**find** 命令可能是其中最有名的,但它不是唯一的命令,也不一定总是找到目标文件的最快方法。
### 快速搜索命令which 和 locate
搜索文件的最简单的命令可能就是 **which****locate** 了,但二者都有一些局限性。**which** 命令只会在系统定义的搜索路径中,查找可执行的文件,通常用于识别命令。如果您对输入 which 时会运行的命令感到好奇,您可以使用命令 which which它会指向对应的可执行文件。
```
$ which which
/usr/bin/which
```
**which** 命令会显示它找到的第一个以相应名称命名的可执行文件(也就是使用该命令时将运行的那个文件),然后停止。
**locate** 命令更大方一点,它可以查找任意数量的文件,但它也有一个限制:仅当文件名被包含在由 **updatedb** 命令准备的数据库时才有效。该文件可能会存储在某个位置,如 /var/lib/mlocate/mlocate.db但不能用 locate 以外的任何命令读取。这个文件的更新通常是通过每天通过 cron 运行的 updatedb 进行的。
简单的 **find** 命令不需要太多限制,不过它需要搜索的起点和指定搜索条件。最简单的 find 命令:按文件名搜索文件。如下所示:
```
$ find . -name runme
./bin/runme
```
如上所示,通过文件名搜索文件系统的当前位置将会搜索所有子目录,除非您指定了搜索深度。
### 不仅仅是文件名
**find** 命令允许您搜索除文件名以外的多种条件,包括文件所有者、组、权限、大小、修改时间、缺少所有者或组和文件类型等。除了查找文件外,您还可以删除文件、对其进行重命名、更改所有者、更改权限和对文件运行几乎任何命令。
下面两条命令会查找:在当前目录中 root 用户拥有的文件,以及非指定用户(在本例中为 shs拥有的文件。在这个例子中两个输出是一样的但并不总是如此。
```
$ find . -user root -ls
396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./xyz -> /home/peanut/xyz
$ find . ! -user shs -ls
396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./xyz -> /home/peanut/xyz
```
感叹号“!”字符代表“非”:反转跟随其后的条件。
下面的命令将查找具有特定权限的文件:
```
$ find . -perm 750 -ls
397176 4 -rwxr-x--- 1 shs shs 115 Sep 14 13:52 ./ll
398209 4 -rwxr-x--- 1 shs shs 117 Sep 21 08:55 ./get-updates
397145 4 drwxr-x--- 2 shs shs 4096 Sep 14 15:42 ./newdir
```
接下来的命令显示具有 777 权限的非符号链接文件:
```
$ sudo find /home -perm 777 ! -type l -ls
397132 4 -rwxrwxrwx 1 shs shs 18 Sep 15 16:06 /home/shs/bin/runme
396949 4 -rwxrwxrwx 1 root root 558 Sep 21 11:21 /home/oops
```
以下命令将查找大小超过千兆字节的文件。请注意,我们找到了一个非常有趣的文件。它在 ELF 核心文件格式中代表该系统的物理内存。
```
$ sudo find / -size +1G -ls
4026531994 0 -r-------- 1 root root 140737477881856 Sep 21 11:23 /proc/kcore
1444722 15332 -rw-rw-r-- 1 shs shs 1609039872 Sep 13 15:55 /home/shs/Downloads/ubuntu-17.04-desktop-amd64.iso
```
只要您知道 find 命令是如何描述文件类型的,就可以通过文件类型来查找文件。
```
b = 块设备文件
c = 字符设备文件
d = 目录
p = 命名管道
f = 常规文件
l = 符号链接
s = 套接字
D = 门(仅限 Solaris
```
在下面的命令中,我们要寻找符号链接和套接字:
```
$ find . -type l -ls
396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./whatever -> /home/peanut/whatever
$ find . -type s -ls
395256 0 srwxrwxr-x 1 shs shs 0 Sep 21 08:50 ./.gnupg/S.gpg-agent
```
您还可以根据 inode 数字来搜索文件:
```
$ find . -inum 397132 -ls
397132 4 -rwx------ 1 shs shs 18 Sep 15 16:06 ./bin/runme
```
另一种通过 inode 搜索文件的方法是使用 **debugfs** 命令。在大的文件系统上,这个命令可能比 find 快得多,您可能需要安装 icheck。
```
$ sudo debugfs -R 'ncheck 397132' /dev/sda1
debugfs 1.42.13 (17-May-2015)
Inode Pathname
397132 /home/shs/bin/runme
```
在下面的命令中我们从主目录开始限制搜索的深度是我们将搜索子目录的层数并只查看在最近一天内创建或修改的文件mtime 设置)。
```
$ find ~ -maxdepth 2 -mtime -1 -ls
407928 4 drwxr-xr-x 21 shs shs 4096 Sep 21 12:03 /home/shs
394006 8 -rw------- 1 shs shs 5909 Sep 21 08:18 /home/shs/.bash_history
399612 4 -rw------- 1 shs shs 53 Sep 21 08:50 /home/shs/.Xauthority
399615 4 drwxr-xr-x 2 shs shs 4096 Sep 21 09:32 /home/shs/Downloads
```
### 不仅仅是列出文件
使用 **-exec** 选项,在您使用 find 命令找到文件后可以以某种方式更改文件。您只需参照 -exec 选项即可运行相应的命令。
```
$ find . -name runme -exec chmod 700 {} \;
$ find . -name runme -ls
397132 4 -rwx------ 1 shs shs 18 Sep 15 16:06 ./bin/runme
```
在这条命令中,“{}”代表文件名。此命令将更改当前目录和子目录中任何名为“runme”的文件的权限。
把您想运行的任何命令放在 -exec 选项之后,并使用类似于上面命令的语法即可。
### 其他搜索条件
如上面的例子所示,您还可以通过其他条件进行搜索:文件的修改时间、所有者、权限等。以下是一些示例。
#### 根据用户查找文件
```
$ sudo find /home -user peanut
/home/peanut
/home/peanut/.bashrc
/home/peanut/.bash_logout
/home/peanut/.profile
/home/peanut/examples.desktop
```
#### 根据权限查找文件
```
$ sudo find /home -perm 777
/home/shs/whatever
/home/oops
```
#### 根据修改时间查找文件
```
$ sudo find /home -mtime +100
/home/shs/.mozilla/firefox/krsw3giq.default/gmp-gmpopenh264/1.6/gmpopenh264.info
/home/shs/.mozilla/firefox/krsw3giq.default/gmp-gmpopenh264/1.6/libgmpopenh264.so
```
#### 通过比较修改时间查找文件
像这样的命令可以让您找到修改时间较近的文件。
```
$ sudo find /var/log -newer /var/log/syslog
/var/log/auth.log
```
### 寻找重复的文件
如果您正在清理磁盘空间,则可能需要删除较大的重复文件。确定文件是否真正重复的最好方法是使用 **fdupes** 命令。此命令使用 md5 校验和来确定文件是否具有相同的内容。使用 -r递归选项fdupes 将在一个目录下并查找具有相同校验和而被确定为内容相同的文件。
如果以 root 身份运行这样的命令,您可能会发现很多重复的文件,但是很多文件都是创建时被添加到主目录的启动文件。
```
# fdupes -rn /home > /tmp/dups.txt
# more /tmp/dups.txt
/home/jdoe/.profile
/home/tsmith/.profile
/home/peanut/.profile
/home/rocket/.profile
/home/jdoe/.bashrc
/home/tsmith/.bashrc
/home/peanut/.bashrc
/home/rocket/.bashrc
```
同样,您可能会在 /usr 中发现很多重复的但不该删除的配置文件。所以,请谨慎利用 fdupes 的输出。
fdupes 命令并不总是很快,但是要记住,它正在对许多文件运行校验和来做比较,你可能会意识到它的有效性。
### 总结
有很多方法可以在 Linux 系统上查找文件。如果您可以描述清楚您正在寻找什么,上面的命令将帮助您找到目标。
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3227075/linux/mastering-file-searches-on-linux.html
作者:[Sandra Henry-Stocker][a]
译者:[jessie-pang](https://github.com/jessie-pang)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/