Linux的权限和所有权模型(转帖)

转载者前言:

本来这些内容在linux的在线man文档或info文档中都有非常详细的解释,无奈英文不行,还是不能全面理解linux的权限系统,只好上网查了一下,收集到一篇比较完整的介绍转帖于此。其中的内容涉及:一般w,r,x标志位控制,特殊的suid,sgid,t标志位控制,umask控制;

linux的权限系统是使用linux的重要基础,如果不能对其所有权模型有比较透彻的理解,就会对正确理解和使用系统中的一些东西造成障碍,比如我碰到的:删除linux的/tmp目录引起的不能正常登录系统的故障: http://java.learndiary.com/diaries/3112.jsp

另外,对权限系统目前还有如下的疑问

1)、大写“X”标志位是做什么用的?

2)、passwd程序怎样控制用户只访问/etc/passwd文件中用户能够访问的部分?

转帖正文:

******************************************************************************

转自:Linux的权限和所有权模型:http://linux.chinaitlab.com/safe/38178.html

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  一个用户、一个组

  

  我们来看一看 Linux 权限和所有权模型。我们已经看到每个文件属于一个用户和一个

组。这正是 Linux 中权限模型的核心。您可以在 ls -l 清单中查看用户和组:

  

  $ ls -l /bin/bash

  

  -rwxr-xr-x  1 root   wheel   430540 Dec 23 18:27 /bin/bash在这个特殊

的示例中,/bin/bash 可执行文件属于 root 用户,并且在 wheel 组中。Linux 权限模型

通过允许给每个文件系统对象设置三种独立的权限级别来工作—它们为文件的所有者、文

件的组以及所有其他用户。

  

  理解“ls -l”

  

  我们来看一看我们的 ls -l 输出,检查一下这个清单的第一栏:

  

  $ ls -l /bin/bash-rwxr-xr-x  1 root   wheel   430540 Dec 23 18:27 /

bin/bash第一个字段 -rwxr-xr-x 包含该特殊文件的权限的符号表示。该字段中的首字符

(-)指定该文件的类型,本例中它是一个常规文件。其它可能的首字符还有:

  

  “d”目录“l”符号链接“c”字符专门设备文件“b”块专门设备文件“p”先进先出

“s”套接字三个三元组$ ls -l /bin/bash-rwxr-xr-x  1 root   wheel   

430540 Dec 23 18:27 /bin/bash该字段的其余部分由三个三元组字符组成。第一个三元字

符组代表文件所有者的权限,第二个代表文件的组的权限,第三个代表所有其他用户的权

限:

  

  "rwx""r-x""r-x"上面,r 表示允许读(查看文件中的数据),w 表示允许写(修改文

件以及删除),x 表示允许“执行”(运行程序)。将所有这些信息放在一起,我们可以

发现每个人都能够读该文件的内容和执行该文件,但是只允许文件所有者(root 用户)可

以以任何方式修改该文件。因此,虽然一般用户可以复制该文件,但是只允许 root 用户

更新或删除它。

  

  我是谁?在我们看怎样改变文件的用户所有权和组所有权之前,我们首先来看一看怎

样得知您当前的用户标识和组成员资格。除非最近您使用过 su 命令,否则您当前的用户

标识是您用来登录系统的用户标识。但是,如果您经常使用 su,您可能不记得您当前有效

的用户标识。要查看用户标识,输入 whoami:# whoamiroot# su drobbins$

whoamidrobbins我在哪一组?要看看您属于哪一组,使用 group 命令:$ groupsdrobbins

wheel audio在上面的示例中,我是 drobbins、wheel 和 audio 组的成员。如果您想看看

其他用户在什么组,指定他们的用户名作为参数:

  

  $ groups root daemonroot : root bin daemon sys adm disk wheel floppy

dialout tape videodaemon : daemon bin adm改变用户和组所有权为了改变文件或其它文

件系统对象的所有者或组,分别使用 chown 或 chgrp。这两个命令都要一个用户名或组名

作参数,后面跟上一个或多个文件名。

  

  # chown root /etc/passwd# chgrp wheel /etc/passwd您还可以用 chown 命令的另

一种形式同时设置所有者和组:

  

  # chown root.wheel /etc/passwd除非您是超级用户,否则您不可以使用 chown,然

而任何人都可以使用 chgrp 来将文件的组所有权改为他们所属的组。

  

  递归的所有权改变chown 和 chgrp 都有一个 -R 选项,该选项可以用来告诉它们递归

地将所属权和组改变应用到整个目录树中。例如:# chown -R drobbins /home/drobbins

介绍 chmodchown 和 chgrp 可以用来改变文件系统对象的所有者和组,而另一个程序—叫

做 chmod —用来改变我们可以在 ls -l 清单中看到的 rwx 权限。chmod 带有两个或多个

参数:“mode”,描述怎样改变权限,后面跟将会受到影响的文件或文件列表:$ chmod

+x scriptfile.sh在上面的示例中,我们的“mode”是 +x。您可能会猜到,+x 模式告诉

