主要介绍下在 Linux 中,日常用到的一些常用指令,如 find、cmp 等。
find
对于 find 命令,即使系统中含有网络文件系统 (NFS), find 命令在该文件系统中同样有效,只要具有相应的权限。
如下是 find 命令的格式。
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
路径默认为当前路径,默认 expression 为 -print
,参数通常以 -
、(
、!
开头。
find 命令会从左到右检测 expression 的条件,当知道结果时退出,如 and 为假时, or 为真时。如果在路径中使用通配符,则路径需要以 ./
或 /
开头。
如下是常用选项:
-P 默认选项。对于符号链接,检查时检测符号链接本身。
-L 对于符号链接,检查时检测符号链接指向的内容,如果指向文件不在或find无法找到,则使用链接符号。
-H 除非是处理命令行,否则只针对符号本身。
-print 将匹配的文件输出到标准输出,查找结果使用换行间隔。
-print0 查找结果使用NULL间隔。
-exec 对匹配的文件执行该参数所给出的 shell 命令,相应的形式为 'command' { } \;,注意 { } 和 \; 之间的空格。
-ok 和 -exec 相同,不过在执行每一个命令之前,都会给出提示,让用户来确定是否执行。
-name 按照指定文件名搜索。可以使用通配符,此时需要加引号。
-perm 指定文件的权限。
mode 指定具体的权限,严格匹配,如 -perm g=w, 0020 。
-mode 转换为二进制后,为 1 的必须都匹配。
+/mode 转换为二进制后,为 1 的任何一位匹配即可,最好使用 / 。
-prune 不在当前指定的目录中查找,如果同时使用 -depth 选项,那么该选项被忽略。
-user username 指定用户名,也可以为 ID 。
-group groupname 指定组名,也可以为 ID 。
-amin +-n 按照文件访问时间来查找文件,n正好是n分钟,-n指n分钟以内,+n指n分钟以前。
-atime +-n 按照文件访问时间来查找文件,n正好是n天,-n指n天以内,+n指n天以前。
-cmin +-n 按照文件状态时间来查找文件,n正好是n分钟,-n指n分钟以内,+n指n分钟以前。
-ctime +-n 按照文件状态时间来查找文件,n正好是n天,-n指n天以内,+n指n天以前。
-mmin +-n 按照文件更改时间来查找文件,n正好是n分钟,-n指n分钟以内,+n指n分钟以前。
-mtime +-n 按照文件更改时间来查找文件,n正好是n天,-n指n天以内,+n指n天以前。
-nogroup 查无有效属组的文件,即文件的属组在/etc/groups中不存在。
-nouser 查无有效属主的文件,即文件的属主在/etc/passwd中不存在。
-group groupname 指定组名,也可以为ID。
-newer/cnewer/anewer file1 !file2 文件的修改时间/状态时间/访问时间,比file1早,比file2晚。
-newerXY reference XY可以是a/B/c/m/t,访问时间/创建时间(不支持)/状态时间/修改时间/指定时间。
-type b/d/c/p/l/f/s 块设备、目录、字符设备、管道、符号链接、普通文件、socket。
-size n[cwbkMG] 长度为n字节c/双字节w/块512字节b/千字节k/兆字节M/吉字节G的文件。
-fstype 查位于某一类型文件系统中的文件,这些文件系统类型通常可在 /etc/fstab 中找到。
-follow 如果遇到符号链接文件,就跟踪链接所指的文件。
-maxdepth levels 查找目录时的最大深度。
-path pattern 指定目录,可以使用通配符,与 Shell 相同。如果find .则path必须使用./doc,且不能以/结尾。
-depth 在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
示例
查找文件
find / -path "/etc*" -name "*.txt"
查找 /etc
目录下,且后缀是 txt
的文件,使用 -iname
忽略文件名的大小写。
用户andy所拥有的文件
find /etc -name "passwd*" -exec grep "andy" {} \;
find . -name "*.cpp" | xargs grep 'efg'
首先匹配所有文件名为 "passwd*"
的文件,如 passwd
、passwd.old
,然后执行 grep
命令看看在这些文件中是否存在一个 andy 用户。注意 {
}
之间没有空格,相当于前面查找到的文件。
忽略某个目录
find /etc -path "/etc/fonts" -a -prune -o -print
可以使用 -prune
指定需要忽略的目录,-a
可以去掉。使用该选项需要注意的是,如果同时使用了 -depth
选项,那么 -prune
选项就会被 find 命令忽略。
-a
-o
均支持短路操作,因此实际上述等于如下的伪代码:if -path "/etc/fonts": -prune else: -print
。
忽略多个目录
find /usr \( -path /usr/dir -o -path /usr/file \) -a -prune -o -print
-a
选项可以去掉,表示 and
,-o
表示 or
或者是 -not
,-prune
始终会返回 1
。
查找某一特定文件
find /usr \( -path /usr/dir -o -path /usr/file \) -a -prune -o -name "test" -print
注意,-name
等,应该放置到最后一个 -o
选项后面。
无主文件
find /home -nouser -print
查找属主帐户已经被删除的文件,这样就能够找到那些属主在 /etc/passwd
文件中没有有效帐户的文件。
查看某个时间点文件
find ./ -name "jdk*" | xargs ls -l --full-time 2>/dev/null | grep "2011-11-11 03:41:54"
查找 2011-11-11 03:41:54
时更改过的 jdk 文件。
cmp
二进制文件的比较。
cmp 命令会逐字节比较两个文件内容,如果两个文件内容完全,则 cmp 命令不显示任何内容。若两个文件内容有差异,会显示第一个不同之处的字节数和行数编号。
如果文件是 ‘-’ 或没给出,则从标准输入读入内容。
cmp [options] file1 file2
常用选项:
-l, --verbose
显示每一个不同点的字节号(10进制)和不同点的字节内容(8进制);会显示所有不同字节。
-b, --print-bytes
以子符的形式显示不同的字节。
-i NUM, --ignore-initial=NUM
两个文件均越过开始的NUM个字节开始比较。
-i NUM1:NUM2, --ignore-initial=NUM1:NUM2
第一个文件越过开始的NUM1个字节,第二个文件越过开始的NUM2个字节,开始比较。
-n NUM, --bytes=NUM
设定比较的上限,最多比较 NUM 个字节。
文件相同只返回0;文件不同返回1;发生错误返回2。
$ cmp file1 file2
file1 file2 differ: char 23, line 6
cmp: EOF on file1
第一行的结果表示 file1 与 file2 内容在第 6 行的第 23 个字符开始有差异。第二行的结果表示 file2 前半部分与 file1 相同,但在 file2 中还有其他数据。
常用技巧
如果其中的部分参数需要动态获取,而 ''
则会原样输出字符内容,那么可以通过类似如下的方式使用。
$ echo "'$(hostname)'" | xargs sed filename -e