总结一、区别
atime是指access time,即文件被读取或者执行的时间,修改文件是不会改变access time的。网上很多资料都声称cat、more等读取文件的命令会改变atime,但是我试验时却发现使用cat、more时atime没有被修改。这个问题需要另外做研究探讨。
ctime即change time文件状态改变时间,指文件的i结点被修改的时间,如通过chmod修改文件属性,ctime就会被修改。
mtime即modify time,指文件内容被修改的时间。
find . –mtime n中的n指的是24*n, +n、-n、n分别表示:
+n:大于n
-n: 小于n
n:等于n
find . –mtime n: File waslast modified n*24 hours ago.
最后一次修改发生在距离当前时间n*24小时至(n+1)*24 小时
find . –mtime +n:
最后一次修改发生在n+1天以前,距离当前时间为(n+1)*24小时或者更早
find . –mtime –n:
最后一次修改发生在n天以内,距离当前时间为n*24小时以内
总结二、实例
atime、mtime与ctime的区别
access time , atime在读取文件或执行文件时会修改
create time , ctime在文件写入,更改所有者,权限。链接时文件的ctime会随之改变
modified time ,mtime 在文件写入时会改变。
ls -lu 或者 ls -l --time=atime 显示文件的atime
ls -lc 或者 ls -l --time=ctime 显示文件的ctime
ls -l 显示文件的mtime
[root@station206 test]# touch test.txt
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 0 Blocks: 8 IO Block: 4096 regular
empty file
Device: fd00h/64768d Inode: 1179651 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:46:26.000000000 0800 ## atime
Modify: 2009-05-21 01:46:26.000000000 0800 ## mtime
Change: 2009-05-21 01:46:26.000000000 0800 ## ctime
[root@station206 test]# more test.txt ## 访问文件
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 0 Blocks: 8 IO Block: 4096 regular
empty file
Device: fd00h/64768d Inode: 1179651 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:47:21.000000000 0800 ## atime有变法了
Modify: 2009-05-21 01:46:26.000000000 0800
Change: 2009-05-21 01:46:26.000000000 0800
[root@station206 test]# echo asdf > test.txt ## 添加内容
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 5 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179651 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:47:21.000000000 0800 ## atime没有变法
,疑问?
Modify: 2009-05-21 01:48:14.000000000 0800 ## mtime有变法
Change: 2009-05-21 01:48:14.000000000 0800 ## ctime有变法
[root@station206 test]# chmod a x test.txt ## 修改属性
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 5 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179651 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:47:21.000000000 0800 ## atime没有变
法
Modify: 2009-05-21 01:48:14.000000000 0800 ## mtime没有变
法
Change: 2009-05-21 01:49:39.000000000 0800 ## ctime有变法
[root@station206 test]# vim test.txt ## 编辑文件
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:50:55.000000000 0800
Modify: 2009-05-21 01:50:55.000000000 0800
Change: 2009-05-21 01:50:55.000000000 0800 ## 都发生变法
[root@station206 test]# mv test.txt test.txt2
[root@station206 test]# stat test.txt
stat: cannot stat `test.txt': No such file or directory
[root@station206 test]# stat test.txt2
File: `test.txt2'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:50:55.000000000 0800
Modify: 2009-05-21 01:50:55.000000000 0800
Change: 2009-05-21 01:51:52.000000000 0800 ##只有ctime发
生变法
atime 访问时间(access time):访问时间是文件最后一次被读取的时间。因此
阅读一个文件会更新它的访问时间,而它的改变时间并没有变化(有关文件状态
的信息没有被改变),它的date.html' target='_blank'>修改时间也同样没有变化(文件内容本身没有被改变)
;
mtime 修改时间(modification time):文件内容最后被修改的时间。
ctime 改变时间(change time):文件状态(status)最后被改变的时间。
[root@station206 test]# touch -at 200701010000 test.txt2
[root@station206 test]# stat test.txt2
File: `test.txt2'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2007-01-01 00:00:00.000000000 0800
Modify: 2009-05-21 01:50:55.000000000 0800
Change: 2009-05-21 01:53:57.000000000 0800
[root@station206 test]# touch -mt 200701010000 test.txt2
[root@station206 test]# stat test.txt2
File: `test.txt2'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2007-01-01 00:00:00.000000000 0800
Modify: 2007-01-01 00:00:00.000000000 0800
Change: 2009-05-21 01:54:07.000000000 0800
[root@station206 test]# touch -ct 200701010000 test.txt2
[root@station206 test]# stat test.txt2
File: `test.txt2'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2007-01-01 00:00:00.000000000 0800
Modify: 2007-01-01 00:00:00.000000000 0800
Change: 2009-05-21 01:54:12.000000000 0800
## touch改不了ctime?可能只能修改系统时间才能修改ctime了。http://www.linuxso.com/linuxrumen/8637.html
总结三、参数
mtime 文件内容最后一次被修改的时间
-ctime 文件的i节点最后一次被修改的时间(例如修改文件的权限属主等信息会影响到ctime)
-atime 文件内容的最后访问时间,例如(cat filename >/dev/null 会影响到文件filename的atime,ls则不会,ls会影响所查看目录的atime,因为它访问了目录文件的内容)
-------------------------------------------
N
每个N代表一天24小时,
N=0:less than 24 hours ago (见 `info find` ->Finding Files::->Time::->Age Ranges::)
N=1:between 24 and 48 hours ago
N=2:between 48 and 72 hours ago
...
+N|N|-N
当N=1时,来画个时间轴
现在是20070423/21:28
+N表示 当前时间起 (N*24+24)小时这个时间点之前
-N表示 当前时间向前(N*24)小时 至 当前时间
所以做为特例,-Xtime -1 与-Xtime 0 结果是一致的。
-------------------------------------
测试方法
先date命令看一下当前时间,再
touch -d "YYYYMMDD mm:ss" filename
touch 几个不同时间点的文件,然后分别
find -mtime {+N|N|-N}
看看结果就知道了
-------------------------------------
under KUbuntu6.06 LTS
很郁闷的是--我的时间轴三行总是不好对齐~编辑的时候很齐哇
20070514更新:把那个对不齐的时间轴换成图片了 :)
find参数mtime与ctime划分每天的时间界限是几点?
我每次用mtime或ctime来find一些文件时,
总是发现在临界的那天,
中午12点前的文件,可以被find,
中午12点后的文件,就无法find出来
是不是mtime与ctime将一天的区别定在中午12点啊?
也就是我要查10月5日的所有文件,结果10月5日的文件12点之前产生的文件都能找到,而12点之后的却没有办法找到
请问 -ctime 和 -mtime 有什么关系 ?
如果父目录的 ctime 改变, 那它下面的文件的 ctime 就会自动都改了吗 ?
-ctime 和 -mtime ,-atime 这些信息是存在哪儿呢 ?
多谢!
玉兰油 回复于:2002-08-20 16:38:22 我也想知道。
lyq01 回复于:2002-08-20 17:27:08 我用 -mtime -1 找到了新建或改的文件.
但怎样才能找到一天内 mv 来的文件呢( 它们的时间是原有的时间,早于一天 ) ?
玉兰油 回复于:2002-08-21 08:20:03 用-newer选项啊。
你可以先touch一个你想要的时间的文件如下:
$ touch -t 08190800 test
$ ls -l test
-rw-r--r-- 1 dba other 0 Aug 19 08:00 test
然后
$ find . -newer test -print
.
./.sh_history
$ ls -l .sh_history
-rw------- 1 dba other 154 Aug 20 17:39 .sh_history
用touch可以写出你想要的任何时间的文件,然后用-newer ,! -newer选项即可成功。
valentine 回复于:2002-08-21 09:14:10 1.ctime含inode信息修改的时间.mtime只指文件内容建立或修改的时间.
2 不会.
3.这些信息应该是存在文件系统的超级块里.
lyq01 回复于:2002-08-21 11:11:45 我查了书 -ctime 是指 inode 的改变(或称文件的状态改变).
请问 inode 存了哪些信息 ?
做了些小测试,-mtime 改, -ctime 一定也改.
改文件名, -ctime 也会改.
谁能回答 i-node 存了哪些东西 ?
valentine 回复于:2002-08-21 11:26:41 vi /usr/include/sys/inode.h
lyq01 回复于:2002-08-21 16:24:07 班主,我不能 access /usr/include/sys/inode.h .
摘书如下:
Directories contain directory entries. Each entry contains a file or subdirectory name and an index node reference number (i-node number). To increase speed and enhance use of disk space, the da
可我发现 -atime 改了, -ctime 还没改. why ?
( 我先 cat 一个 ASCII 文件,再用 -atime -1 有它用 -ctime -1 居然没有它.)
着岂不跟 inode 信息改变, ctime 就改矛盾吗?
valentine 回复于:2002-08-21 17:07:59 我不同意你贴出来的那段文章,正如我提到的那样,atime,ctime,mtime是放到超级块里,在sco unix下是一种叫stat的结构.(stat_32),不同的系统文件系统可能不同.
sco 下inode的结构如下:
typedef struct inode
{
struct inode *i_forw; /* inode hash chain */
struct inode *i_back; /* '' */
struct inode *av_forw; /* freelist chain */
struct inode *av_back; /* '' */
int *i_fsptr; /* "typeless" pointer to fs dependent */
ino32_t i_number; /* i number, 1-to-1 with dev address */
ushort i_ftype; /* file type = IFDIR, IFREG, etc. */
short i_fstyp; /* File system type */
off_t i_size; /* size of file */
ushort i_uid; /* owner */
ushort i_gid; /* group of owner */
ushort i_flag;
ushort i_want; /* i_flag extension to avoid MP races */
ushort i_count; /* reference count */
short i_nlink; /* directory entries */
dev_t i_rdev; /* Raw device number */
#define i_namtype i_rdev /* i_ftype==IFNAM subtype */
dev_t i_dev; /* device where inode resides */
struct mount *i_mton;/* ptr to mount table entry that */
/* this directory is mounted on */
struct region *i_rp; /* ptr to shared region if any */
struct stdata *i_sp; /* ptr to associated stream */
struct iisem *isem; /* ptr to XENIX semaphores */
struct iisd *isd; /* ptr to XENIX shared da
} i_un;
#define i_mnton i_un.i_mton /* i_ftype==IFDIR IMOUNT */
#define i_rptr i_un.i_rp /* i_ftype==IFREG || i_ftype==IFBLK */
#define i_sptr i_un.i_sp /* i_ftype==IFCHR || i_ftype==IFIFO */
#define i_sem i_un.isem /* i_ftype==IFNAM && i_namtype==IFSEM */
#define i_sd i_un.isd /* i_ftype==IFNAM && i_namtype==IFSHD */
struct fstypsw *i_fstypp; /* ptr to file system switch FSPTR */
long *i_filocks; /* pointer to filock (structure) list */
unsigned long i_mappages; /* number of pages currently cached */
unsigned long i_vcode; /* read-ahead block save (NFS) */
short i_wcnt; /* write open count or ITEXT count */
struct lockb i_cilock; /* tas to synchronize i_flag changes */
ushort i_rdlocks; /* count of non-exclusive lockers */
} inode_t;
所以,访问一个文件不能改变inode信息.
使用chown, chgrp, chmod命令可以很好的比较mtime和ctime
chown改变一个文件的属主,用ctime可以找到,用mtime便找不到.
试试看.
lyq01 回复于:2002-08-21 19:32:38 多谢斑竹! 我是在 Solaris 上面试的.我是对 -ctime 不明白.
试的结果如下:
修改文件,-mtime 改了, -ctime 也会改.
访问文件,-atime 改了, -ctime 没变.
chown, chgrp, chmod,mv, 都会使 -ctime 改变,但不影响 -atime 和 -mtime.
touch 可以改 -mtime and/or -atime,但 touch -a 只改访问时间时,-ctime也改了.
touch -m 改修改时间时,-ctime当然也改了.
好象还有别的很多东西可以令 -ctime 改变, 搞不清楚.
有什么方法可以显示 -mtime,atime,ctime 吗?
可以用 -ctime 来实现对目录的增量文件进行备份或 transfer 吗 ?
多谢!
valentine 回复于:2002-08-21 20:35:22 [这个贴子最后由valentine在 2002/08/22 02:02pm 编辑]
没有什么工具显示,(可能是俺不知道)
把下面程序里的st_mtime换成st_ctime,或st_atime便可以得到你要的了.
#include <sys/stat.h>
int
main (int argc, char **argv)
{
struct stat buf;
char date[80];
char fname[80];
printf("Enter filename (with full path) to check mtime : ");
scanf("%s",fname);
stat(fname, &buf);
printf ("mtime (in sec) of %s = %ld\n", fname, buf.st_mtime);
strcpy(date, ctime((time_t *)&(buf.st_mtime)));
printf ("mtime (in date) of %s = %s\n", fname, date);
}
至于文件备份,有什么不可以的么?
ahyan 回复于:2002-08-22 12:34:37 mtime ls -l 最近修改文件内容的时间
atime ls -lu 最近访问文件的时间
ctime ls -li 最近文件有所改变的状态 ,如文件修改,属性\属主 改变 ,节点 ,链接变化等 ,应该是不拘泥只是时间前后的改变
valentine 回复于:2002-08-22 14:05:47 俺看了ls的帮助,以为只是按ctime或atime排序,显示的时间还是mtime.
仔细比较了一下,ayhan说的是对的.谢谢ayhan.
lyq01 回复于:2002-08-22 14:14:27 多谢 ahyan 提示 ! 我在 Solaris 上试过如下:
mtime 用 ls -l 看到
atime 用 ls -lu 看到
ctime 用 ls -lc 看到. (ls -li 只有 inode number)
摘书如下:
-c Uses time of last modification of the i-node (file
created, mode changed, and so forth) for sorting (-t)
or printing (-l or -n).
-u Uses time of last access instead of last modification
for sorting (with the -t option) or printing (with the
-l option).
-i For each file, prints the i-node number in the first
column of the report.
wws75111 回复于:2002-08-26 13:13:21 我在sco unix5.0.5中试了一下,好像不对:chmod,chgrp等不会改变ls -il显示的时间;vi,touch倒是有影响。做何解?
ificanfly 回复于:2004-11-14 09:29:09 所有文件都有3个时间信息,保存在文件系统中
atime是文件最后一此读的时间
mtime是文件最后一次写的时间
ctime是i-node信息最后一次写的时间.
find -atime -ctime -mtime区别
atime、mtime与ctime的区别
access time , atime在读取文件或执行文件时会修改
create time , ctime在文件写入,更改所有者,权限。链接时文件的ctime会随之改变
modified time ,mtime 在文件写入时会改变。
ls -lu 或者 ls -l --time=atime 显示文件的atime
ls -lc 或者 ls -l --time=ctime 显示文件的ctime
ls -l 显示文件的mtime
[root@station206 test]# touch test.txt
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 0 Blocks: 8 IO Block: 4096 regular
empty file
Device: fd00h/64768d Inode: 1179651 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:46:26.000000000 +0800 ## atime
Modify: 2009-05-21 01:46:26.000000000 +0800 ## mtime
Change: 2009-05-21 01:46:26.000000000 +0800 ## ctime
[root@station206 test]# more test.txt ## 访问文件
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 0 Blocks: 8 IO Block: 4096 regular
empty file
Device: fd00h/64768d Inode: 1179651 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:47:21.000000000 +0800 ## atime有变法了
Modify: 2009-05-21 01:46:26.000000000 +0800
Change: 2009-05-21 01:46:26.000000000 +0800
[root@station206 test]# echo asdf > test.txt ## 添加内容
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 5 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179651 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:47:21.000000000 +0800 ## atime没有变法
,疑问?
Modify: 2009-05-21 01:48:14.000000000 +0800 ## mtime有变法
Change: 2009-05-21 01:48:14.000000000 +0800 ## ctime有变法
[root@station206 test]# chmod a+x test.txt ## 修改属性
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 5 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179651 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:47:21.000000000 +0800 ## atime没有变
法
Modify: 2009-05-21 01:48:14.000000000 +0800 ## mtime没有变
法
Change: 2009-05-21 01:49:39.000000000 +0800 ## ctime有变法
[root@station206 test]# vim test.txt ## 编辑文件
[root@station206 test]# stat test.txt
File: `test.txt'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:50:55.000000000 +0800
Modify: 2009-05-21 01:50:55.000000000 +0800
Change: 2009-05-21 01:50:55.000000000 +0800 ## 都发生变法
[root@station206 test]# mv test.txt test.txt2
[root@station206 test]# stat test.txt
stat: cannot stat `test.txt': No such file or directory
[root@station206 test]# stat test.txt2
File: `test.txt2'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2009-05-21 01:50:55.000000000 +0800
Modify: 2009-05-21 01:50:55.000000000 +0800
Change: 2009-05-21 01:51:52.000000000 +0800 ##只有ctime发
生变法
atime 访问时间(access time):访问时间是文件最后一次被读取的时间。因此
阅读一个文件会更新它的访问时间,而它的改变时间并没有变化(有关文件状态
的信息没有被改变),它的修改时间也同样没有变化(文件内容本身没有被改变)
;
mtime 修改时间(modification time):文件内容最后被修改的时间。
ctime 改变时间(change time):文件状态(status)最后被改变的时间。
[root@station206 test]# touch -at 200701010000 test.txt2
[root@station206 test]# stat test.txt2
File: `test.txt2'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2007-01-01 00:00:00.000000000 +0800
Modify: 2009-05-21 01:50:55.000000000 +0800
Change: 2009-05-21 01:53:57.000000000 +0800
[root@station206 test]# touch -mt 200701010000 test.txt2
[root@station206 test]# stat test.txt2
File: `test.txt2'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2007-01-01 00:00:00.000000000 +0800
Modify: 2007-01-01 00:00:00.000000000 +0800
Change: 2009-05-21 01:54:07.000000000 +0800
[root@station206 test]# touch -ct 200701010000 test.txt2
[root@station206 test]# stat test.txt2
File: `test.txt2'
Size: 12 Blocks: 16 IO Block: 4096 regular
file
Device: fd00h/64768d Inode: 1179653 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/
root)
Access: 2007-01-01 00:00:00.000000000 +0800
Modify: 2007-01-01 00:00:00.000000000 +0800
Change: 2009-05-21 01:54:12.000000000 +0800
## touch改不了ctime?可能只能修改系统时间才能修改ctime了。
关于find命令中-perm中+- 的含义
举个例子:比如当前目录下有a b c d4个文件
a文件的权限为6000 也就是a文件仅有suid sgid的特殊权限
b文件的权限为2000 也就是b文件仅有sgid的特殊权限
c文件的权限为4000 也就是c文件仅有suid的特殊权限
d文件的权限为6600 也就是d文件有sgid suid的特殊权限并且该文件拥有者对该文件有读写权限
那么现在find . -type f -perm 6000 可以找到a文件,因为a文件权限为6000
那么现在find . -type f -perm -6000 可以找到a d两个文件,这是因为:
我们可以先将a b c d这4个文件的权限转化为2进制那么,
a权限转为2进制后为 110 000 000 000
b权限转为2进制后为 010 000 000 000
c权限转为2进制后为 100 000 000 000
d权限转为2进制后为 110 110 000 000
在find . -type f -perm -6000 中的6000权限转为2进制为110 000 000 000,那么6000前的-号代表缺一不可,也就是如果有1的地方必须有1,那么这里找-6000权限的文件,这6000权限里前面有2个位置都是1,所以这里find找-6000权限的文件就是找前面2个位置都是1的文件.而只有a d这两个文件前2个位置都是1,所以find . -type f -perm -6000 只会找到a d两个文件.
find . -type f -perm +6000会找到a b c d这4个文件,这是因为:
+6000里的这个+号代表有1即可,也就是有1的位置只要有1就可以.那么这里找+6000权限的文件,这6000权限前面2个位置都有1,所以这里find找+6000权限的文件就是找前面2个位置只要有一个位置有1的文件就可以了,这4个文件都符合要求所以最后都能被 find . -type f -perm +6000找到
一天一点学习Linux之文件查找/搜索
在Linux文件系统中,搜索概念有两种,一种是搜索文件名,另一种是在一个文件中搜索指定的内容。文件的查找,在操作系统的使用中,是一个非常重要的功能,所以,今天我们就来学习研究他了。
一、文件的搜索
(一)命令的查找
我们在前面的内容中,讲到PATH变量,这里面写了一些命令的所在位置,而且我们常用的TAB键补全功能,也会在这些目录里面来查找相关的命令。但某个命令具体在哪个位置,我们可能还不知道,如果想找到他的具体位置的话,那么可以通过查找来发现他。
查找命令文件 which
此命令会在环境变量PATH设置的目录里面查找内容。
这里面有个-a参数,他将所有从PATH变量的目录中找到的命令全部列出,而不只列出第一个被找到的命令名称。
在RHEL6系统中,你可以随便cp一个命令到用户的家目录的bin(自己建立)目录里面,然后用which和which -a来查找一下看看,你就会明白-a参数的意义了。
注:which后面跟的是要查找的命令全名,不能用通配符。
如果你想用which来查找cd命令,你会发现找不到cd命令,
[root@yufei ~]# which cd
/usr/bin/which: no cd in (/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)
这是为什么呢?系统中不存在这个命令,为什么我能使用此命令呢?其实这个cd命令不是放在系统的PATH中的,而是集成在shell中了。当然找不到,不过,你也可以通过type命令来查看
[root@yufei ~]# type cd
cd is a shell builtin
这个type也是shell中的命令
type命令其实不能算查找命令,它是用来区分某个命令到底是由shell自带的,还是由shell外部的独立二进制文件提供的。如果一个命令是外部命令,那么使用-p参数,会显示该命令的路径,相当于which命令。
(二)普通文件的查找
在Linux系统上的文件查找命令find,绝对不亚于windows系统上的查找,但find不足的地方就是速度比较慢,而且要大量读取硬盘内容。其实,在平时使用的时候,我们常用的命令并不是find,而是whereis或locate,因为他们是通过查找数据库里面的数据来查找文件的,这速度就会变的很快了,但这两个文件不一定能找到我们想要的内容,特别是一些新建议的文件,因为数据库还没有储存相应的信息。怎么办,没有关系,这个数据库除了定时更新外,我们还可以手动对其更新(updatedb)。好了,下面我们就来具体看看他们三个命令的用法。
whereis会在数据库中查找二进制,源代码文件和帮助手册文件
-s 只查找原始代码文件。
-S<目录> 只在设置的目录下查找原始代码文件。
-b 只查找二进制文件。
-B<目录> 只在设置的目录下查找二进制文件。
-m 只查找说明文件。
-M<目录> 只在设置的目录下查找说明文件。
如果省略参数,则返回所有信息。
locate也是在数据库中查找文件,不限制是什么文件
-i 忽略大小写
如果这个命令后面跟上文件名(字符)的话,那么这个命令执行的时候,会把系统中所有包含此字符的文件全部列出来。这个后面的名字就相当于关键字一样。
[root@yufei ~]# locate log
会列出很多内容出来
这个命令可以使用通配符,但在使用的时候要用”\”来处理一下,否则就查询当前的目录了
[root@yufei ~]# pwd
/root
[root@yufei ~]# locate *.log
/root/install.log
/root/install.log.bak
/root/install.log.syslog
/root/Desktop/install.log
/root/Desktop/install.log.syslog
上面的命令把当前目录(/root)里面所有包涵.log的文件全部找出来,无论是不是以.log结尾
[root@yufei ~]# locate \*.log
这个显示的内容比较多,他把系统中所有以.log结尾的文件全部找出来了。
虽然只是多了一个反斜杠,结果确明显不同
如果说,你要用”?”这个通配符,那么就要用-b这个参数了。当然上面的也可以用-b参数
[root@yufei ~]# locate -b \????.log
/var/log/boot.log
/var/spool/plymouth/boot.log
为了方便大家的记忆,建议大家在使用通配符号的时候,统一用-b这个参数。而且可以把反斜杠换成”””
如
locate -b ‘????.log’
locate -b ‘*.log’
这样可以和后面的find命令统一起来,省得大家搞混淆了。
更多的关于单引号与双引号的区别,请参考shell中单引号、双引号、反引号、反斜杠的使用
以上两个命令都是通过/var/lib/mlocate/mlocate.db这个数据库来查询内容的,所以,为了得到更准确的查找结果的话,在每次命令以上两个命令的时候,先执行updatedb命令,这样就不会把刚刚删除的文件再找出来,也不会找不到刚刚新建的文件了。
find 是最常见和最强大的查找命令,你可以用它找到任何你想找的文件。
语法格式如下
find <指定目录> <指定条件> <指定动作>
一般的参数
-name filename 按照文件名查找文件
-size [+-]SIZE 找比SIZE还要大(+)或小(-)的文件。这个SIZE的格式有:
c: 代表 byte,k: 代表 1024bytes。
所以,要找比50KB还要大的文件,就是用-size +50k
-type 查找某一类型的文件(b、d、c、p、l等等文件类型)
-newer file :file为一个存在的档案,列出比file文件还要新的文件
-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找
-prune 使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略
权限相关的参数
-perm mode 查找权限为mode(数字表示的权限)的文件
-perm -mode 查找权限全部包括mode(数字表示的权限)的文件。找到的文件权限比参考权限(mode)要大
-perm +mode 查找包含任一mode(数字表示的权限)的文件.找到的文件权限比参考权限(mode)要小
用户和组相关的参数
-user username :按照文件所有者来查找文件
-uid n :按照文件所有者的UID来查找文件
-group groupname :按照文件所属的组来查找文件
-gid n :按照文件所属组的GID来查找文件
-nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在
-nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在
和时间相关的参数
共有 -atime, -ctime 与 -mtime ,以-mtime说明,其他两个也一样
-mtime n :n为数字,意义为在n天之前(n当天)被更动过内容的文件
-mtime +n :列出在n天之前(不含n天本身)被更动过内容的文件名
-mtime -n :列出在n天之内(含n天本身)被更动过内容的文件名
-n表示文件更改时间距现在n天以内
+n表示文件更改时间距现在n天以前
n表示文件更改的当天
可以看下图,更好的帮助大家来理解
如将系统上面24小时内有更动过内容(mtime)的文件列出
find / -mtime 0
那个0是重点,0代表目前的时间,所以,从现在开始到 24 小时前。
后续的动作参数
-exec command :command为其他指令,-exec后面可再接额外的命令来处理查找到的结果。
exec选项后面的格式:所要执行的命令或脚本+一对”{}”+”一个空格”+一个”\”+一个分号”;”。
最后的样式:-exec command {} \;
注:
1、{} 代表的是由find找到的内容,结果会被放置到{}中
2、-exec一直到\;是关键词。代表find额外动作的开始(-exec)到结束(\;),在这中间的就是find指令内的额外动作
3、因为”;”在bash环境下是有特殊意义,因此利用反斜杠来转义
下面看几个例子
1、查找/etc目录下的所有文件,并用ls -l把他们列出来
[root@yufei ~]# find /etc/ -type f -exec ls -l {} \;
2、在/var/log/目录中查找更改时间在5日以前的文件并删除它们
[root@yufei ~]# find /var/log/ -type f -mtime +5 -exec rm {} \;
如果你要进行这项操作的话,为了安全,建议先用ls再用rm,如果你确认没有问题的话,当然完全没有问题,用什么命令都可以。当然,也有一个确认的功能,下面就来看看这个-ok
3、在/var/log/目录中查找所有以.log结尾的文件名、更改时间在5日以上的,并删除它们,但在删除之前先给出提示。
[root@yufei ~]# find /var/log/ -name ‘*.log’ -mtime +5 -ok rm {} \;
这时候,如果找到了符合的文件,就会给出删除提示,按y键删除文件,按n键不删除。
4、查找所有的passwd文件,看看在这些文件中是否存在一个某个用户
[root@yufei ~]# find /etc -name “passwd*” -exec grep “yufei” {} \;
5、找出/etc底下,文件大小介于50K 到 60K 之间的文件,并将权限完整的列出
[root@yufei ~]# find /etc -size +50k -a -size -60k -exec ls -l {} \;
那个 -a 是 and的意思,为符合两者才符合
6、找出 /etc 底下,容量大于1500K 以及容量等于0的文件
[root@yufei ~]# find /etc -size +1500k -o -size 0
相对于-a ,那个 -o 就是或 (or)的意思
xargs
在使用find命令的-exec选项处理匹配到的文件时,find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是”参数列太长”或”参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。
看几个例子
1、查找/tmp目录下,名字为core的文件,并将其删除
[root@yufei ~]# find /tmp -name core -type f -print | xargs /bin/rm -f
2、在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限
[root@yufei ~]# find . -perm -7 -print | xargs chmod o-w
3、用grep命令在所有的普通文件中搜索hostname这个词
[root@yufei ~]# find / -type f -print | xargs grep “hostname”
[root@yufei ~]# find / -name \* -type f -print | xargs grep “hostnames”
其实这两个命令是一样的意思。和前面我们讲的一样,反斜杠”\”用来取消find命令中的*在shell中的特殊含义。
通过上面的一些例子,find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。而且在find的帮助文件中也有相应的帮助说明。大家可以参考学习。
二、在文件中搜索关键词
grep (global search regular RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
由于正则表达式我们还没有学习,在这里只做简单的介绍几个例子,来让大家了解一下grep。
1、在/etc/passwd中查找yufei用户的相关信息
[root@yufei ~]# grep yufei /etc/passwd
yufei:x:500:500:yufei:/home/yufei:/bin/bash
2、查看系统日志/var/log/message文件,并查找2月12号的日志内容
[root@yufei ~]# cat /var/log/messages |grep ‘Feb 12′ |more
这个例子我们用到了管理符号,翻页命令
通过上面讲解,你会发现在Linux系统上的查找,不亚于图形界面的windows系统吧,是不是越来越喜欢Linux系统了。今天的内容,重在实践,通过实践加深理解,在实践中解决问题。
本文关键字:一天一点,学习Linux,RHEL6,find,which,whereis,locate,文件查找
-----------------------------------------------------------------------------------------------------
簡單的比較說明: 【which】通常都是用來尋找『執行檔』 【whereis】通常是用來尋找『特定檔案』 【whersis】和【locate】搜尋時是以資料庫檔案裡的資料為主 【find】搜尋時是以整個硬碟裡的資料為主 在Linux下,find這個指令不常用到,因為不僅速度慢也很操硬碟。所以通常都是先使用whereis或是locate來檢查,最後真的找不到的話,才會使用到find來搜尋。 Whereis和locate是利用資料庫來搜尋資料,並非實際搜尋硬碟。因此在找資料上的速度相當快速,也較省時間。 以下是各指令的說明 which 這個指令是根據『PATH』這個環境變數所規範的路徑,去搜尋『執行檔』的檔名,而且which後面接的是『完整檔名』。若加上 -a 選項,則可以列出所有的可以找到的同名執行檔,而非僅顯示第一個! [root@www ~]# which [-a] command 選項或參數: -a :將所有由 PATH 目錄中可以找到的指令均列出,而不止第一個被找到的指令名稱 範例一:分別用root與一般帳號搜尋 ifconfig 這個指令的完整檔名 [root@www ~]# which ifconfig /sbin/ifconfig<==用 root 可以找到正確的執行檔名喔! [root@www ~]# su – derek<==切換身份成為 derek 去! [derek@www ~]$ which ifconfig /usr/bin/which: no ifconfig in (/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin :/home/derek/bin)<==竟然一般身份帳號找不到! # 因為 which 是根據使用者所設定的 PATH 變數內的目錄去搜尋可執行檔的! # 不同的 PATH 設定內容所找到的指令當然不一樣啦!因為 /sbin 不在 derek 的 # PATH 中,找不到也是理所當然的啊!瞭乎? whereis 為什麼whereis的搜尋速度會比find快這麼多呢? 因為Linux 會將系統內所有的檔案都記錄在一個資料庫檔案裡面,當要使用whereis和locate時,就會先以此資料庫檔案的內容為準。有時在使用這兩個執行檔的時後,會找到已經被殺掉的檔案。也有時後會找不到剛剛所建立的最新檔案,因為還沒有被記錄到此資料庫檔案中。 [root@www ~]# whereis [-bmsu] 檔案或目錄名 選項與參數: -b:只找可執行檔( binary )格式的檔案 -m:只找在說明檔 manual 路徑下的檔案 -s:只找 source 來源檔案 -u:搜尋不在上述三個項目當中的其他特殊檔案 如果不加任何選項的話,那麼就將所有的資料列出來囉! 範例一:請用不同的身份找出 ifconfig 這個檔名 [root@www ~]# whereis ifconfig ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz [root@www ~]# su – derek<==切換身份成為 derek [derek@www ~]$ whereis ifconfig<==找到同樣的結果喔! ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz [derek@www ~]$ exit<==回歸身份成為 root 去! # 注意看,明明 which 一般使用者找不到的 ifconfig 卻可以讓 whereis 找到! # 這是因為系統真的有 ifconfig 這個『檔案』,但是使用者的 PATH 並沒有加入 /sbin # 所以,未來你找不到某些指令時,先用檔案搜尋指令找找看再說! Locate 這個 locate 的使用更簡單,直接在後面輸入『檔案的部分名稱』後,就能夠得到結果。但是,在使用上還是會有一些限制的。因為他是經由資料庫來搜尋的,而資料庫的建立預設是在每天執行一次 (每個distribution 都不同,CentOS 5.x 是每天更新資料庫一次!) 所以當你新建立起來的檔案,卻還在資料庫更新之前搜尋該檔案,那麼 locate 會告訴你『找不到!』因此必須要更新資料庫。 那如何手動更新資料庫呢?更新 locate 資料庫的方法非常簡單,直接輸入『 updatedb 』就可以了!updatedb指令會去讀取 /etc/updatedb.conf 這個設定檔的設定,然後再去硬碟裡面進行搜尋檔名的動作,最後就更新整個資料庫檔案囉!因為 updatedb 會去搜尋硬碟,所以當你執行updatedb 時,可能會等待數分鐘的時間喔! updatedb:根據 /etc/updatedb.conf 的設定去搜尋系統硬碟內的檔名, 並更新 /var/lib/mlocate 內的資料庫檔案; locate:依據 /var/lib/mlocate 內的資料庫記載,找出使用者輸入的關鍵字檔名。 你會發現使用 locate 來尋找資料的時候特別的快,這是因為 locate 尋找的資料是由『已建立的資料庫 /var/lib/mlocate/』 裡面的資料所搜尋到的,所以不用直接在去硬碟當中存取資料! [root@www ~]# locate [-ir] keyword 選項與參數: -i:忽略大小寫的差異; -r:後面可接正規表示法的顯示方式 Find find是直接從硬碟做查詢的動作,在查詢的方式有很多種。以下就是一些範例參考。 時間參數 [root@www ~]# find [PATH] [option] [action] 選項與參數: 1. 與時間有關的選項:共有 -atime, -ctime 與 -mtime ,以 -mtime 說明 -mtimen :n 為數字,意義為在n 天之前的『一天之內』被更動過內容的檔案; -mtime +n :列出在 n 天之前(不含 n 天本身)被更動過內容的檔案檔名; -mtime -n :列出在 n 天之內(含 n 天本身)被更動過內容的檔案檔名。 -newer file :file 為一個存在的檔案,列出比 file 還要新的檔案檔名 範例一:將過去系統上面 24 小時內有更動過內容 (mtime) 的檔案列出 [root@www ~]# find / -mtime 0 # 那個 0 是重點!0 代表目前的時間,所以,從現在開始到 24 小時前, # 有變動過內容的檔案都會被列出來!那如果是三天前的 24 小時內? # find / -mtime 3 有變動過的檔案都被列出的意思! 範例二:尋找 /etc 底下的檔案,如果檔案日期比 /etc/passwd 新就列出 [root@www ~]# find /etc -newer /etc/passwd # -newer 用在分辨兩個檔案之間的新舊關係是很有用的! 現在知道 atime, ctime 與 mtime 的意義 如果要找出一天內被更動過的檔案名稱,可以使用上述範例一的作法。 如果要找出『4天內被更動過的檔案檔名』那就可以使用『find /var -mtime -4』。 那如果是『4天前的那一天』就用『find /var -mtime 4』。 有沒有加上『+, -』差別很大喔!可以用簡單的圖示來說明一下: 圖中最右邊為目前的時間,越往左邊則代表越早之前的時間軸啦。由上圖可以清楚的知道: +4代表大於等於5天前的檔名:ex> find /var -mtime +4 -4代表小於等於4天內的檔案檔名:ex> find /var -mtime -4 4則是代表4-5那一天的檔案檔名:ex> find /var -mtime 4 使用者或群組名稱的參數 若想找出某個使用者在系統底下建立了什麼,可參考下列的選項與參數 選項與參數: 2. 與使用者或群組名稱有關的參數: -uid n :n 為數字,這個數字是使用者的帳號 ID,亦即 UID ,這個 UID 是記錄在 /etc/passwd 裡面與帳號名稱對應的數字。這方面我們會在第四篇介紹。 -gid n :n 為數字,這個數字是群組名稱的 ID,亦即 GID,這個 GID 記錄在 /etc/group,相關的介紹我們會第四篇說明~ -user name :name 為使用者帳號名稱喔!例如 dmtsai -group name:name 為群組名稱喔,例如 users ; -nouser:尋找檔案的擁有者不存在 /etc/passwd 的人! -nogroup:尋找檔案的擁有群組不存在於 /etc/group 的檔案! 當你自行安裝軟體時,很可能該軟體的屬性當中並沒有檔案擁有者, 這是可能的!在這個時候,就可以使用 -nouser 與 -nogroup 搜尋。 範例三:搜尋 /home 底下屬於 derek 的檔案 [root@www ~]# find /home -user derek # 這個東西也很有用的~當我們要找出任何一個使用者在系統當中的所有檔案時, # 就可以利用這個指令將屬於某個使用者的所有檔案都找出來喔! 範例四:搜尋系統中不屬於任何人的檔案 [root@www ~]# find / -nouser # 透過這個指令,可以輕易的就找出那些不太正常的檔案。 # 如果有找到不屬於系統任何人的檔案時,不要太緊張, # 那有時候是正常的~尤其是你曾經以原始碼自行編譯軟體時。 參數中的-nouser 或 -nogroup 的選項功能中,除了自行從網路上下載檔案時會發生之外,如果將系統內某個帳號刪除,但是該帳號已經在系統內建立很多檔案時,就可能會發生檔案存在但是擁有者或擁有群組不存在的情況!這個時後就可使用 -nouser 來找出該類型的檔案! 檔案權限及名稱的參數 選項與參數: 3. 與檔案權限及名稱有關的參數: -name filename:搜尋檔案名稱為 filename 的檔案; -size [+-]SIZE:搜尋比 SIZE 還要大(+)或小(-)的檔案。這個 SIZE 的規格有: c: 代表 byte, k: 代表 1024bytes。所以,要找比 50KB 還要大的檔案,就是『 -size +50k 』 -type TYPE:搜尋檔案的類型為 TYPE 的,類型主要有:一般正規檔案 (f), 裝置檔案 (b, c), 目錄 (d), 連結檔 (l), socket (s), 及 FIFO (p) 等屬性。 -perm mode:搜尋檔案權限『剛好等於』 mode 的檔案,這個 mode 為類似 chmod 的屬性值,舉例來說, -rwsr-xr-x 的屬性為 4755 ! -perm -mode :搜尋檔案權限『必須要全部囊括 mode 的權限』的檔案,舉例來說, 我們要搜尋 -rwxr–r– ,亦即 0744 的檔案,使用 -perm -0744, 當一個檔案的權限為 -rwsr-xr-x ,亦即 4755 時,也會被列出來, 因為 -rwsr-xr-x 的屬性已經囊括了 -rwxr–r– 的屬性了。 -perm +mode :搜尋檔案權限『包含任一 mode 的權限』的檔案,舉例來說,我們搜尋 -rwxr-xr-x ,亦即 -perm +755 時,但一個檔案屬性為 -rw——- 也會被列出來,因為他有 -rw…. 的屬性存在! -perm 這個參數,重點在找出特殊權限的檔案 範例五:找出檔名為 passwd 這個檔案 [root@www ~]# find / -name passwd # 利用這個 -name 可以搜尋檔名啊! 範例六:找出 /var 目錄下,檔案類型為 Socket 的檔名有哪些? [root@www ~]# find /var -type s # 這個 -type 的屬性也很有幫助喔!尤其是要找出那些怪異的檔案, # 例如 socket 與 FIFO 檔案,可以用 find /var -type p 或 -type s 來找! 範例七:搜尋檔案當中含有 SGID 或 SUID 或 SBIT 的屬性 [root@www ~]# find / -perm +7000 # 所謂的 7000 就是 —s–s–t ,那麼只要含有 s 或 t 的就列出, # 所以當然要使用 +7000 ,使用 -7000 表示要含有 —s–s–t 的所有三個權限, # 因此,就是 +7000 我們知道 SUID 與 SGID 都可以設定在二進位程式上,假設想要找出來 /bin, /sbin 這兩個目錄下,只要具有 SUID 或 SGID 就列出來該檔案,可以這樣做。 [root@www ~]# find /bin /sbin -perm +6000 因為 SUID 是 4 分,SGID 2 分,總共為 6 分,因此可用 +6000 來處理這個權限!至於 find 後面可以接多個目錄來進行搜尋!另外,find 本來就會搜尋次目錄,這個特色也要特別注意 額外可進行的動作 選項與參數: 4. 額外可進行的動作: -exec command :command 為其他指令,-exec 後面可再接額外的指令來處理搜尋到 的結果。 -print:將結果列印到螢幕上,這個動作是預設動作! 範例八:將上個範例找到的檔案使用 ls -l 列出來~ [root@www ~]# find / -perm +7000 -exec ls -l {} \; # 注意到,那個 -exec 後面的 ls -l 就是額外的指令,指令不支援命令別名, # 所以僅能使用 ls -l 不可以使用 ll 喔!注意注意! 範例九:找出系統中,大於 1MB 的檔案 [root@www ~]# find / -size +1000k # 雖然在 man page 提到可以使用 M 與 G 分別代表 MB 與 GB, find 的特殊功能就是能夠進行額外的動作(action)。將範例八的例子以圖解來說明如下: 該範例中特殊的地方有 {} 以及 \; 還有 -exec 這個關鍵字,這些東西的意義為: {} 代表的是『由 find 找到的內容』,如上圖所示,find 的結果會被放置到 {} 位置中; -exec 一直到 \; 是關鍵字,代表 find 額外動作的開始 (-exec) 到結束 (\;) ,在這中間的就是 find 指令內的額外動作。 在本例中就是『 ls -l {} 』囉! 因為『 ; 』在 bash 環境下是有特殊意義的,因此利用反斜線來跳脫。 如果你要找的檔案是具有特殊屬性的,例如 SUID 、檔案擁有者、檔案大小等等,那麼利用 locate 是沒有辦法達成你的搜尋的!此時 find 就顯的很重要!另外,find 還可以利用萬用字元來找尋檔名呢! 舉例來說,你想要找出 /etc 底下檔名包含 httpd 的檔案,那麼你就可以這樣做: [root@www ~]# find /etc -name '*httpd*' 不但可以指定搜尋的目錄(連同次目錄),並且可以利用額外的選項與參數來找到最正確的檔名!真是好好用!不過由於 find 在尋找資料的時後相當的操硬碟!所以沒事情不要使用find !有更棒的指令可以取代呦!那就是上面提到的whereis與locate!