chmod,使该特殊文件对于用户、组以及其它任何人都是可执行的。如果我们想要除去一个

文件的所有执行权限,我们应该这样做: $ chmod -x scriptfile.sh用户/组/其他粒度

到此,我们的 chmod 示例已经影响到了所有三个三元组—用户、组和所有其他用户。通常

,一次只修改一个或两个三元组很方便。要这样做,只需要在 + 或 - 符号之前,给您想

要修改的特定的三元组指定符号字符。对于“用户”三元组使用 u,对于“组”三元组使

用 g,对于“其他/每个人”使用 o:$ chmod go-w scriptfile.sh我们刚除去了组和所

有其他用户的写权限,而保留“所有者”权限不动。重新设置权限除了交替打开和关闭权

限位以外,我们还可以一起重新设置它们。通过使用 = 操作符,我们可以告诉 chmod 我

们要指定权限和取消别的权限:$ chmod =rx scriptfile.sh上面,我们只设置了所有的“

read”和“execute”位,没有设置所有的“write”位。如果您仅仅想重新设置特定的三

元组,您可以像下面这样,在 = 之前指定该三元组的符号名:

  

  $ chmod u=rx scriptfile.sh

  

  数字模式

  

  直到现在为止,我们使用了叫做“符号”的模式来用 chmod 指定权限的改变。然而,

指定权限还有一种普遍使用的方法—使用 4 位八进制数。使用叫做数字权限语法的语法,

每一位代表一个权限三元组。例如,在 1777 中,777 设置本章我们所讨论的“owner”、

“group”和“other”标志。1 用来设置专门的权限位,我们将在本章的结束部分讲到。

这个图表说明了怎样解释第二到四位(777):

  

  模式数字

  rwx 7

  rw- 6

  r-x 5

  r-- 4

  -wx 3

  -w- 2

  --x 1

  --- 0

  

  数字权限语法

  

  当您需要给一个文件指定所有权限时,数字权限语法特别有用,比如在下面的示例中



  

  $ chmod 0755 scriptfile.sh

  

  $ ls -l scriptfile.sh

  

  -rwxr-xr-x  1 drobbins drobbins    0 Jan 9 17:44 scriptfile.sh

  

  在该示例中,我们使用了 0755 模式,它展开为一个完整的权限设置“-rwxr-xr-x”



  

  Umask

  

  当进程创建了新文件时,它指定新文件应该具有的权限。通常,所请求的模式是 0666

(每个人可读和可写),它比我们希望的具有更多的权限。幸运的是,不管什么时候创建

了新文件,Linux 将参考叫做“umask”的东西。系统用 umask 值来将初始指定的权限降

低为更合理、更安全的权限。您可以通过在命令行中输入 umask 来查看您当前的 umask

设置:

  

  $ umask

  

  0022

  

  Linux 系统上,umask 的缺省值一般为 0022,它允许其他人读您的新文件(如果他们

可以得到它们),但是不能进行修改。为了在缺省的情况下使新文件更安全,您可以改变

umask 设置: $ umask 0077umask 将确保组和其他用户对于新创建的文件绝对没有任何权

限。那么,umask 怎样工作呢?与文件的“常规”权限不同,umask 指定应该关闭哪一个

权限。我们来参阅一下我们的“模式到数字”映射表,从而使我们可以理解 0077 的

umask 的意思是什么:模式数字 rwx 7 rw- 6 r-x 5 r-- 4 -wx 3 -w- 2 --x 1 --- 0 使

用该表,0077 的最后三位扩展为 ---rwxrwx。现在,请记住 umask 告诉系统禁用哪个权

限。根据推断,我们可以看到将关闭所有“组”和“其他”权限,而“用户”权限将保留

不动。

  

  介绍 suid 和 sgid

  

  当您最初登录时,将启动一个新的 shell 进程。您已经知道,但是您可能还不知道这

个新的 shell进程(通常是 bash)使用您的用户标识运行。照这样,bash 程序可以访问

所有属于您的文件和目录。事实上,作为用户,我们完全依靠其它程序来代表我们执行操

作。因为您启动的程序继承了您的用户标识,因此它们不能访问任何不允许您访问的文件

系统对象。

  

  例如,一般用户不能直接修改 passwd 文件,因为“write”标志已经对除“root 用

户”以外的每个用户关闭:

  

  $ ls -l /etc/passwd

  

  -rw-r--r--  1 root   wheel    1355 Nov 1 21:16 /etc/passwd

  

  但是,一般用户确实需要在他们需要改变其密码的任何时候,能够修改 /etc/passwd

(至少间接地)。但是,如果用户不能修改该文件,究竟怎样完成这个工作呢?

  

  Suid

  

  幸好,Linux 权限模型有两个专门的位,叫做“suid”和“sgid”。当设置了一个可

执行程序的“suid”这一位时,它将代表可执行文件的所有者运行,而不是代表启动程序

的人运行。现在,回到 /etc/passwd 问题。如果看一看 passwd 可执行文件,我们可以看

到它属于 root 用户:

  

  $ ls -l /usr/bin/passwd

  

  -rwsr-xr-x  1 root   wheel    17588 Sep 24 00:53 /usr/bin/passwd

  

  您还将注意到,这里有一个 s 取替了用户权限三元组中的一个 x。这表明,对于这个

特殊程序,设置了 suid 和可执行位。由于这个原因,当 passwd 运行时,它将代表 root

用户执行(具有完全超级用户访问权),而不是代表运行它的用户运行。又因为 passwd

以 root 用户访问权运行,所以能够修改 /etc/passwd 文件,而没有什么问题。

  

  suid/sgid 告诫说明

  

  我们看到了 suid 怎样工作,sgid 以同样的方式工作。它允许程序继承程序的组所有

权,而不是当前用户的程序所有权。这里有一些关于 suid 和 sgid 的其它的但是很重要

的信息。首先,suid 和 sgid 占据与 ls -l 清单中 x 位相同的空间。如果还设置了 x

位,则相应的位表示为 s(小写)。但是,如果没有设置 x 位,它将表示为 S(大写)。

另一个很重要的提示:在许多环境中,suid 和 suid 很管用,但是不恰当地使用这些位可

能使系统的安全遭到破坏。最好尽可能地少用“suid”程序。passwd 命令是为数不多的必

须使用“suid”的命令之一。

  

  改变 suid 和 sgid

  

  设置和除去 suid 与 sgid 位相当简单。这里,我们设置 suid 位:

  

  # chmod u+s /usr/bin/myapp

  

  此处,我们从一个目录除去 sgid 位。我们将看到 sgid 位怎样影响下面几屏中的目

录:

  

  # chmod g-s /home/drobbins

  

  权限和目到此为止,我们从常规文件的角度来看权限。当从目录的角度看权限时,情

况有一点不同。目录使用同样的权限标志,但是它们被解释为表示略微不同的含义。对于

一个目录,如果设置了“read”标志,您可以列出目录的内容;“write”表示您可以在目

录中创建文件,“execute”表示您可以进入该目录并访问内部的任何子目录。没有“

execute”标志,目录内的文件系统对象是不可访问的。没有“read”标志,目录内的文件

系统对象是不可查看的,但是只要有人知道磁盘上对象的完整路径,就仍然可以访问目录

内的对象。目录和 sgid如果启用了目录的“sgid”标志,在目录内创建的任何文件系统对

象将继承目录的组。当您需要创建一个属于同一组的一组人使用的目录树时,这种特殊的

功能很管用。只需要这样做:

  

  # mkdir /home/groupspace

  

  # chgrp mygroup /home/groupspace

  

  # chmod g+s /home/groupspace

  

  现在,mygroup 组中的所有用户都可以在 /home/groupspace 内创建文件或目录,同

样,他们也将自动地分配到 mygroup 的组所有权。根据用户的 umask 设置,新文件系统

对象对于 mygroup 组的其他成员来说,可以或不可以是可读、可写或可执行的。目录和删

除缺省情况下,Linux 目录以一种不是在所有情况下都很理想的方式表现。一般来说,只

要对一个目录有写访问权,任何人都可以重命名或删除该目录中的文件。对于个别用户使

用的目录,这种行为是很合理的。但是,对于很多用户使用的目录来说,尤其是 /tmp 和

/var/tmp,这种行为可能会产生麻烦。因为任何人都可以写这些目录,任何人都可以删除

或重命名任何其他人的文件—即使是不属于他们的!显然,当任何其他用户在任何时候都

可以输入“rm -rf /tmp/*”并损坏每个人的文件时,很难把 /tmp 用于任何有意义的文件

。所幸,Linux 有叫做“粘滞位”(sticky bit)的东西。当给 /tmp 设置了粘滞位(用

chmod +t),唯一能够删除或重命名 /tmp 中文件的是该目录的所有者(通常是 root 用

户)、文件的所有者或 root 用户。事实上,所有 Linux 分发包都缺省地启用了 /tmp 的

粘滞位,而您还可以发现粘滞位在其它情况下也很管用。难以理解的第一位总结本章,我

们最后来看一看数字模式的难以理解的第一位数。您可以看到,这个第一位数用来设置

sticky、suid 和 sgid 位:

  

  suid sgid sticky 模式数字 on on on 7 on on off 6 on off on 5 on off off 4

off on on 3 off on off 2 off off on 1 off off off 0

  

  这里有一个怎样用 4 位数字模式来设置一个目录的权限的示例,该目录将由一个工作

组使用: # chmod 1775 /home/groupfiles请想一想 1755 数字模式权限设置的含义。

  相关产品与培训

● 相关文章                                           ● 推荐文章

避其锋芒 Linux操作系统入侵实例

构建一个基于软盘的防火墙

用Linux防火墙伪装抵挡黑客恶意攻击

用rsync从Linux到Windows远程备份(组图)

解决新的SELinux安全级别产生问题(图)

linux SSH 的一些安全小技巧

Linux下PhpMyAdmin程序目录的安全管理

Linux网络安全经验之谈

防火墙 Linux 数据包捕获模块包过滤

巧妙利用Linux系统IP伪装抵住黑客攻击

********************************************************************************

                                     转帖完毕

redhat linux9.0中grub启动的恢复

在用fdisk /mbr时,本来想对机器上的第二块硬盘作清除主引导记录的操作,结果却把装有linux操作系统的第一块硬盘的主引导记录清掉了。现在还不知道fdisk /mbr在两块硬盘上操作的有关问题?

恢复需要进入linux的grub命令行程序,可以从两个途径进入。

一是从安装光盘设置为从光盘启动,进入安装界面后输入linux rescue,进行一系列语言、键盘等的设置后就进入了shell命令行,这时就可以进入grub程序了。

一是从其它途径(如grub启动软盘、从dos引导)进入系统工作状态后进入grub程序。

然后就是输入 grub命令如下:

grub>root (hd0,0) (hd0指第一个硬盘,后面的0指的是/boot/grub目录所在的分区,而不是指的是/所在的分区,如果你的/boot和/分别在两个分区上,就不要弄错了)

grub>setup (hd0) (是指把grub引导程序写入第一个硬盘的主引导记录,如果写成(hd0,0)是指把引导记录写入第一个硬盘的第一个分区的引导扇区中)

执行成功后会显示success的信息。

不过,我的这个redhat linux9.0操作系统挂在amd毒龙700上可以用这个方法把grub恢复到MBR中,但挂在486DX100却不行,启动报告grub read error,要用setup (hd0,0)写入分区的引导扇区才行,不知道是怎么一回事?

一个可以在linux和windows控制台使用的qq客户端软件MilyQQ

详见作者的博客:喋喋不休: http://spadger.blog.com.cn

现在最新的版本是MilyQQ3.0。现在的版本是c++写的,速度很快。以前的版本是java写的。

我试了一下,使用MilyQQ3.0,在我的486dx100+redhat linux9.0的真正古董级机器上也能流畅的运行,很不错。

在linux下使用前需要改变这个软件的权限:chmod a+x MilyQQ (赋与所有用户对这个软件的可执行权限)

我感觉这个软件的主要使用者还是经常使用linux控制台的人,比如像我,因为电脑太老,只能使用linux的控制台。而经常使用windows图形界面和linux图形界面的人,估计都不大会使用这个软件。

本地下载MilyQQ3.0:

附件:MilyQQ3.0.zip,316958 bytes

原创地下载MilyQQ3.0:

附件:MilyQQ3.0.zip,316958 bytes

用libstdc++.so.5冒充libstdc++.so.6欺骗mysql4.1.21

昨天在我的486+redhat linux9.0的老机上装了一个mysql4.1.0的客户端,不想连到远程数据库时,一执行use dbname;程序就会退出,报告什么sem* fault错误;

今天下载了一个mysql-standard-4.1.22-pc-linux-gnu-i686-icc-glibc23.tar.gz,解压到/usr/local,作好链接什么的,一执行mysql命令,报告缺少/usr/lib/libstdc++.so.6文件。查了一下,redhat linux9.0配的rpm包是libstdc++-3.2.2-5.i386.rpm,而不是有/usr/lib/libstdc++.so.6的libstdc++-3.4(好像是这样的)。不想去下载源码在这么老的机器上编译。于是,试着用命令: ln -s /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so.6用libstdc++.so.5冒充libstdc++.so.6欺骗mysql4.1.21,结果执行mysql -hhostname -uusername -p竟然连接成功了。

不过不知道这种欺骗手段有没有什么负作用呢?

linux下的换行符号引起Resin3的struts-config.xml解析报错

由于linux和windows的换行符不一致,有时在这种系统间的文件交换就会出现问题。我就碰到这样的问题。

本来应该是这样的Struts-config.xml内容:


        <action

            attribute="loginForm"

            input="/login.jsp"

            name="loginForm"

            path="/loginAction"

            type="com.learndiary.website.action.account.LoginAction">

            <forward name="success" path="/loginSuccess.jsp" />

            <forward name="failure" path="/login.jsp" />

        </action>

可能是从windows转到linux下变成了这样:


        <action^M^M

            attribute="loginForm"^M^M

            input="/login.jsp"^M^M

            name="loginForm"^M^M

            path="/loginAction"^M^M

            type="com.learndiary.website.action.account.LoginAction">^M^M

            <forward name="success" path="/loginSuccess.jsp" />^M^M

            <forward name="failure" path="/login.jsp" />^M^M

        </action>

这在本地的Tomcat5和空间原来的Resin2下都没有问题,但是当空间改为Resin3后,每次重新启动应用就报错:


The content of element type "action" must match "(icon?,display-name?,description?,set-property*,exception*,forward*)".

...

但是奇怪的是,应用启动后的工作看起来还是正常的。

下面附的是相关的文字:(转自:http://www.real-blog.com/linux-bsd-notes/67

Unix 及 Windows 文字檔轉換

大家如果試過在 Linux 及 Windows 文字檔分享的話,會發現文字檔的 “換行” 不一樣。在 Windows 用記事本開啟 Unix 文字檔時,文件不會開新行,需要使用支援 Unix 格式的文字編輯器才可看到分行;而在 Linux 開啟 Windows 的文字檔時,在每一行最後會有字元 Ctrl-m (^M)。以下是使用 Perl 在 Linux 下將文字檔轉換的方法:

Windows 格式 -> Unix 格式

perl -p -e ’s/\r$//’ < winfile.txt > unixfile.txt

Unix 格式 -> Windows 格式

perl -p -e ’s/\n/\r\n/’ < unixfile.txt > winfile.txt

February 13, 2006 · Linux / BSD 筆記, Windows 筆記 ·

1 Comment »

   1.

      UNIX WINDOWS MAC三者的回车都不一样,好像是:windows是0×0d 0×0a

      UNIX是0×0d MAC是0×0a吧。记不太清楚了。大体上是这样的。

      Comment by 数据恢复 — April 6, 2006 @

呵呵,等这段时间过了玩一玩lfs?

在linuxsir.org听到朋友们说用lfs,在老机上也有好的表现.我的老机是amd dron 700, 384m, 20g, 15".现在装的是redhat linux9.0,还勉强能够用eclipse写学习日记程序.

不知用lfs在上面写程序的表现如何?我现在有一种玩一下lfs的想法了.

听说,lfs很难装,是直接在已有linux系统上直接上编译系统源代码来安装的.所以,到时不妨建一个目标,就叫,攻克lfs.

在安装之前我要充分作好啃硬骨头的思想准备.把安装过程尽量先事先学习一下.到时争取一举拿下lfs:)

linux应用小技巧收集

一些一两句话的linux应用小技巧放在这个帖子里。

1、查看文件字符集编码是gb2312还是utf8等:$file filename (Determine file type of FILEs.)

2、find 命令忽略大小写参数 -iname

3、gftp 中如果要把一个文件移到其它目录可以使用“更名”,如把文件h.txt 移到 ./folder/h.txt就把文件名h.txt更名为./folder/h.txt就行了。注:gftp是linux下的图形化的ftp软件。

4、 查看目录的大小

du -sh dirname

-s 仅显示总计

-h 以K、M、G为单位,提高信息的可读性。KB、MB、GB是以1024为换算单 位, -H以1000为换算单位。

-b print size in bytes

(但是奇怪的是在redhat linux9.0中在图形界面的目录上点击右键的属性项上显示的大小与上面命令显示的大小不一样,如上面命令显示的是9M,而在图形界面的属性中显示的却是7.2M。不知道是怎么一回事?)

与WIN不同,linux替换文件夹会删除原文件夹下的全部内容!

例如:

原文件夹folder含一个文件test.txt和一个子文件夹subdir;

同名新文件夹folder下只有一个文件test.txt。

我在文件夹中用鼠标复制新文件夹到旧文件夹所在的文件夹,在windows下只会替换其中新文件夹中的test.txt,旧文件夹下的子文件夹subdir不会受影响;而在linux下旧文件夹下面的子文件夹subdir也会被删除!

这就是linux和windows不同的地方之一,一些在windows下面想当然的操作在linux下没有用过也不要去随便做。

另外,我在linux下的命令行方式下试了一下复制覆盖操作:

假设folder和anotherfolder在当前目录下,anotherfolder下有个名为folder的旧文件夹,

cp folder anotherfolder/ -fr

这样操作只会覆盖同名的文件test.txt,而不会覆盖旧文件夹下面的其它东西。

真不知道在窗口中用鼠标操作的复制操作的等同的命令是什么?

Linux文件查找命令find,xargs详述(转帖)

转自:(http://docs.chinalinuxpub.com/read.php?wid=1230)

想删除工程中的CVS文件和文件夹,查了一下网上,基本的东西都是差不多的,就是这篇帖子才解决问题。为什么?因为这篇文章多了一句话:“相应命令的形式为'command' { } \;,注意{ }和\;之间的空格。”

我没有在{}和\;之间加空格,结果是费了不少时间。感谢原作者的贡献。

我前面的命令为:

find . -name "*CVS*" -exec rm -fr {} \;

转帖正文:

×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

Linux文件查找命令find,xargs详述

发布于2006-06-12 被读1665次 【字体:大 中 小】

版权声明

本文是zhyfly兄贴在LinuxSir.Org 的一个帖子而整理出来的,如果您对版权有疑问,请在本帖后面跟帖。谢谢;本文的HTML版本由北南南北整理;修改了整篇文档的全角及说明文字中的单词中每个字母空格的问题;为标题加了编号,方便大家阅读;

前言:关于find命令

由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下。即使系统中含有网络文件系统( NFS),find命令在该文件系统中同样有效,只你具有相应的权限。

在运行一个非常消耗资源的find命令时,很多人都倾向于把它放在后台执行,因为遍历一个大的文件系统可能会花费很长的时间(这里是指30G字节以上的文件系统)。

一、find 命令格式

1、find命令的一般形式为;

find pathname -options [-print -exec -ok ...]

2、find命令的参数;

pathname: find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。

-print: find命令将匹配的文件输出到标准输出。

-exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' { } \;,注意{ }和\;之间的空格。

-ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。

3、find命令选项

-name

按照文件名查找文件。

-perm

按照文件权限来查找文件。

-prune

使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。

-user

按照文件属主来查找文件。

-group

按照文件所属的组来查找文件。

-mtime -n +n

按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。

-nogroup

查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。

-nouser

查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。

-newer file1 ! file2

查找更改时间比文件file1新但比文件file2旧的文件。

-type

查找某一类型的文件,诸如:

b - 块设备文件。

d - 目录。

c - 字符设备文件。

p - 管道文件。

l - 符号链接文件。

f - 普通文件。

-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。

-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。

-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。

-mount:在查找文件时不跨越文件系统mount点。

-follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。

-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。

另外,下面三个的区别:

   -amin n

  查找系统中最后N分钟访问的文件

  -atime n

  查找系统中最后n*24小时访问的文件

  -cmin n

  查找系统中最后N分钟被改变文件状态的文件

  -ctime n

  查找系统中最后n*24小时被改变文件状态的文件

    -mmin n

  查找系统中最后N分钟被改变文件数据的文件

  -mtime n

  查找系统中最后n*24小时被改变文件数据的文件

4、使用exec或ok来执行shell命令

使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find查找,很方便的

在有些操作系统中只允许-exec选项执行诸如l s或ls -l这样的命令。大多数用户使用这一选项是为了查找旧文件并删除它们。建议在真正执行rm命令删除文件之前,最好先用ls命令看一下,确认它们是所要删除的文件。

exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{ },一个空格和一个\,最后是一个分号。为了使用exec选项,必须要同时使用print选项。如果验证一下find命令,会发现该命令只输出从当前路径起的相对路径及文件名。

例如:为了用ls -l命令列出所匹配到的文件,可以把ls -l命令放在find命令的-exec选项中

# find . -type f -exec ls -l { } \;

-rw-r--r-- 1 root root 34928 2003-02-25 ./conf/httpd.conf

-rw-r--r-- 1 root root 12959 2003-02-25 ./conf/magic

-rw-r--r-- 1 root root 180 2003-02-25 ./conf.d/README

上面的例子中,find命令匹配到了当前目录下的所有普通文件,并在-exec选项中使用ls -l命令将它们列出。

在/logs目录中查找更改时间在5日以前的文件并删除它们:

 $ find logs -type f -mtime +5 -exec rm { } \;

记住:在shell中用任何方式删除文件之前,应当先查看相应的文件,一定要小心!当使用诸如mv或rm命令时,可以使用-exec选项的安全模式。它将在对每个匹配到的文件进行操作之前提示你。

在下面的例子中, find命令在当前目录中查找所有文件名以.LOG结尾、更改时间在5日以上的文件,并删除它们,只不过在删除之前先给出提示。

 $ find . -name "*.conf" -mtime +5 -ok rm { } \;

< rm ... ./conf/httpd.conf > ? n

按y键删除文件,按n键不删除。

任何形式的命令都可以在-exec选项中使用。

在下面的例子中我们使用grep命令。find命令首先匹配所有文件名为“ passwd*”的文件,例如passwd、passwd.old、passwd.bak,然后执行grep命令看看在这些文件中是否存在一个sam用户。

# find /etc -name "passwd*" -exec grep "sam" { } \;

sam:x:501:501::/usr/sam:/bin/bash

二、find命令的例子;

1、查找当前用户主目录下的所有文件:

下面两种方法都可以使用

 $ find  $HOME -print

 $ find ~ -print

2、让当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件;

 $ find . -type f -perm 644 -exec ls -l { } \;

3、为了查找系统中所有文件长度为0的普通文件,并列出它们的完整路径;

 $ find / -type f -size 0 -exec ls -l { } \;

4、查找/var/logs目录中更改时间在7日以前的普通文件,并在删除之前询问它们;

 $ find /var/logs -type f -mtime +7 -ok rm { } \;

5、为了查找系统中所有属于root组的文件;

 $find . -group root -exec ls -l { } \;

-rw-r--r-- 1 root root 595 10月 31 01:09 ./fie1

6、find命令将删除当目录中访问时间在7日以来、含有数字后缀的admin.log文件。

该命令只检查三位数字,所以相应文件的后缀不要超过999。先建几个admin.log*的文件 ,才能使用下面这个命令

 $ find . -name "admin.log[0-9][0-9][0-9]" -atime -7 -ok

rm { } \;

< rm ... ./admin.log001 > ? n

< rm ... ./admin.log002 > ? n

< rm ... ./admin.log042 > ? n

< rm ... ./admin.log942 > ? n

7、为了查找当前文件系统中的所有目录并排序;

 $ find . -type d | sort

8、为了查找系统中所有的rmt磁带设备;

 $ find /dev/rmt -print

三、xargs

xargs - build and execute command lines from standard input

在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。

find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。

在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;

而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

来看看xargs命令是如何同find命令一起使用的,并给出一些例子。

下面的例子查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件

#find . -type f -print | xargs file

./.kde/Autostart/Autorun.desktop: UTF-8 Unicode English text

./.kde/Autostart/.directory: ISO-8859 text\

......

在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中:

 $ find / -name "core" -print | xargs echo "" >/tmp/core.log

上面这个执行太慢,我改成在当前目录下查找

#find . -name "file*" -print | xargs echo "" > /temp/core.log

# cat /temp/core.log

./file6

在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限:

# ls -l

drwxrwxrwx 2 sam adm 4096 10月 30 20:14 file6

-rwxrwxrwx 2 sam adm 0 10月 31 01:01 http3.conf

-rwxrwxrwx 2 sam adm 0 10月 31 01:01 httpd.conf

# find . -perm -7 -print | xargs chmod o-w

# ls -l

drwxrwxr-x 2 sam adm 4096 10月 30 20:14 file6

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf

用grep命令在所有的普通文件中搜索hostname这个词:

# find . -type f -print | xargs grep "hostname"

./httpd1.conf:# different IP addresses or hostnames and have them handled by the

./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames

on your

用grep命令在当前目录下的所有普通文件中搜索hostnames这个词:

# find . -name \* -type f -print | xargs grep "hostnames"

./httpd1.conf:# different IP addresses or hostnames and have them handled by the

./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames

on your

注意,在上面的例子中, \用来取消find命令中的*在shell中的特殊含义。

find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。

四、find 命令的参数

下面是find一些常用参数的例子,有用到的时候查查就行了,像上面前几个贴子,都用到了其中的的一些参数,也可以用man或查看论坛里其它贴子有find的命令手册

1、使用name选项

文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用。

可以使用某种文件名模式来匹配文件,记住要用引号将文件名模式引起来。

不管当前路径是什么,如果想要在自己的根目录 $HOME中查找文件名符合*.txt的文件,使用~作为 'pathname'参数,波浪号~代表了你的 $HOME目录。

 $ find ~ -name "*.txt" -print

想要在当前目录及子目录中查找所有的‘ *.txt’文件,可以用:

 $ find . -name "*.txt" -print

想要的当前目录及子目录中查找文件名以一个大写字母开头的文件,可以用:

 $ find . -name "[A-Z]*" -print

想要在/etc目录中查找文件名以host开头的文件,可以用:

 $ find /etc -name "host*" -print

想要查找 $HOME目录中的文件,可以用:

 $ find ~ -name "*" -print 或find . -print

要想让系统高负荷运行,就从根目录开始查找所有的文件。

 $ find / -name "*" -print

如果想在当前目录查找文件名以两个小写字母开头,跟着是两个数字,最后是.txt的文件,下面的命令就能够返回名为ax37.txt的文件:

 $find . -name "[a-z][a-z][0--9][0--9].txt" -print

2、用perm选项

按照文件权限模式用-perm选项,按文件权限模式来查找文件的话。最好使用八进制的权限表示法。

如在当前目录下查找文件权限位为755的文件,即文件属主可以读、写、执行,其他用户可以读、执行的文件,可以用:

 $ find . -perm 755 -print

还有一种表达方法:在八进制数字前面要加一个横杠-,表示都匹配,如-007就相当于777,-006相当于666

# ls -l

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf

-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf

drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam

-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp

# find . -perm 006

# find . -perm -006

./sam

./httpd1.conf

./temp

-perm mode:文件许可正好符合mode

-perm +mode:文件许可部分符合mode

-perm -mode: 文件许可完全符合mode

3、忽略某个目录

如果在查找文件时希望忽略某个目录,因为你知道那个目录中没有你所要查找的文件,那么可以使用-prune选项来指出需要忽略的目录。在使用-prune选项时要当心,因为如果你同时使用了-depth选项,那么-prune选项就会被find命令忽略。

如果希望在/apps目录下查找文件,但不希望在/apps/bin目录下查找,可以用:

 $ find /apps -path "/apps/bin" -prune -o -print

4、使用find查找文件的时候怎么避开某个文件目录

比如要在/usr/sam目录下查找不在dir1子目录之内的所有文件

find /usr/sam -path "/usr/sam/dir1" -prune -o -print

find [-path ..] [expression] 在路径列表的后面的是表达式

-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o

-print 的简写表达式按顺序求值, -a 和 -o 都是短路求值,与 shell 的 && 和 || 类似如果 -path "/usr/sam" 为真,则求值 -prune , -prune 返回真,与逻辑表达式为真;否则不求值 -prune,与逻辑表达式为假。如果 -path "/usr/sam" -a -prune 为假,则求值 -print ,-print返回真,或逻辑表达式为真;否则不求值 -print,或逻辑表达式为真。

这个表达式组合特例可以用伪码写为

if -path "/usr/sam" then

          -prune

else

          -print

避开多个文件夹

find /usr/sam \( -path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -print

圆括号表示表达式的结合。

\ 表示引用,即指示 shell 不对后面的字符作特殊解释,而留给 find 命令去解释其意义。

查找某一确定文件,-name等选项加在-o 之后

#find /usr/sam \(-path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -name "temp" -print

5、使用user和nouser选项

按文件属主查找文件,如在 $HOME目录中查找文件属主为sam的文件,可以用:

 $ find ~ -user sam -print

在/etc目录下查找文件属主为uucp的文件:

 $ find /etc -user uucp -print

为了查找属主帐户已经被删除的文件,可以使用-nouser选项。这样就能够找到那些属主在/etc/passwd文件中没有有效帐户的文件。在使用-nouser选项时,不必给出用户名; find命令能够为你完成相应的工作。

例如,希望在/home目录下查找所有的这类文件,可以用:

 $ find /home -nouser -print

6、使用group和nogroup选项

就像user和nouser选项一样,针对文件所属于的用户组, find命令也具有同样的选项,为了在/apps目录下查找属于gem用户组的文件,可以用:

 $ find /apps -group gem -print

要查找没有有效所属用户组的所有文件,可以使用nogroup选项。下面的find命令从文件系统的根目录处查找这样的文件

 $ find / -nogroup-print

7、按照更改时间或访问时间等查找文件

如果希望按照更改时间来查找文件,可以使用mtime,atime或ctime选项。如果系统突然没有可用空间了,很有可能某一个文件的长度在此期间增长迅速,这时就可以用mtime选项来查找这样的文件。

用减号-来限定更改时间在距今n日以内的文件,而用加号+来限定更改时间在距今n日以前的文件。

希望在系统根目录下查找更改时间在5日以内的文件,可以用:

 $ find / -mtime -5 -print

为了在/var/adm目录下查找更改时间在3日以前的文件,可以用:

 $ find /var/adm -mtime +3 -print

8、查找比某个文件新或旧的文件

如果希望查找更改时间比某个文件新但比另一个文件旧的所有文件,可以使用-newer选项。它的一般形式为:

newest_file_name ! oldest_file_name

其中,!是逻辑非符号。

查找更改时间比文件sam新但比文件temp旧的文件:

例:有两个文件

-rw-r--r-- 1 sam adm 0 10月 31 01:07 fiel

-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf

drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam

-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp

# find -newer httpd1.conf ! -newer temp -ls

1077669 0 -rwxrwxr-x 2 sam adm 0 10月 31 01:01 ./httpd.conf

1077671 4 -rw-rw-rw- 1 root root 2792 10月 31 20:19 ./temp

1077673 0 -rw-r--r-- 1 sam adm 0 10月 31 01:07 ./fiel

查找更改时间在比temp文件新的文件:

 $ find . -newer temp -print

9、使用type选项

在/etc目录下查找所有的目录,可以用:

 $ find /etc -type d -print

在当前目录下查找除目录以外的所有类型的文件,可以用:

 $ find . ! -type d -print

在/etc目录下查找所有的符号链接文件,可以用

 $ find /etc -type l -print

10、使用size选项

可以按照文件长度来查找文件,这里所指的文件长度既可以用块(block)来计量,也可以用字节来计量。以字节计量文件长度的表达形式为N c;以块计量文件长度只用数字表示即可。

在按照文件长度查找文件时,一般使用这种以字节表示的文件长度,在查看文件系统的大小,因为这时使用块来计量更容易转换。

在当前目录下查找文件长度大于1 M字节的文件:

 $ find . -size +1000000c -print

在/home/apache目录下查找文件长度恰好为100字节的文件:

 $ find /home/apache -size 100c -print

在当前目录下查找长度超过10块的文件(一块等于512字节):

 $ find . -size +10 -print

11、使用depth选项

在使用find命令时,可能希望先匹配所有的文件,再在子目录中查找。使用depth选项就可以使find命令这样做。这样做的一个原因就是,当在使用find命令向磁带上备份文件系统时,希望首先备份所有的文件,其次再备份子目录中的文件。

在下面的例子中, find命令从文件系统的根目录开始,查找一个名为CON.FILE的文件。

它将首先匹配所有的文件然后再进入子目录中查找。

 $ find / -name "CON.FILE" -depth -print

12、使用mount选项

在当前的文件系统中查找文件(不进入其他文件系统),可以使用find命令的mount选项。

从当前目录开始查找位于本文件系统中文件名以XC结尾的文件:

 $ find . -name "*.XC" -mount -print

五、关于本文

本文是find 命令的详细说明,可贵的是针对参数举了很多的实例,大量的例证,让初学者更为容易理解;本文是zhy2111314兄贴在论坛中;我对本文进行了再次整理,为方便大家阅读; ── 北南南北

                                     --转帖完毕