??xml version="1.0" encoding="utf-8" standalone="yes"?>色偷偷亚洲男人天堂,亚洲а∨天堂久久精品9966,久久精品国产亚洲综合色http://www.tkk7.com/joan/category/32989.htmlUは张で QQ:774199038zh-cnFri, 18 Sep 2009 05:31:29 GMTFri, 18 Sep 2009 05:31:29 GMT60linux常用端口对照http://www.tkk7.com/joan/articles/236558.htmljoanjoanSat, 25 Oct 2008 08:48:00 GMThttp://www.tkk7.com/joan/articles/236558.htmlhttp://www.tkk7.com/joan/comments/236558.htmlhttp://www.tkk7.com/joan/articles/236558.html#Feedback0http://www.tkk7.com/joan/comments/commentRss/236558.htmlhttp://www.tkk7.com/joan/services/trackbacks/236558.html著名端口
1 tcpmux TCP 端口服务多\复用
5 rje q程作业入口
7 echo Echo 服务
9 discard 用于q接试的空服务
11 systat 用于列Dq接了的端口的系l状?
13 daytime l请求主机发送日期和旉
  阅读全文

joan 2008-10-25 16:48 发表评论
]]>
Solaris下MySQL5安装W记http://www.tkk7.com/joan/articles/236552.htmljoanjoanSat, 25 Oct 2008 07:59:00 GMThttp://www.tkk7.com/joan/articles/236552.htmlhttp://www.tkk7.com/joan/comments/236552.htmlhttp://www.tkk7.com/joan/articles/236552.html#Feedback0http://www.tkk7.com/joan/comments/commentRss/236552.htmlhttp://www.tkk7.com/joan/services/trackbacks/236552.html  阅读全文

joan 2008-10-25 15:59 发表评论
]]>
LINUX COMMANDS LINEhttp://www.tkk7.com/joan/articles/234751.htmljoanjoanThu, 16 Oct 2008 12:12:00 GMThttp://www.tkk7.com/joan/articles/234751.htmlhttp://www.tkk7.com/joan/comments/234751.htmlhttp://www.tkk7.com/joan/articles/234751.html#Feedback0http://www.tkk7.com/joan/comments/commentRss/234751.htmlhttp://www.tkk7.com/joan/services/trackbacks/234751.html阅读全文

joan 2008-10-16 20:12 发表评论
]]>
linux 中文q解决http://www.tkk7.com/joan/articles/233559.htmljoanjoanFri, 10 Oct 2008 04:34:00 GMThttp://www.tkk7.com/joan/articles/233559.htmlhttp://www.tkk7.com/joan/comments/233559.htmlhttp://www.tkk7.com/joan/articles/233559.html#Feedback0http://www.tkk7.com/joan/comments/commentRss/233559.htmlhttp://www.tkk7.com/joan/services/trackbacks/233559.html阅读全文

joan 2008-10-10 12:34 发表评论
]]>
Linux 文g和目录管理之列出、删除、复制、移动及改名http://www.tkk7.com/joan/articles/233124.htmljoanjoanWed, 08 Oct 2008 05:31:00 GMThttp://www.tkk7.com/joan/articles/233124.htmlhttp://www.tkk7.com/joan/comments/233124.htmlhttp://www.tkk7.com/joan/articles/233124.html#Feedback0http://www.tkk7.com/joan/comments/commentRss/233124.htmlhttp://www.tkk7.com/joan/services/trackbacks/233124.html
1、列文g或目录的信息工具 ls或dir;

ls 命o可以用于昄目录的内容,也可以显C文件的属性,比如节点、文件种cR权限、拥有者、大、创建时间等Q在目前最新版本的Linux中dir和ls命o的用法是一L(fng)Q有兴趣的不仿尝试一下;


1.1 ls 的基语法和参敎ͼ

语法格式Q?/strong>

#ls Qd数]   [目录或文件名]

 

参数Q?/strong>

-a 昄所有文Ӟ包含隐藏文gQ包?#8220;.“?#8220;..“
-A 昄所有文Ӟ包含隐藏文gQ不包括“.“?#8220;..“目录Q?br /> -B 不列出文件名以~l尾的文Ӟ
-C 按列列出文gQ?br /> -d 仅可以查看目录的属性参数及信息Q?br /> -F q个参数加上后,能给目录d?Q给可执行文件加?Q给W号链接加上@  {等Q来标记文g名,目的是让用户方便查看Q?
-l 长格式输?br /> -h 习惯Z可阅ȝ方式来显C文件或目录的大,比如K、M或G{;
-p 在目录的后面附加/标记Q?br /> -r 逆序列出文gQ?br /> -t  按文件最后访问(或修改)的时间排序,最新的排在最前面Q?br /> -U 按原始排序,
-L 递归昄Q也是_当我们列某个目录的下的所有文件和目录Ӟ能把它的下目录的内Ҏ(gu)C出来?br /> --help  获得帮助Q?/code>

 

在这里,位于[]之内的都是可选的。如果?zhn)只输入ls Q就会列出用h处当前目录的所有文Ӟ用短格式输出Q但不会列出隐藏文g?/p>

判断用户所处目录的命o是pwdQ也是

[root@localhost ~]# pwd
/root

 


1.2 ls 的参数示例应用;


1.21 列出目录下所有文Ӟ包含或不包含隐藏文gQ?a 参数?l参数的运用;

#ls -la Qȝ录名]

 

如果不接目录名,表示输出当前用户所处目录内的所有文Ӟ包括隐藏文gQ?/p>

[root@localhost ~]# pwd
/root
[root@localhost ~]# ls -la

 

列出某一目录下的的文件或目录Q但不包括隐藏文Ӟ我们只用-l参数

#ls -l  目录

 

比如Q?br />

[root@localhost ~]# ls  -l /root/
总计 13968
-rw-r--r-- 1 root root         0 04-19 14:09 123.txt
-rw------- 1 root root      1375 03-16 08:55 anaconda-ks.cfg
-rw-r--r-- 1 root root         2 03-27 02:00 fonts.scale
-rw-r--r-- 1 root root      5423 03-16 08:52 install.log.syslog
-rw-r--r-- 1 root root  14087155 03-16 07:53 kernel-2.6.15-1.2025_FC5.i686.rpm
lrwxrwxrwx 1 root root        33 04-19 11:27 kernel.rpm -> kernel-2.6.15-1.2025_FC5.i686.rpm
drwxr-xr-x 2 1000 users     4096 04-04 23:30 mkuml-2004.07.17
-rw-r--r-- 1 root root     68012 04-04 20:28 mkuml-2004.07.17-ananas.tar.bz2
drwxr-xr-x 2 root root      4096 04-19 10:53 mydir
-rw-r--r-- 1 root root     53992 03-16 08:54 myinstall.log
-rw-r--r-- 1 root root         0 04-19 14:10 plinux.txt
drwxr-xr-x 2 root root      4096 03-17 04:25 Public
-rw-r--r-- 1 root root       613 03-26 18:41 upgrade.log
-rw-r--r-- 1 root root         0 03-26 18:39 upgrade.log.syslog
lrwxrwxrwx 1 root root         6 04-19 11:17 yourdir -> mydir/

 

说明Q如果以长格式输入,d昄出八D内容:

W一D?/strong>文gU类及权限,也就是类DL(fng)-rw-r--r-- Q我们在前面讲到Q如果在q段中,W一字符表示文g的类型,如果出现-Q表C普通文件。如果是d开头的是目录。在q个例子中,123.txt是普通文Ӟ而mkuml-2004.07.17是一个目录。关于文件的U类Q请参?Q?br /> rw-r--r--是权限位Q我们在以后的教E中会讲到?br /> W二D?/strong> 链接个敎ͼ文gpd加一个硬链接Q数字会增加1Q默认从1开始,1表示无硬链接文gQ如果是一个目录,它的默认值应该是2。目录是不能做硬链接的)
如果我们不以长格式输出的话,可以把参数省略;
W三D?/strong> 文g或目录所占用的字节数Q如果?zhn)想用K来表C,L(fng)ls -lh /root
W四D?最后访问日?br /> W五D?/strong> 最后访问时?br /> W六D?/strong> 文g?/p>

[root@localhost ~]# ls /root

 


1.22 仅查看目录的属性的-d参数的运用示例;

[root@localhost ~]# ls -ld  /etc  /boot  注:查看/etc?boot目录的信息;

drwxr-xr-x   4 root root  4096 04-11 16:22 /boot
drwxr-xr-x 108 root root 12288 04-20 12:36 /etc

 


1.23 查看文g或目录的inode节点Q?i参数的运用;

查看文g或目录的节点Q我们要用到i参数。如果节点相同,能确认他们是相同的文Ӟ是通过通过ln 创徏的硬链接文gQ链接接有何用?如果(zhn)想把一个文件复制时保持原文件或目录的节炏V大、权限以及访问(或修改)旉都和原文件一致的文g。必通过链接来实现Q用cp命o是不可能实现的?/p>

比如Q?/strong>

[root@localhost ~]# ls -li /root



[root@localhost ~]# ls -li kernel*
2408323 -rw-r--r-- 3 root root 14087155 03-16 07:53 kernel00.rpm
2408270 lrwxrwxrwx 1 root root       33 04-19 14:56 kernel1.rpm -> kernel-2.6.15-1.2025_FC5.i686.rpm
2408323 -rw-r--r-- 3 root root 14087155 03-16 07:53 kernel-2.6.15-1.2025_FC5.i686.rpm
2408323 -rw-r--r-- 3 root root 14087155 03-16 07:53 kernel.rpm

 

我们看一下kernel00.rpm 、kernel.rpm ?kernel-2.6.15-1.2025_FC5.i686.rpm 是不是节点相同?Q他们的大小是不是一P他们的访问日期是不是一P只是他们的文件名不一栗文件名不一h有关p,q能证明其中两个文g是由另一个文仉过ln 创徏而成?/p>

(zhn)可以尝试着用cp ?kernel-2.6.15-1.2025_FC5.i686.rpm 复制为kernel002.rpm Q看看能不能保持节点相同Q?/p>

[root@localhost ~]# ls -li kernel*
2408272 -rw-r--r-- 1 root root 14087155 04-19 16:05 kernel002.rpm
2408323 -rw-r--r-- 3 root root 14087155 03-16 07:53 kernel00.rpm
2408270 lrwxrwxrwx 1 root root       33 04-19 14:56 kernel1.rpm -> kernel-2.6.15-1.2025_FC5.i686.rpm
2408323 -rw-r--r-- 3 root root 14087155 03-16 07:53 kernel-2.6.15-1.2025_FC5.i686.rpm
2408323 -rw-r--r-- 3 root root 14087155 03-16 07:53 kernel.rpm

 

不是是kernel002.rpm 的节点和 kernel-2.6.15-1.2025_FC5.i686.rpm 不一样了Q?/p>


1.24 关于排序的参数的应用Q?br />

ls 昄目录的内Ҏ(gu)Q会文件按a到z的字母顺序显C,优先U如下;

数字 
a-z 
A-Z

 

也就是说如果不加M排序的参敎ͼ文g名第一个字母是数字的,优先显C;其次才是AQZQ然后才是a-zQ下面是几个排序的参敎ͼ大家l习一下就知道了;

在文件的大小排序上,我们要用?S参数Q?
如果是逆序排序Ӟ我们要用?r参数Q?br /> 按最后访问的时候排序,要用?t参数Q?br /> Ҏ(gu)扩展名进行排序,要用到参?-X Q?

 

举例

[root@localhost ~]# ls
123.txt          fonts.scale         kernel                           myinstall.log  upgrade.log
anaconda-ks.cfg  install.log.syslog  mkuml-2004.07.17-ananas.tar.bz2  plinux.txt     upgrade.log.syslog

 

[root@localhost ~]# ls -lS /root
[root@localhost ~]# ls -lS
总计 180
-rw-r--r-- 1 root root 68012 04-04 20:28 mkuml-2004.07.17-ananas.tar.bz2
-rw-r--r-- 1 root root 53992 03-16 08:54 myinstall.log
-rw-r--r-- 1 root root  5423 03-16 08:52 install.log.syslog
drwxr-xr-x 2 root root  4096 04-19 20:04 kernel
-rw------- 1 root root  1375 04-19 15:04 anaconda-ks.cfg
-rw-r--r-- 1 root root   613 03-26 18:41 upgrade.log
-rw-r--r-- 1 root root    21 04-19 15:06 123.txt
-rw-r--r-- 1 root root     2 03-27 02:00 fonts.scale
-rw-r--r-- 1 root root     0 04-19 14:10 plinux.txt
-rw-r--r-- 1 root root     0 03-26 18:39 upgrade.log.syslog

 

举例Q?/p>

[root@localhost ~]# ls -lr
总计 180
-rw-r--r-- 1 root root     0 03-26 18:39 upgrade.log.syslog
-rw-r--r-- 1 root root   613 03-26 18:41 upgrade.log
-rw-r--r-- 1 root root     0 04-19 14:10 plinux.txt
-rw-r--r-- 1 root root 53992 03-16 08:54 myinstall.log
-rw-r--r-- 1 root root 68012 04-04 20:28 mkuml-2004.07.17-ananas.tar.bz2
drwxr-xr-x 2 root root  4096 04-19 20:04 kernel
-rw-r--r-- 1 root root  5423 03-16 08:52 install.log.syslog
-rw-r--r-- 1 root root     2 03-27 02:00 fonts.scale
-rw------- 1 root root  1375 04-19 15:04 anaconda-ks.cfg
-rw-r--r-- 1 root root    21 04-19 15:06 123.txt

 

[root@localhost ~]# ls -lt
总计 180
drwxr-xr-x 2 root root  4096 04-19 20:04 kernel
-rw-r--r-- 1 root root    21 04-19 15:06 123.txt
-rw------- 1 root root  1375 04-19 15:04 anaconda-ks.cfg
-rw-r--r-- 1 root root     0 04-19 14:10 plinux.txt
-rw-r--r-- 1 root root 68012 04-04 20:28 mkuml-2004.07.17-ananas.tar.bz2
-rw-r--r-- 1 root root     2 03-27 02:00 fonts.scale
-rw-r--r-- 1 root root   613 03-26 18:41 upgrade.log
-rw-r--r-- 1 root root     0 03-26 18:39 upgrade.log.syslog
-rw-r--r-- 1 root root 53992 03-16 08:54 myinstall.log
-rw-r--r-- 1 root root  5423 03-16 08:52 install.log.syslog

 


1.25 递归昄目录的文Ӟ-R参数的应用;

递归昄目录下的所有文Ӟ如果该目录下有子目录Q也会把子目录的文g一q显C出来?/p>

比如

[root@localhost ~]# ls -lR /

 

注:也就是把Linux?根目录下的所有文件显C出来,但不会显C隐藏文件。自p着输入上面的命令就知道怎么回事了?/p>


1.26 关于ls 输出内容在终端显C颜色的参数 --colorQ?br />

在一般的情况下,ls输出内容是有颜色的,比如目录是蓝Ԍ压羃文g是红字的昄。如果没有颜Ԍ可以加上参数。当然也可以L颜色?/p>

--color=never  表示输出输出没有彩色
--color=auto  表示自动
--color=always 表示输出内容有彩?

 

举例Q?/strong>

[root@localhost ~]# ls -la --color=never
[root@localhost ~]# ls -la --color=any
[root@localhost ~]# ls -la --color=always

 

如果(zhn)的l端或控制台输出的内Ҏ(gu)有颜Ԍ可以自己来定义。在当前用户的家目录下的.bashrc 中加入下面的一行;

alias ls="ls --color=always"

 


1.27 ls?F参数的示例;

[root@localhost ~]# ls -F
crondw.sh*  kernel/  mkuml-2004.07.17-ananas.tar.bz2  openQreadme.txt@  sun.txt  upgrade.log  youdir/

[root@localhost ~]# ls -lF
总计 92
-rwxr-xr-x 1 root root     0 04-20 14:18 crondw.sh*
drwxr-xr-x 3 root root  4096 04-20 14:17 kernel/
-rw-r--r-- 1 root root 68012 04-04 20:28 mkuml-2004.07.17-ananas.tar.bz2
lrwxrwxrwx 1 root root     7 04-20 14:18 openQreadme.txt -> sun.txt
-rw-r--r-- 1 root root    11 04-20 14:17 sun.txt
-rw-r--r-- 1 root root   613 03-26 18:41 upgrade.log
drwxr-xr-x 6 root root  4096 04-20 14:17 youdir/

 


1.3 通配W在ls命o中的应用Q?br />

* 代表0个或多个字符
[]内部包括M字符
? M单个字符

 

举例Q?/strong>

比如我们昄以k开头的所有文Ӟ?root目录中的Q?/p>

[root@localhost ~]# ls /root/k*
kernel002.rpm  kernel00.rpm  kernel1.rpm  kernel-2.6.15-1.2025_FC5.i686.rpm  kernel.rpm

 

我们昄以数字开头的所有文Ӟ

[root@localhost ~]# ls [0-9]*
123.txt  234.txt  2kexe.txt  6mns.doc

 

下面是一?通配W的CZQ?/p>

[root@localhost ~]# ls *.t?t
123.txt  234.txt  2kexe.txt  333.tot  plinux.txt

 


1.4 获得ls 的帮助;

ls 的用法比较简单,至于更详l的参考,q是查man和help。遇C会的Q就查手册,我也是这么做的?/p>

[root@localhost ~]# ls --help
[root@localhost ~]# man ls
[root@localhost ~]# info ls

 


2、移动文件或目录的命?mv Q?br />

mv 命o是用来移动文件或目录的;有以下几U格式;

#mv file1 file2  注:把file1Ud到file2Q如果file2不存在,则创建file2文g名;
#mv file1 dir 注:把一个文件移动到一个事实存在的目录Q?br /> #mv dir1 dir2   Ud目录dir1 ?dir2 Q如果dir2不存在,则创建它Q?br /> #mv file1 file2 file3 ... ...  dir   Udfile1、file2、file3{多个文件到dir目录中;
#mv dir1 dir2 ... ... dirn   注:Ud目录dir1和dir2{多个目录到dirn目录?/code>

 

参数-i Q表CZhZ互模式;提示警告信息Q?/strong>

举例Q?/strong>

[root@localhost ~]# mv -i 123.txt  234.txt
mvQ是否覆?#8220;234.txt”? y 注:要在q里输入yQ表C允许覆?34.txt文gQ如果是nQ请CZ允许Q?/code>

 

mv 也能和通配W结合一起用,q样能把怼特征的文件移动到某处Q?/strong>

* 代表0个或多个字符
[]内部包括M字符
? M单个字符

 


举例Q比如移动以数字开头的文g或目录到 root目录下的tmp目录中;

[root@localhost ~]# pwd
/root
[root@localhost ~]# mv [0-9]* tmp/
[root@localhost ~]# ls -lh tmp/
总计 4.0K
-rw-r--r-- 1 root root 21 04-19 15:06 234.txt
-rw-r--r-- 1 root root  0 04-19 22:23 2kexe.txt
-rw-r--r-- 1 root root  0 04-19 22:25 333.tot
-rw-r--r-- 1 root root  0 04-19 22:23 6mns.doc

 


3、文件或目录的复制工具cp Q?br />


3.1 cp 的语法和参数

#cp  Qd数选项]   源文件或目录      目标文g或目?/code>

 

注:参数是可选的Q常用参数比?-r,-R,-p,-i Q?/p>

参数说明Q部份)

-a {同?dpR参数一起用;在复制过E中可能保留源文g或目录的属性;
-b l被覆盖的文件做备䆾。比如我们把file1 复制到file2Ӟ如果file2存在Q我们把file2覆盖掉,用这个参数就能同时生成一个file2~的文Ӟ注意文g名后有~l尾
-d 不间接引用符号链接,保持源文件和目标文g之间的硬链接关系Q?br /> -f 删除已存在的目标文gQ?br /> -i 覆盖已存在的目标文g之前l出警告提示Q这是hZ互的选项Q?br /> -l 建立文g链接,而不是复Ӟ
-p 保存源文件或目录的最后修Ҏ(gu)间和模式Q比如要保持目标目录或文件的属主、组、权限和最后访问(或修改)旉Q?br /> -R 复制目录Ӟ包括淅目录下所有的子目录和文gQ?br /> -s 建立源文件的W号链接Q而不是复制源文g。源文g名必ȝl对路径Q?br /> -r 复制目录Ӟ包括淅目录下所有的子目录和文gQ?r选项不同?R之处在于 试打开目的地文件前先删除已存在的目的地文g
-i 人机交互模式Q显法覆盖已存在的文件或目录的警告信息;
-v 在复制之前,输出每个文g的名字;
--help 查看帮助 Q?/p>


3.2 CZ说明cp应用Q?br />


3.21 参数-i的示例;

[root@localhost ~]# ls
anaconda-ks.cfg  install.log.syslog  Kernel.rpm                       mydir       Plist  upgrade.log         youdir
fonts.scale      kernel              mkuml-2004.07.17-ananas.tar.bz2  plinux.txt  sun    upgrade.log.syslog
[root@localhost ~]# pwd
/root

[root@localhost ~]# cp  -i Kernel.rpm Plist
cpQ是否覆?#8220;Plist”? y

 

注:人机交互在数-i的运用;如果源文件复制到目标文gQ如果目标文件存在,则提C告;


3.22 参数-a的示例及说明Q?br />

把源目录复制到另外的一个目标,相当于克隆了一个目录,源目录和目标目录在用L(fng)、权限及修改或访问时间保持一_

[root@localhost ~]# cp -a mydir youdir

 

注:复制目录mydir 到youdir Q如果yourdir目录不存在,则创建。ƈ且把mydir中所有的文g下子目录都复制?yourdir目录中。也是说mydir目录的文件和youdir是一L(fng)?a 参数{同?dpRQƈ且源目录和目标目录的属性(用户l、权限、最后访问及修改旉Q都一_


3.23 参数-b的示例应用;

把源文g复制为目标文Ӟq且试-b参数的运用;

[root@localhost ~]# cp fonts.scale fonts.dir  把一个文件复制ؓ另一个文Ӟ

[root@localhost ~]# cp -bi fonts.scale fonts.dir

cpQ是否覆?#8220;fonts.dir”? y  注:因ؓ用了-i 参数Q如果目标文件存在,则报警提C;

[root@localhost ~]# ls -lh fonts.*
-rw-r--r-- 1 root root 2 04-20 10:24 fonts.dir
-rw-r--r-- 1 root root 2 04-20 10:24 fonts.dir~  注:-b参数q用的效果就是生成已存在目标文g的覆盖之前备份?br /> -rw-r--r-- 1 root root 2 03-27 02:00 fonts.scale

 


3.24 把多个文件复制到目录目录中示例;

比如我们把位于用户当前目录下的fonts.dir、Kernel.rpm和Plist文gQ复制到当前用户所处的目录下的sun目录中;

[root@localhost ~]# pwd  注:判断用户所处的位置Q也是所处的目录Q?br /> /root

[root@localhost ~]# mv fonts.dir Kernel.rpm  Plist  sun/
[root@localhost ~]# ls sun/
fonts.dir  Kernel.rpm  Plist

 

注:如果(zhn)想把多个目录或文g复制到目标目录时Q?zhn)得加参?-R


3.25 复制目录?R参数的应用;

复制一个目录到另一个目录时Q我们要用到 -r?R ?a Q?如果目标目录不存在,则创建它Q如果目标目录存在,则复制源目录到目标目录之下;看看-a?R?r有什么不同?试看看Q?/p>

比如我们在用户当前操作的目录中,有mydir目录Q我们想把mydir复制为medirQ在复制之前medir是不存在的)?/p>

[root@localhost ~]# cp -R mydir medir 注:如果medir目录不存在,则创建medir目录Qƈ且medir目录中的内容和mydir中的一P

 

如果(zhn)把-R参数换成-a参数Q会有什么不同?看看前面的例子所说的Q?/p>


4?目录创徏工具mkdir和删除空目录工具rmdirQ?br />


4.1 mkdir 是目录创建工P


4.11 mkdir语法格式及参敎ͼ

语法格式

#mkdir [参数选项]  目录

 

参数常用的如下:

-m 在创建目录时要授其权限,要和chmod的授权格式;
-p 如果中间目录不存在,则创建它


4.12 参数 -p 的应用示?br />

我们要创Z个目录linuxsirQƈ且linuxsir目录下包含子目录sirdocQsirdoc目录下还?redhat目录Q?/p>

[root@localhost ~]# mkdir -p  linuxsir/sirdoc/redhat

 

举例Q?/strong> -m 参数的应用示例;

我们以不同的权限来创建目录,然后查看我们所创徏目录的属性;q要涉及到chown 来改变目录的权限的格式。我们会在以后讲到chown改变目录或文件的权限。在q里不同的是Q在目录创徏之时q其授权了Q?/p>

[root@localhost ~]# mkdir -m  644 sundir
[root@localhost ~]# mkdir -m 755 moondir
[root@localhost ~]# mkdir -m 000 beinandir
[root@localhost ~]# ls -ld sundir moondir beinandir
d--------- 2 root root 4096 04-20 11:01 beinandir
drwxr-xr-x 2 root root 4096 04-20 11:01 moondir
drw-r--r-- 2 root root 4096 04-20 11:00 sundir

 


4.2 删除I目录工?rmdir 和rm Q?br />

rmdir 是用来删除空目录用的Q如果目录中有文件或子目录,必须先删除文件或子目录,其语法格式如下:

#rmdir Qd数]  目录

 


rmdir 参数常用的有Q?br />

-p 删除目录时是一U一U的时行的,值得注意的是Q首先从最里面的目录开始。下面是一个例子;

[root@localhost ~]# mkdir -p  linuxsir/sirdoc/redhat/ 

注:首先在当前目录下创徏linuxsir目录Q他的子目录是sirdocQsirdoc内又有一个子目录redhat

[root@localhost ~]# rmdir -p linuxsir/sirdoc/redhat/  注:删除linuxsir目录Q要用到参数-p
[root@localhost ~]# ls linuxsir  注:查一下是不是q有q个目录Q?
ls: linuxsir: 没有那个文g或目?/code>

 

rmdir 所删除的目录,每目录中都是空的,没有其它的文件。如果Q何一U的目录有文Ӟ也不能删除。这时?zhn)要用到rm -rf 命o强制删除。不q用rm -rf 删除时有点不安全Q还是用rf -ri 比较好一点,因ؓ在删除的时候,会有警告提示。这对于安全操作来说是很重要的;

[root@localhost ~]# ls -lh sun/  注:q是sun目录Q里面有内容Q?br /> 总计 28K
-rw------- 1 root root 1.4K 04-19 15:04 anaconda-ks.cfg
-rw-r--r-- 1 root root    2 04-20 10:24 fonts.dir
-rw-r--r-- 1 root root    2 03-27 02:00 fonts.scale
-rw-r--r-- 1 root root 5.3K 03-16 08:52 install.log.syslog
-rw-r--r-- 1 root root    0 04-19 20:44 Kernel.rpm
-rw-r--r-- 1 root root    0 04-20 10:20 Plist
[root@localhost ~]# rmdir sun/  注:我们试用rmdir来删除,
rmdir: sun/: 目录非空  

[root@localhost ~]# rm -rf sun/  注:强制用rm -rf 来删除;

[root@localhost ~]# ls sun    注:查是否删除,删除成功Q?br /> ls: sun: 没有那个文g或目?/code>

 


5、创Z个空文g的工P?touch、echo、cat{工P

有时我们Z方便Q可能在控制台或l端下创Z个不存在的空文gQ然后我们再用编辑器来编辑它Q创建空文g有时q有点用。说说也无妨。我们在q里用touch、ech0及cat 工具。其实这些工P创徏文g只是他们的一个小的功能Q我们以后再介绍q些工具Q先说他们创建文件的功能?/p>

注意Q创些文Ӟ在我们操作创建文件之前,q些文g在用户当前操作目录下是不存在的,我们在这里只是创Z个新的文件名Qƈ且它里面没有MI容的;

[root@localhost ~]# ls 123456.txt 654321.txt 98765.txt
ls: 123456.txt: 没有那个文g或目?br /> ls: 654321.txt: 没有那个文g或目?br /> ls: 98765.txt: 没有那个文g或目?/code>

 

[root@localhost ~]# echo > 123456.txt  注:用ech0 来创建,在创Z前在此操作目录下不存?23456.txt文gQ?br /> [root@localhost ~]# ls 123456.txt     注:查看一下看有没有生成?
123456.txt

 

[root@localhost ~]# touch 654321.txt  注:?touch 来创建,在创Z前在此操作目录下不存?54321.txt文gQ?br /> [root@localhost ~]# ls 654321.txt  注:查看一下看有没有生成?
654321.txt

 

[root@localhost ~]# cat > 98765.txt  注:用ech0 来创建,在创Z前在此操作目录下不存?8765.txt 文gQ然后按ctrl+cl合键退出;

[root@localhost ~]# ls 98765.txt   注:查看一下看有没有生成?
98765.txt

 


6、删除文件工具rmQ?br />

rm 是用来删除一个或多个文g的工Pq且能用于删除非I目录。我们前面提C可以加参?rf 可以强制删除一个非I目录?/p>

rm的语法格式;

#rm Qd数选项Q?file1 file2 ... ...
#rm  Qd数选项]  dir1 dir2 dir3 ... ...

 

rm 常用参数Q?/strong>

-f  不显C告或提示信息删除,用的时候需要小心;
-i  删除文gӞ昄警告信息Q要多用Q这h较安全;Ҏ(gu)提示Q输入ypC删除,输入nQ请CZ删除Q?br /> -r?R  表示可以删除整个目录Q包括子目录及所有文ӞQ要心用;

 

[root@localhost ~]# rm -i 123.sh  注:q是删除一个文Ӟ?i参数的示例,有警告提C;

rmQ是否删除一般空文g“123.sh”? y

 

比如我们惛_除mydir目录及所有下U目录和文gQ要有提C的警告信息Q可以用-r参数?i参数的组合;如果(zhn)想l止rm命oQ请按ctrl+cl合健退出rmQ?/p>

[root@localhost ~]# rm -ri mydir/

rmQ是否进入目?#8220;mydir/”? y
rmQ是否进入目?#8220;mydir//youdir”? y
rmQ是否删除一般文?#8220;mydir//youdir/enteruml.sh”?

 

如果(zhn)想没有M警告信息的删除mydir目录下的所有文件及子目录,可以?r?f参数的组合;

[root@localhost ~]# rm -rf mydir

 


7、修Ҏ(gu)件名工具 mv

mv 可以Ud一个文Ӟ或目录)到另一个文Ӟ或目录)Q如果文Ӟ或目录)不存在,则创建它。其实mv q个q程也可以理解ؓ改名q程Q所以说mv工具能修Ҏ(gu)件名和目录名?/p>

#mv 原文件名或目录名  新文件或目录?

 

注意Q?/strong>新文件名或目录名应该不能与现有文件名Q或目录名)同名?/p>

举例Q?/strong>

[root@localhost ~]# ls
crondw.sh  kernel  mkuml-2004.07.17-ananas.tar.bz2  mydir  openQreadme.txt  sun.txt  upgrade.log  youdir

[root@localhost ~]# mv crondw.sh 123.sh  注:Udcrondw.sh ?23.sh Q其实就是把文g名改Z123.sh

[root@localhost ~]# ls
123.sh  kernel  mkuml-2004.07.17-ananas.tar.bz2  mydir  openQreadme.txt  sun.txt  upgrade.log  youdir

 

再看一例mv 修改目录的。当然mv是把文gQ或目录Q从一个地方移到另一个地斏V如果另一地方没有和源文gQ或目录Q同名的Q就创徏。这也相当于改名Q?/p>

[root@localhost ~]# ls
123.sh  kernel  mkuml-2004.07.17-ananas.tar.bz2  mydir  openQreadme.txt  sun.txt  upgrade.log  youdir

[root@localhost ~]# mv kernel/ kernelBak

[root@localhost ~]# ls
123.sh  kernelBak  mkuml-2004.07.17-ananas.tar.bz2  mydir  openQreadme.txt  sun.txt  upgrade.log  youdir


joan 2008-10-08 13:31 发表评论
]]>
讄vi/vim实现打开不同字符~码的文?/title><link>http://www.tkk7.com/joan/articles/233066.html</link><dc:creator>joan</dc:creator><author>joan</author><pubDate>Wed, 08 Oct 2008 02:07:00 GMT</pubDate><guid>http://www.tkk7.com/joan/articles/233066.html</guid><wfw:comment>http://www.tkk7.com/joan/comments/233066.html</wfw:comment><comments>http://www.tkk7.com/joan/articles/233066.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/joan/comments/commentRss/233066.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/joan/services/trackbacks/233066.html</trackback:ping><description><![CDATA[<p>1>说明Q?br /> 默认vi/vim会根据terminal的locale讄Q用相应的字符~码?br /> 如:<br /> # locale<br /> LANG=en_US.UTF-8<br /> LC_CTYPE=zh_CN.UTF-8<br /> LC_NUMERIC="en_US.UTF-8"<br /> LC_TIME="en_US.UTF-8"<br /> LC_COLLATE="en_US.UTF-8"<br /> LC_MONETARY="en_US.UTF-8"<br /> LC_MESSAGES="en_US.UTF-8"<br /> LC_PAPER="en_US.UTF-8"<br /> LC_NAME="en_US.UTF-8"<br /> LC_ADDRESS="en_US.UTF-8"<br /> LC_TELEPHONE="en_US.UTF-8"<br /> LC_MEASUREMENT="en_US.UTF-8"<br /> LC_IDENTIFICATION="en_US.UTF-8"<br /> LC_ALL=<br /> # vim<br /> 查看默认的字W编?br /> :set fileencodings<br /> fileencodings=utf-8,latin1 <br />                 <br />                 <br />                 <br /> 2>实现<br /> 知道了上面这些,当我们在打开一个其它编码的文gӞ只要先设|一下vi/vim的fileencodings值就可以了?br /> (1)动态设|实?br /> # vim<br /> :set fileencodings gb2312,utf-8<br /> 多个字符~码?#8220;Q?#8221;隔开?br /> (2)配置文g静态设|实?br /> 配置一下vi/vim的配|文Ӟ<br /> vi ~/.vimrc<br /> set fileencodings=utf-8,gb2312</p> <img src ="http://www.tkk7.com/joan/aggbug/233066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/joan/" target="_blank">joan</a> 2008-10-08 10:07 <a href="http://www.tkk7.com/joan/articles/233066.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ls命o选项详解http://www.tkk7.com/joan/articles/232889.htmljoanjoanTue, 07 Oct 2008 04:41:00 GMThttp://www.tkk7.com/joan/articles/232889.htmlhttp://www.tkk7.com/joan/comments/232889.htmlhttp://www.tkk7.com/joan/articles/232889.html#Feedback0http://www.tkk7.com/joan/comments/commentRss/232889.htmlhttp://www.tkk7.com/joan/services/trackbacks/232889.html
  -a 列出目录下的所有文Ӟ包括?. 开头的隐含文g?br />
  -b 把文件名中不可输出的字符用反斜杠加字W编?p在C语言里一?的Ş式列出?br />
  -c 输出文g?i 节点的修Ҏ(gu)_q以此排序?br />
  -d 目录象文g一hC,而不是显C其下的文g?br />
  -e 输出旉的全部信息,而不是输出简略信息?br />
  -f -U 对输出的文g不排序?br />
  -g 无用?br />
  -i 输出文g?i 节点的烦引信息?br />
  -k ?k 字节的Ş式表C文件的大小?br />
  -l 列出文g的详l信息?br />
  -m 横向输出文g名,q以“Q?#8221;作分格符?br />
  -n 用数字的 UID,GID 代替名称?br />
  -o 昄文g的除l信息外的详l信息?br />
  -p -F 在每个文件名后附上一个字W以说明该文件的cdQ?#8220;*”表示可执行的普?br />
  文gQ?#8220;/”表示目录Q?#8220;@”表示W号链接Q?#8220;|”表示FIFOsQ?#8220;=”表示?br />
  接字(sockets)?br />
  -q ?代替不可输出的字W?br />
  -r 对目录反向排序?br />
  -s 在每个文件名后输文g的大?br />
  -t 以时间排序?br />
  -u 以文件上ơ被讉K的时间排序?br />
  -x 按列输出Q横向排序?br />
  -A 昄?“.”?#8220;..”外的所有文件?br />
  -B 不输Z “~”l尾的备份文件?br />
  -C 按列输出Q纵向排序?br />
  -G 输出文g的组的信息?br />
  -L 列出链接文g名而不是链接到的文件?br />
  -N 不限制文仉度?br />
  -Q 把输出的文g名用双引hh?br />
  -R 列出所有子目录下的文g?br />
  -S 以文件大排序?br />
  -X 以文件的扩展?最后一?. 后的字符)排序?br />
  -1 一行只输出一个文件?br />
  --color=no 不显C彩色文件名

  --help 在标准输Z昄帮助信息?br />
  --version 在标准输Z输出版本信息q出?

joan 2008-10-07 12:41 发表评论
]]>
Shell W号(载录)http://www.tkk7.com/joan/articles/232856.htmljoanjoanTue, 07 Oct 2008 02:51:00 GMThttp://www.tkk7.com/joan/articles/232856.htmlhttp://www.tkk7.com/joan/comments/232856.htmlhttp://www.tkk7.com/joan/articles/232856.html#Feedback0http://www.tkk7.com/joan/comments/commentRss/232856.htmlhttp://www.tkk7.com/joan/services/trackbacks/232856.htmlShell W号
  针对许多频繁使用?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%C3%FC%C1%EE">命o行参敎ͼShell 提供了相应的W号 或记号作为简写。?zhn)只需输入q些W号来代替相应的参数?br />
  如上所qͼ~ 表示(zhn)的 home 目录。与之类似的写Ş?~username 表示 username ?home 目录。例如,~joe 表示 joe ?home 目录Q所以,要将文g?joe ?doc 目录复制到?zhn)?info 目录Q?zhn)可以输入下面的命令?
代码:
$ cp ~joe/doc/report.txt ~/info
  假设 joe ?home 目录位于 /guestsQ而?zhn)?home 目录?/staff/bobrQ~joe 由 /guests/joe 替换Q?~ 则变?/staff/bobrQ最后生命?cp /guests/joe/doc/report.txt /staff/bobr/info?br />
  另一个有用的W号?..Q两个点PQ这是当前目录的父目录的写。?.. ?.Q当前工作目录的写符PQ?zhn)可以引用文g中相对于当前工作目录的文件和目录?br />
  例如Q如果?zhn)的当前工作目录?~/jane/projects/lambdaQ那么简?../.. 表示向上两目录的目录,?~/jane。要表示包含 ~/jane 的目录,(zhn)可以?../../../Q?#8220;向上三目录”Q或路径 ~jane/../。后面的q个路径表示?~jane 开始,然后转到上一U目录?br />
  要将文g复制到?zhn)的当前目录,不需要指定目标目录,可以直接使用 .Q?#8220;?#8221;Q来表示Q?
代码:$ cp -pr /path/to/lots/of/stuff
  前面的命令将 /path/to/lots/of/stuff 目录递归地复制到(zhn)的当前目录Qƈ保持其原始的旉和日期戳。引?.. ?. 的\径名UCؓ相对路径名。以 /Q正斜杠Q或 ~QL符P开头的路径名称为绝对\径名Q因为?zhn)是从文gpȝ的顶端、或从一个目录层ơ结构的端开始来引用相应的文件?br />
用L号快速修改输错的命o

假如打错了一个很长的命oQ需要重新输入是十分沮的事情。例如:

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

  的例子中Qname 被错误的输成?naem Q我们能够用下面的L符h替换Q?br />
  $ ^em^me^

  find . -name "*.txt" -print


验?zhn)的工?/strong>

  如果(zhn)想要查看命令行W号扩展后的l果Q可以?echo 命oQ?
代码:$ echo ~joe/doc/report.txt ~/info
/guests/joe/doc/report.txt /staff/bobr/info

$ echo $SHELL
/bin/zsh

$ ls
architecture.txt  Services.pdf
services.txt      Schema.pdf

$ echo *.txt
architecture.txt services.txt
  echo 命o完整地表达(zhn)在命o行中输入的内宏V然而,因ؓ Shell 会在调用ME序之前Q对Q大多数Q命令行参数q行扩展Q所以该命o打印出所有替换的l果。(Shell 环境变量 $SHELL 包含当前正在q行?Shell 的名U。)




joan 2008-10-07 10:51 发表评论
]]>
Linux内核代码构架?/title><link>http://www.tkk7.com/joan/articles/232652.html</link><dc:creator>joan</dc:creator><author>joan</author><pubDate>Mon, 06 Oct 2008 06:07:00 GMT</pubDate><guid>http://www.tkk7.com/joan/articles/232652.html</guid><wfw:comment>http://www.tkk7.com/joan/comments/232652.html</wfw:comment><comments>http://www.tkk7.com/joan/articles/232652.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/joan/comments/commentRss/232652.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/joan/services/trackbacks/232652.html</trackback:ping><description><![CDATA[<p> </p> <img height="1536" alt="" src="http://www.testage.net/attachments/2008/04/8_200804251414031acVI.jpg" width="2048" border="0" /> <img src ="http://www.tkk7.com/joan/aggbug/232652.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/joan/" target="_blank">joan</a> 2008-10-06 14:07 <a href="http://www.tkk7.com/joan/articles/232652.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>构徏linux下IDE环境--Eclipse?/title><link>http://www.tkk7.com/joan/articles/232598.html</link><dc:creator>joan</dc:creator><author>joan</author><pubDate>Mon, 06 Oct 2008 01:44:00 GMT</pubDate><guid>http://www.tkk7.com/joan/articles/232598.html</guid><wfw:comment>http://www.tkk7.com/joan/comments/232598.html</wfw:comment><comments>http://www.tkk7.com/joan/articles/232598.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/joan/comments/commentRss/232598.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/joan/services/trackbacks/232598.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="0" width="90%" align="center" border="0"> <tbody> <tr> <th class="f24"> <h1><span style="color: #000000"><span style="color: #003366">构徏linux下IDE环境--Eclipse?/span></span></h1> </th> </tr> <tr> <td align="center" height="20"><span style="color: #000000"></span></td> </tr> <tr> <td><span style="color: #000000"><br /> </span></td> </tr> <tr> <td class="l17"><font class="f14" id="zoom"><font color="#cccccc"><!-- 正文begin --><!--startfragment --><span style="color: #000000"><span style="color: #003366"> <br /> <!-- message --></span></span> <div><span style="color: #000000"><span style="color: #003366">摘要 <br /> <br /> Eclipse是一由ibmQborland{资助的开源开发环境;其功能可以通过插g方式q行扩展Q本文在linux下构建java、c、cQ+的IDE?<br /> <br /> 我用的环境是 red hat linux 9 Q自~译gnome2.4Q?<br /> <br /> 一Q下载所需软gQ所有下载的软g均放?opt下) <br /> <br /> 先下?EclipseQ网址?</span></span><a target="_blank"><span style="color: #000000"><span style="color: #003366">http://www.eclipse.org</span></span></a><span style="color: #000000"><span style="color: #003366"> 目前QEclipse的最新版本ؓ2.1.1Q?.0版也正在试中。我使用eclipse2.1Q下载其gtk版本Qeclipse-SDK-2.1.1-linux-gtk.zip <br /> <br /> 执行 Eclipse是须用到JDKQ但Eclipse的安装程序和Red Hat Linux 9 里没有包含JDKQSun 最新版本的 JDK可到 </span></span><a target="_blank"><span style="color: #000000"><span style="color: #003366">http://java.sun.com下蝲Q在此我们用的是sun</span></span></a><span style="color: #000000"><span style="color: #003366"> jdk (J2SE) 1.4.2_01版(也可使用IBM的jdkQ?<br /> <br /> 要在Eclipse 上面开发C/C++E序Q需要另外安装plug-insQ在此我们用的是C/C++ Development ToolsQCDTQ。CDT 整合了gcc、make、gdb{GUN 工具Q(CDT 与Eclipse 中内建的JDTQJava 开发环境)比v来,功能q差得远。例如,在JDT 中相当好用的Refactor、Refactoring、Organize Imports{在CDT 中都没有。)CDT 可从</span></span><a target="_blank"><span style="color: #000000"><span style="color: #003366">http://www.eclipse.org/cdt/</span></span></a><span style="color: #000000"><span style="color: #003366"> 下蝲Q目前最新版本ؓCDT 1.1 GA2 . <br /> <br /> ?Q安?<br /> <br /> 1.׃cdt需要gcc{工P所以要先把red hat9的Y件开发包装上Q?<br /> <br /> 2.安装JDKQ需以rootw分安装Q: <br /> <br /> [root@redarmy] chmod Qx j2sdk-1_4_2_01-linux-i586-rpm.bin<br /> [root@redarmy] ./j2sdk-1_4_2_01-linux-i586-rpm.bin<br /> [root@redarmy] rpm –ivh j2sdk-1_4_2_01-linux-i586-rpm.bin<br /> <br /> <br /> <br /> 安装好的JDK 会存?/usr/java/j2sdk1.4.2_01 目录中?<br /> <br /> 讑֮JAVA_HOME,CLASSPATH,PATH; ?etc/profile文g最后加如下四行Q?<br /> <br /> export JAVA_HOME = /usr/java/j2sdk1.4.2_01 <br /> export PATH = $JAVA_HOME/bin:$PATH<br /> CLASSPATH=.:/usr/java/j2sdk1.4.2_01/lib/tools.jar:$CLASSPATH<br /> export CLASSPATH<br /> <br /> <br /> <br /> 3.安裝Eclipse <br /> <br /> 在此我把Eclipse安装?/opt 下,安装Eclipse很简单,只要把下载回来的压羃包解压就可以了;解压后得到eclipse目录Q?<br /> <br /> [root@redarmy] unzip –d /opt eclipse-SDK-2.1.1-linux-gtk.zip <br /> <br /> 每一个帐号都可以执行EclipseQ我写了个小脚本Qeclipse.shQ: <br /> <br /> #!/bin/bash<br /> #<br /> # 执行 eclipse 2.1.1 <br /> #<br /> export JAVA_HOME=/usr/java/j2sdk1.4.2_01<br /> export CLASSPATH=/usr/java/j2sdk1.4.2_01/lib<br /> /opt/eclipse/eclipse -vm /usr/java/j2sdk1.4.2_01/bin/java -data ~/workspace &<br /> # -vm 参数用以指定使用哪一?jvm 来执行EclipseQ?br /> # -date参数用以指定Eclipse的数据目录。在此指定其存在用户根目?~)下的workspace目录?br /> <br /> <br /> <br /> eclipse.sh 复制?usr/local/bin中,qؓ它加上权?55Q现在执?eclipse.sh 卛_启动 Eclipse?<br /> <br /> [root@redarmy] cp eclipse.sh /usr/local/bin<br /> [root@redarmy] chmod 755 /usr/local/bin/eclipse.sh<br /> <br /> <br /> <br /> eclipsed到桌面。首先,在桌面上按下鼠标右键Q在弹出菜单中选择“新增启动”Q之后分別在“名称”中输入Eclipse?#8220;命o”中填 /usr/local/bin/eclipse.shQ然后再为它随便找个喜欢的图标(我用的是/opt/eclipse/icon.xpmQ?再后?“定”Q桌面上有eclipse的快h式了Q以后可以直接双击这个图标启动Eclipse?<br /> <br /> Eclipse 安装好后Q已l内Zjava开发环境(JDTQ就可以直接开发Java E序?<br /> <br /> 4.安装cdtQCDT 1.1 GA 目前只支持Eclipse 2.1 版?<br /> <br /> 下载的包解压,会得到features 和plugins q两个目?<br /> <br /> [root@redarmy] unzip –d /opt org.eclipse.cdt-linux.gtk_1.1.0.bin.dist.zip <br /> <br /> 分别这两个目录中的所有文件分别剪?opt/eclipse下的对应目录里,卛_。(Eclipse 的插件安裝方法几乎都q样安装Q?把文件下载后Q?直接解到eclipse所安装的目录中对应的features 和plugins 中即可。) <br /> <br /> 三:?<br /> <br /> 要是不习惯,eclipse英文环境Q可以在eclipse.org的主站上下,它的语言包;装了语言包后Q不光菜单成中文了,它的帮助文档也成中文了,爽吧^_^ </span></span></div> <!-- 正文end --><br /> <span style="color: #000000"><span style="color: #003366">(http://www.fanqiang.com)<br /> </span></span></font></font></td> </tr> </tbody> </table> <img src ="http://www.tkk7.com/joan/aggbug/232598.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/joan/" target="_blank">joan</a> 2008-10-06 09:44 <a href="http://www.tkk7.com/joan/articles/232598.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 2.6 中的文g?/title><link>http://www.tkk7.com/joan/articles/214335.html</link><dc:creator>joan</dc:creator><author>joan</author><pubDate>Fri, 11 Jul 2008 13:31:00 GMT</pubDate><guid>http://www.tkk7.com/joan/articles/214335.html</guid><wfw:comment>http://www.tkk7.com/joan/comments/214335.html</wfw:comment><comments>http://www.tkk7.com/joan/articles/214335.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/joan/comments/commentRss/214335.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/joan/services/trackbacks/214335.html</trackback:ping><description><![CDATA[<p>     本文的目的是惛_助读者理?Linux 2.6中文仉的概念以?Linux 2.6 都提供了何种数据l构以及关键的系l调用来实现文g锁,从而可以帮助读者更好地使用文g锁来解决多个q程d同一个文件的互斥问题。本文主要描qC Linux 中各cL仉的概念,使用场景Q内怸描述文g锁的数据l构以及与文仉密切相关的系l调用等内容?/p> <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES--> <p>在多d操作pȝ环境中,如果一个进E尝试对正在被其他进E读取的文gq行写操作,可能会导致正在进行读操作的进E读取到一些被破坏或者不完整的数据;如果两个q程q发对同一个文件进行写操作Q可能会D该文仉到破坏。因此,Z避免发生q种问题Q必要采用某种机制来解军_个进Eƈ发访问同一个文件时所面(f)的同步问题,由此而生了文g加锁斚w的技术?/p> <p>早期?UNIX pȝ只支持对整个文gq行加锁Q因此无法运行数据库之类的程序,因ؓ此类E序需要实现记录的加锁。在 System V Release 3 中,通过 fcntl 提供了记录的加锁,此后发展成ؓ POSIX 标准的一部分。本文将Z 2.6.23 版本的内核来探讨 Linux 中文仉的相x术?/p> <p><a name="Linux 中的文g?><span id="4mmueeg" class="atitle">Linux 中的文g?/span></a></p> <p>Linux 支持的文仉技术主要包括劝告锁Qadvisory lockQ和强制锁(mandatory lockQ这两种。此外,Linux 中还引入了两U强刉的变UŞ式:׃n模式强制锁(share-mode mandatory lockQ和U借锁QleaseQ?/p> <p>?Linux 中,不论q程是在使用劝告锁还是强刉Q它都可以同时用共享锁和排他锁Q又UCؓ读锁和写锁)。多个共享锁之间不会怺q扰Q多个进E在同一时刻可以对同一个文件加׃n锁。但是,如果一个进E对该文件加了排他锁Q那么其他进E则无权再对该文件加׃n锁或者排他锁Q直到该排他锁被释放。所以,对于同一个文件来_它可以同时拥有很多读者,但是在某一特定时刻Q它只能拥有一个写者,它们之间的兼容关pd?1 所C?/p> <br /> <a name="?1. 锁间的兼容关p?><strong>?1. 锁间的兼容关p?/strong></a><br /> <table class="data-table-1" cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td style="vertical-align: top"> <td style="vertical-align: top; text-align: center" colspan="2"><strong>是否满h</strong> </td> </tr> <tr> <td style="vertical-align: top; text-align: center"><strong>当前加上的锁</strong> </td> <td style="vertical-align: top; text-align: center">׃n?</td> <td style="vertical-align: top; text-align: center">排他?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">?</td> <td style="vertical-align: top; text-align: center">?</td> <td style="vertical-align: top; text-align: center">?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">׃n?</td> <td style="vertical-align: top; text-align: center">?</td> <td style="vertical-align: top; text-align: center">?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">排他?</td> <td style="vertical-align: top; text-align: center">?</td> <td style="vertical-align: top; text-align: center">?</td> </tr> </tbody> </table> <br /> <p><a name="劝告?><span id="us2uecw" class="smalltitle">劝告?/span></a></p> <p>劝告锁是一U协同工作的锁。对于这一U锁来说Q内核只提供加锁以及文件是否已l加锁的手段Q但是内核ƈ不参与锁的控制和协调。也是_如果有进E不遵守“游戏规则”Q不查目标文件是否已l由别的q程加了锁就往其中写入数据Q那么内核是不会加以L的。因此,劝告锁ƈ不能Lq程Ҏ(gu)件的讉KQ而只能依靠各个进E在讉K文g之前查该文g是否已经被其他进E加锁来实现q发控制。进E需要事先对锁的状态做一个约定,q根据锁的当前状态和怺关系来确定其他进E是否能Ҏ(gu)件执行指定的操作。从q点上来_劝告锁的工作方式与用信号量保护临界区的方式非常cM?/p> <p>劝告锁可以对文g的Q意一个部分进行加锁,也可以对整个文gq行加锁Q甚臛_以对文g来增大的部分也q行加锁。由于进E可以选择Ҏ(gu)件的某个部分q行加锁Q所以一个进E可以获得关于某个文件不同部分的多个锁?/p> <p><a name="强制?><span id="w46cue8" class="smalltitle">强制?/span></a></p> <p>与劝告锁不同Q强刉是一U内核强刉用的文g锁,它是?System V Release 3 开始引入的。每当有pȝ调用 open()、read() 以及write() 发生的时候,内核都要查ƈ保q些pȝ调用不会q反在所讉K文g上加的强刉U束。也是_如果有进E不遵守游戏规则Q硬要往加了锁的文g中写入内容,内核׃加以LQ?/p> <p>如果一个文件已l被加上了读锁或者共享锁Q那么其他进E再对这个文件进行写操作׃被内栔R止;</p> <p>如果一个文件已l被加上了写锁或者排他锁Q那么其他进E再对这个文件进行读取或者写操作׃被内栔R止?/p> <p>如果其他q程试图讉K一个已l加有强刉的文Ӟq程行ؓ取决于所执行的操作模式和文g锁的cdQ归U_?2 所C:</p> <br /> <a name="?2. q行对已加强刉的文件进行操作时的行?><strong>?2. q行对已加强刉的文件进行操作时的行?/strong></a><br /> <table class="data-table-1" cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td style="vertical-align: top; text-align: center">当前锁类?</td> <td style="vertical-align: top; text-align: center">d?</td> <td style="vertical-align: top; text-align: center">d?</td> <td style="vertical-align: top; text-align: center">非阻塞读 </td> <td style="vertical-align: top; text-align: center">非阻塞写 </td> </tr> <tr> <td style="vertical-align: top; text-align: center">读锁 </td> <td style="vertical-align: top; text-align: center">正常d数据 </td> <td style="vertical-align: top; text-align: center">d </td> <td style="vertical-align: top; text-align: center">正常d数据 </td> <td style="vertical-align: top; text-align: center">EAGAIN </td> </tr> <tr> <td style="vertical-align: top; text-align: center">写锁 </td> <td style="vertical-align: top; text-align: center">d </td> <td style="vertical-align: top; text-align: center">d </td> <td style="vertical-align: top; text-align: center">EAGAIN </td> <td style="vertical-align: top; text-align: center">EAGAIN </td> </tr> </tbody> </table> <br /> <p>需要注意的是,如果要访问的文g的锁cd与要执行的操作存在冲H,那么采用d?写操作的q程会被dQ而采用非d?写操作的q程则不会阻塞,而是立即q回 EAGAIN?/p> <p>另外Qunlink() pȝ调用q不会受到强刉的媄响,原因在于一个文件可能存在多个硬链接Q此时删除文件时q不会修Ҏ(gu)件本w的内容Q而是只会改变其父目录?dentry 的内宏V?/p> <p>然而,在有些应用中q不适合使用强制锁,所以烦引节点结构中?i_flags 字段中定义了一个标志位MS_MANDLOCK用于有选择地允许或者不允许对一个文件用强刉。在 super_block l构中,也可以将 s_flags q个标志|ؓ1或?Q用以表C整个设备上的文件是否允怋用强刉?/p> <p>要想对一个文仉用强刉Q必L照以下步骤执行:</p> <p>使用 -o mand 选项来挂载文件系l。这样在执行 mount() pȝ调用Ӟ会传?MS_MANDLOCK 标记Q从而将 super_block l构中的 s_flags 讄?1Q用来表C在q个文gpȝ上可以采用强刉。例如:</p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"># mount -o mand /dev/sdb7 /mnt # mount | grep mnt /dev/sdb7 on /mnt type ext3 (rw,mand) </pre> </td> </tr> </tbody> </table> <br /> <p>1.修改要加强制锁的文g的权限:讄 SGID 位,q清除组可执行位。这U组合通常来说是毫无意义的Q系l用来表C文g被加了强刉。例如:</p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"># touch /mnt/testfile # ls -l /mnt/testfile -rw-r--r-- 1 root root 0 Jun 22 14:43 /mnt/testfile # chmod g+s /mnt/testfile # chmod g-x /mnt/testfile # ls -l /mnt/testfile -rw-r-Sr-- 1 root root 0 Jun 22 14:43 /mnt/testfile </pre> </td> </tr> </tbody> </table> <br /> <p>2.使用 fcntl() pȝ调用对该文gq行加锁或解锁操作?/p> <p><strong><em>1.3. ׃n模式?/em> </strong></p> <p>Linux 中还引入了两U特D的文g锁:׃n模式强制锁和U借锁。这两种文g锁可以被看成是强刉的两U变UŞ式。共享模式强刉可以用于某些U有|络文gpȝQ如果某个文件被加上了共享模式强刉Q那么其他进E打开该文件的时候不能与该文件的׃n模式强制锁所讄的访问模式相冲突。但是由于可UL性不好,因此q不使用q种锁?/p> <p><a name="U借锁"><span id="caasaca" class="smalltitle">U借锁</span></a></p> <p>采用强制锁之后,如果一个进E对某个文g拥有写锁Q只要它不释放这个锁Q就会导致访问该文g的其他进E全部被d或不断失败重试;即该进E只拥有读锁Q也会造成后箋更新该文件的q程的阻塞。ؓ了解册个问题,Linux 中采用了一U新型的U借锁?/p> <p>当进E尝试打开一个被U借锁保护的文件时Q该q程会被dQ同Ӟ在一定时间内拥有该文件租借锁的进E会收到一个信受收C号之后,拥有该文件租借锁的进E会首先更新文gQ从而保证了文g内容的一致性,接着Q该q程释放q个U借锁。如果拥有租借锁的进E在一定的旉间隔内没有完成工作,内核׃自动删除q个U借锁或者将该锁q行降Q从而允许被d的进El工作?/p> <p>pȝ默认的这D间隔时间是 45 U钟Q定义如下:</p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> 137 int lease_break_time = 45; </pre> </td> </tr> </tbody> </table> <br /> <p>q个参数可以通过修改 /proc/sys/fs/lease-break-time q行调节Q当Ӟ/proc/sys/fs/leases-enable 必须?1 才行Q?/p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <br /> <br /> <p><a name="Linux 内核中关于文仉的实?><span id="6cksiss" class="atitle">Linux 内核中关于文仉的实?/span></a></p> <p>?Linux 内核中,所有类型的文g锁都是由数据l构 file_lock 来描q的Qfile_lock l构是在 文g中定义的Q内容如下所C:</p> <br /> <a name="清单 1. file_lock l构"><strong>清单 1. file_lock l构</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> 811 struct file_lock { 812 struct file_lock *fl_next; /* singly linked list for this inode */ 813 struct list_head fl_link; /* doubly linked list of all locks */ 814 struct list_head fl_block; /* circular list of blocked processes */ 815 fl_owner_t fl_owner; 816 unsigned int fl_pid; 817 wait_queue_head_t fl_wait; 818 struct file *fl_file; 819 unsigned char fl_flags; 820 unsigned char fl_type; 821 loff_t fl_start; 822 loff_t fl_end; 823 824 struct fasync_struct * fl_fasync; /* for lease break notifications */ 825 unsigned long fl_break_time; /* for nonblocking lease breaks */ 826 827 struct file_lock_operations *fl_ops; /* Callbacks for filesystems */ 828 struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */ 829 union { 830 struct nfs_lock_info nfs_fl; 831 struct nfs4_lock_info nfs4_fl; 832 struct { 833 struct list_head link; /* link in AFS vnode's pending_locks list */ 834 int state; /* state of grant or error if -ve */ 835 } afs; 836 } fl_u; 837 }; </pre> </td> </tr> </tbody> </table> <br /> <p>?3 单描qC file_lock l构中的各个字段所表示的含义?/p> <br /> <a name="?3. file_lock 数据l构的字D?><strong>?3. file_lock 数据l构的字D?/strong></a><br /> <table class="data-table-1" cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td style="vertical-align: top; text-align: center">cd </td> <td style="vertical-align: top; text-align: center">字段 </td> <td style="vertical-align: top; text-align: center">字段描述 </td> </tr> <tr> <td style="vertical-align: top; text-align: center">struct file_lock* </td> <td style="vertical-align: top; text-align: center">fl_next </td> <td style="vertical-align: top; text-align: center">与烦引节点相关的锁列表中下一个元?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">struct list_head </td> <td style="vertical-align: top; text-align: center">fl_link </td> <td style="vertical-align: top; text-align: center">指向z跃列表或者被d列表 </td> </tr> <tr> <td style="vertical-align: top; text-align: center">struct list_head </td> <td style="vertical-align: top; text-align: center">fl_block </td> <td style="vertical-align: top; text-align: center">指向锁等待列?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">struct files_struct * </td> <td style="vertical-align: top; text-align: center">fl_owner </td> <td style="vertical-align: top; text-align: center">锁拥有者的 files_struct </td> </tr> <tr> <td style="vertical-align: top; text-align: center">unsigned int </td> <td style="vertical-align: top; text-align: center">fl_pid </td> <td style="vertical-align: top; text-align: center">q程拥有者的 pid </td> </tr> <tr> <td style="vertical-align: top; text-align: center">wait_queue_head_t </td> <td style="vertical-align: top; text-align: center">fl_wait </td> <td style="vertical-align: top; text-align: center">被阻塞进E的{待队列 </td> </tr> <tr> <td style="vertical-align: top; text-align: center">struct file * </td> <td style="vertical-align: top; text-align: center">fl_file </td> <td style="vertical-align: top; text-align: center">指向文g对象 </td> </tr> <tr> <td style="vertical-align: top; text-align: center">unsigned char </td> <td style="vertical-align: top; text-align: center">fl_flags </td> <td style="vertical-align: top; text-align: center">锁标?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">unsigned char </td> <td style="vertical-align: top; text-align: center">fl_type </td> <td style="vertical-align: top; text-align: center">锁类?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">loff_t </td> <td style="vertical-align: top; text-align: center">fl_start </td> <td style="vertical-align: top; text-align: center">被锁区域的开始位U?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">loff_t </td> <td style="vertical-align: top; text-align: center">fl_end </td> <td style="vertical-align: top; text-align: center">被锁区域的结束位U?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">struct fasync_struct * </td> <td style="vertical-align: top; text-align: center">fl_fasync </td> <td style="vertical-align: top; text-align: center">用于U借暂停通知 </td> </tr> <tr> <td style="vertical-align: top; text-align: center">unsigned long </td> <td style="vertical-align: top; text-align: left">fl_break_time </td> <td style="vertical-align: top; text-align: center">U借的剩余旉 </td> </tr> <tr> <td style="vertical-align: top; text-align: center">struct file_lock_operations * </td> <td style="vertical-align: top; text-align: center">fl_ops </td> <td style="vertical-align: top; text-align: center">指向文g锁操?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">struct lock_manager_operations * </td> <td style="vertical-align: top; text-align: center">fl_mops </td> <td style="vertical-align: top; text-align: center">指向锁管理操?</td> </tr> <tr> <td style="vertical-align: top; text-align: center">union </td> <td style="vertical-align: top; text-align: center">fl_u </td> <td style="vertical-align: top; text-align: center">文gpȝ特定信息 </td> </tr> </tbody> </table> <br /> <p>一?file_lock l构是一?#8220;?#8221;Q结构中?fl_file 指向目标文件的 file l构Q?fl_start ?fl_end 则确定了该文件要加锁的一个区域。当q程发出pȝ调用来请求对某个文g加排他锁Ӟ如果q个文g上已l加上了׃n锁,那么排他锁请求不能被立即满Q这个进E必d要被d。这Pq个q程p放进了等待队列,file_lock l构中的 fl_wait 字段指向这个等待队列。指向磁盘上相同文g的所?file_lock l构会被链接成一个单链表 file_lock_listQ烦引节点结构中?i_flock 字段会指向该单链表结构的首元素,fl_next 用于指向该链表中的下一个元素;当前pȝ中所有被hQ但是未被允许的锁被串成一个链表:blocked_list。fl_link 字段指向q两个列表其中一个。对于被d列表Qblocked_listQ上的每一个锁l构来说Qfl_next 字段指向与该锁生冲H的当前正在使用的锁。所有在{待同一个锁的那些锁会被链接hQ这需要用到字D?fl_blockQ新来的{待者会被加入到{待列表的尾部?此外Qfl_type 表示锁的性质Q如诅R写。fl_flags 是一些标志位Q在 linux 2.6中,q些标志位的定义如下所C:</p> <br /> <a name="清单 2. 标志位的定义"><strong>清单 2. 标志位的定义</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> 773 #define FL_POSIX 1 774 #define FL_FLOCK 2 775 #define FL_ACCESS 8 /* not trying to lock, just looking */ 776 #define FL_EXISTS 16 /* when unlocking, test for existence */ 777 #define FL_LEASE 32 /* lease held on this file */ 778 #define FL_CLOSE 64 /* unlock on close */ 779 #define FL_SLEEP 128 /* A blocking lock */ </pre> </td> </tr> </tbody> </table> <br /> <p>FL_POSIX 锁是通过pȝ调用 fcntl() 创徏的;?FL_FLOCK 锁是通过pȝ调用 flock()创徏的(详细内容请参见后文中的介l)。FL_FLOCK 锁永q都和一个文件对象相兌Q打开q个文g的进E拥有该 FL_FLOCK 锁。当一个锁被请求或者允许的时候,内核׃把这个进E在同一个文件上的锁都替换掉。FL_POSIX 锁则一直与一个进E以及一个烦引节点相兌。当q程M或者文件描q符被关闭的时候,q个锁会被自动释放?/p> <p>对于强制锁来_?Linux 中,内核提供?inline 函数 locks_verify_locked() 用于目标文件或者目标文件所在的讑֤是否允许使用强制锁,q且查该讑֤是否已经加上了锁Q相兛_数如下所C:</p> <br /> <a name="清单 3. 与强刉相关的函?><strong>清单 3. 与强刉相关的函?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> 166 #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg)) 173 #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) 1047 /** 1048 * locks_mandatory_locked - Check for an active lock 1049 * @inode: the file to check 1050 * 1051 * Searches the inode's list of locks to find any POSIX locks which conflict. 1052 * This function is called from locks_verify_locked() only. 1053 */ 1054 int locks_mandatory_locked(struct inode *inode) 1055 { 1056 fl_owner_t owner = current->files; 1057 struct file_lock *fl; 1058 1059 /* 1060 * Search the lock list for this inode for any POSIX locks. 1061 */ 1062 lock_kernel(); 1063 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 1064 if (!IS_POSIX(fl)) 1065 continue; 1066 if (fl->fl_owner != owner) 1067 break; 1068 } 1069 unlock_kernel(); 1070 return fl ? -EAGAIN : 0; 1071 } 1368 /* 1369 * Candidates for mandatory locking have the setgid bit set 1370 * but no group execute bit - an otherwise meaningless combination. 1371 */ 1372 #define MANDATORY_LOCK(inode) \ 1373 (IS_MANDLOCK(inode) && ((inode)->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) 1374 1375 static inline int locks_verify_locked(struct inode *inode) 1376 { 1377 if (MANDATORY_LOCK(inode)) 1378 return locks_mandatory_locked(inode); 1379 return 0; 1380 } </pre> </td> </tr> </tbody> </table> <br /> <p>q里Q函?locks_verify_locked() 利用?MANDATORY_LOCK 来检目标文件是否允许加锁,条g包括Q该文g所在的讑֤?super_block l构中的 s_flags 必须被置?1Q该文g?SGID 被置?1 而且同组可执行位被清 0。如果允许,则调用函数l(f)ocks_mandatory_locked()Q该函数从烦引节点的锁列表中查找是否存在有与其相冲突的锁Q即是否已经加上了锁?/p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <br /> <br /> <p><a name="Linux 中关于文仉的系l调?><span id="oksssa2" class="atitle">Linux 中关于文仉的系l调?/span></a></p> <p>q里介绍?Linux 中与文g锁关pd切的两个pȝ调用Qflock() ?fcntl()。劝告锁既可以通过pȝ调用 flock() 来实玎ͼ也可以通过pȝ调用 fcntl() 来实现。flock() pȝ调用是从 BSD 中衍生出来的Q在传统的类 UNIX 操作pȝ中,pȝ调用flock() 只适用于劝告锁。但是,Linux 2.6内核利用pȝ调用 flock() 实现了我们前面提到的Ҏ(gu)的强刉Q共享模式强刉。另外,flock() 只能实现Ҏ(gu)个文件进行加锁,而不能实现记录的加锁。系l调用fcntl() W合 POSIX 标准的文仉实现Q它也是非常强大的文仉Qfcntl() 可以实现对纪录进行加锁?/p> <p><a name="flock()"><span id="is48ii2" class="smalltitle">flock()</span></a></p> <p>flock() 的函数原型如下所C:</p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> int flock(int fd, int operation); </pre> </td> </tr> </tbody> </table> <br /> <p>其中Q参?fd 表示文g描述W;参数 operation 指定要进行的锁操作,该参数的取值有如下几种QLOCK_SHQ?LOCK_EXQ?LOCK_UN ?LOCK_MANDphost2008-07-03T00:00:00 </p> <p>man page 里面没有提到Q其各自的意思如下所C:</p> <ul> <li>LOCK_SHQ表C创徏一个共享锁Q在L旉内,一个文件的׃n锁可以被多个q程拥有 <li>LOCK_EXQ表C创Z个排他锁Q在L旉内,一个文件的排他锁只能被一个进E拥? <li>LOCK_UNQ表C删除该q程创徏的锁 <li>LOCK_MANDQ它主要是用于共享模式强刉Q它可以?LOCK_READ 或?LOCK_WRITE 联合h使用Q从而表C是否允许ƈ发的L作或者ƈ发的写操作(管?flock() 的手册页中没有介l?LOCK_MANDQ但是阅d核源代码׃发现Q这在内怸已经实现了) </li> </ul> <p>通常情况下,如果加锁h不能被立xI那么pȝ调用 flock() 会阻塞当前进E。比如,q程惌h一个排他锁Q但此时Q已l由其他q程获取了这个锁Q那么该q程会被阻塞。如果想要在没有获得q个排他锁的情况下不d该进E,可以?LOCK_NB ?LOCK_SH 或?LOCK_EX 联合使用Q那么系l就不会d该进E。flock() 所加的锁会Ҏ(gu)个文件v作用?/p> <p><a name="fcntl()"><span id="ugyggy2" class="smalltitle">fcntl()</span></a></p> <p>fcntl() 函数的功能很多,可以改变已打开的文件的性质Q本文中只是介绍其与获取/讄文g锁有关的功能。fcntl() 的函数原型如下所C:</p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> int fcntl (int fd, int cmd, struct flock *lock); </pre> </td> </tr> </tbody> </table> <br /> <p>其中Q参?fd 表示文g描述W;参数 cmd 指定要进行的锁操作,׃ fcntl() 函数功能比较多,q里先介l与文g锁相关的三个取?F_GETLK、F_SETLK 以及 F_SETLKW。这三个值均?flock l构有关。flock l构如下所C:</p> <br /> <a name="清单 4. flock l构"><strong>清单 4. flock l构</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> struct flock { ... short l_type; /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */ short l_whence; /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */ off_t l_start; /* Starting offset for lock */ off_t l_len; /* Number of bytes to lock */ pid_t l_pid; /* PID of process blocking our lock (F_GETLK only) */ ... }; </pre> </td> </tr> </tbody> </table> <br /> <p>?flock l构中,l_type 用来指明创徏的是׃n锁还是排他锁Q其取值有三种QF_RDLCKQ共享锁Q、F_WRLCKQ排他锁Q和F_UNLCKQ删除之前徏立的锁)Ql_pid 指明了该锁的拥有者;l_whence、l_start 和l_end q些字段指明了进E需要对文g的哪个区域进行加锁,q个区域是一个连l的字节集合。因此,q程可以对同一个文件的不同部分加不同的锁。l_whence 必须?SEEK_SET、SEEK_CUR ?SEEK_END q几个g的一个,它们分别对应着文g头、当前位|和文g。l_whence 定义了相对于 l_start 的偏U量Ql_start 是从文g开始计的?/p> <p>可以执行的操作包括:</p> <ul> <li>F_GETLKQ进E可以通过它来获取通过 fd 打开的那个文件的加锁信息。执行该操作Ӟlock 指向的结构中׃存了希望Ҏ(gu)件加的锁Q或者说要查询的锁)。如果确实存在这样一把锁Q它L lock 指向?flock l构所l出的锁描述W,则把现存的锁的信息写?lock 指向?flock l构中,q将该锁拥有者的 PID 写入 l_pid 字段中,然后q回Q否则,将 lock 指向?flock l构中的 l_type 讄?F_UNLCKQƈ保持 flock l构中其他信息不变返回,而不会对该文件真正加锁? <li>F_SETLKQ进E用它来Ҏ(gu)件的某个区域q行加锁Ql_type的gؓ F_RDLCK ?F_WRLCKQ或者删除锁Ql_type 的gؓF_UNLCKQ,如果有其他锁L该锁被徏立,那么 fcntl() 出错返? <li>F_SETLKWQ与 F_SETLK cMQ唯一不同的是Q如果有其他锁阻止该锁被建立Q则调用q程q入睡眠状态,{待该锁释放。一旦这个调用开始了{待Q就只有在能够进行加锁或者收Ch才会q回 </li> </ul> <p>需要注意的是,F_GETLK 用于试是否可以加锁Q在 F_GETLK 试可以加锁之后QF_SETLK ?F_SETLKW ׃企图建立一把锁Q但是这两者之间ƈ不是一个原子操作,也就是说Q在 F_SETLK 或?F_SETLKW q没有成功加锁之前,另外一个进E就有可能已l插q来加上了一把锁。而且QF_SETLKW 有可能导致程序长旉睡眠。还有,E序Ҏ(gu)个文件拥有的各种锁会在相应的文g描述W被关闭时自动清除,E序q行l束后,其所加的各种锁也会自动清除?/p> <p>fcntl() 既可以用于劝告锁Q也可以用于强制锁,在默认情况下Q它用于劝告锁。如果它用于强制锁,当进E对某个文gq行了读或写q样的系l调用时Q系l则会检查该文g的锁?O_NONBLOCK 标识Q该标识是文件状态标识的一U,如果讄文g状态标识的时候设|了 O_NONBLOCKQ则该进E会出错q回Q否则,该进E被d。cmd 参数的?F_SETFL 可以用于讄文g状态标识?/p> <p>此外Q系l调?fcntl() q可以用于租借锁Q此旉用的函数原型如下Q?/p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> int fcntl(int fd, int cmd, long arg); </pre> </td> </tr> </tbody> </table> <br /> <p>与租借锁相关?cmd 参数的取值有两种QF_SETLEASE ?F_GETLEASE。其含义如下所C:</p> <ul> <li>F_SETLEASEQ根据下面所描述?arg 参数指定的值来建立或者删除租U: <ul> <li>F_RDLCKQ设|读U约。当文g被另一个进E以写的方式打开Ӟ拥有该租U的当前q程会收到通知 <li>F_WRLCKQ设|写U约。当文g被另一个进E以L者写的方式打开Ӟ拥有该租U的当前q程会收到通知 <li>F_UNLCKQ删除以前徏立的U约 </li> </ul> <li>F_GETLEASEQ表明调用进E拥有文件上哪种cd的锁Q这需要通过q回值来定Q返回值有三种QF_RDLCK、F_WRLCK和F_UNLCKQ分别表明调用进E对文g拥有ȝ借、写U借或者根本没有租?</li> </ul> <p>某个q程可能会对文g执行其他一些系l调用(比如 OPEN() 或?TRUNCATE()Q,如果q些pȝ调用与该文g上由 F_SETLEASE 所讄的租借锁相冲H,内核׃dq个pȝ调用Q同Ӟ内核会给拥有q个U借锁的进E发信号Q告知此事。拥有此U借锁的进E会对该信号q行反馈Q它可能会删除这个租借锁Q也可能会减短这个租借锁的租U,从而可以得该文g可以被其他进E所讉K。如果拥有租借锁的进E不能在l定旉内完成上q操作,那么pȝ会强制帮它完成。通过 F_SETLEASE 命o?arg 参数指定?F_UNLCK 可以删除这个租借锁。不对该租借锁减短U约或者干脆删除的操作是进E自愿的q是内核的,只要被阻塞的pȝ调用q没有被发出该调用的q程解除dQ那么系l就会允许这个系l调用执行。即使被d的系l调用因为某些原因被解除dQ但是上面对U借锁减短U约或者删除这个过E还是会执行的?/p> <p>需要注意的是,U借锁也只能对整个文g生效Q而无法实现记录的加锁?/p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="文g锁的使用样例"><span id="mqssi4e" class="atitle">文g锁的使用样例</span></a></p> <p>Z使读者更深入理解本文中介l的内容Q下面我们给Z一个例子来详细介绍文g锁的具体用法。这个例子可以用来检所使用的文件是否支持强刉Q其源代码如下所C:</p> <br /> <a name="清单 5. 锁的使用Ҏ(gu)具体CZ"><strong>清单 5. 锁的使用Ҏ(gu)具体CZ</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"> # cat -n mandlock.c 1 #include <errno.h> 2 #include <stdio.h> 3 #include <fcntl.h> 4 #include <sys/wait.h> 5 #include <sys/stat.h> 6 7 int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) 8 { 9 struct flock lock; 10 11 lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */ 12 lock.l_start = offset; /* byte offset, relative to l_whence */ 13 lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ 14 lock.l_len = len; /* #bytes (0 means to EOF) */ 15 16 return( fcntl(fd, cmd, &lock) ); 17 } 18 19 #define read_lock(fd, offset, whence, len) \ 20 lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len) 21 #define write_lock(fd, offset, whence, len) \ 22 lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len) 23 24 #define err_sys(x) { perror(x); exit(1); } 25 26 int main(int argc, char *argv[]) 27 { 28 int fd, val; 29 pid_t pid; 30 char buf[5]; 31 struct stat statbuf; 32 if (argc != 2) { 33 fprintf(stderr, "usage: %s filename\n", argv[0]); 34 exit(1); 35 } 36 if ((fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC )) < 0) 37 err_sys("open error"); 38 if (write(fd, "hello world", 11) != 11) 39 err_sys("write error"); 40 41 /* turn on set-group-ID and turn off group-execute */ 42 if (fstat(fd, &statbuf) < 0) 43 err_sys("fstat error"); 44 if (fchmod(fd, (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0) 45 err_sys("fchmod error"); 46 47 sleep(2); 48 49 if ((pid = fork()) < 0) { 50 err_sys("fork error"); 51 } else if (pid > 0) { /* parent */ 52 /* write lock entire file */ 53 if (write_lock(fd, 0, SEEK_SET, 0) < 0) 54 err_sys("write_lock error"); 55 56 sleep(20); /* wait for child to set lock and read data */ 57 58 if (waitpid(pid, NULL, 0) < 0) 59 err_sys("waitpid error"); 60 61 } else { /* child */ 62 sleep(10); /* wait for parent to set lock */ 63 64 if ( (val = fcntl(fd, F_GETFL, 0)) < 0) 65 err_sys("fcntl F_GETFL error"); 66 67 val |= O_NONBLOCK; /* turn on O_NONBLOCK flag */ 68 69 if (fcntl(fd, F_SETFL, val) < 0) 70 err_sys("fcntl F_SETFL error"); 71 72 /* first let's see what error we get if region is locked */ 73 if (read_lock(fd, 0, SEEK_SET, 0) != -1) /* no wait */ 74 err_sys("child: read_lock succeeded"); 75 76 printf("read_lock of already-locked region returns %d: %s\n", errno, strerror(errno)); 77 78 /* now try to read the mandatory locked file */ 79 if (lseek(fd, 0, SEEK_SET) == -1) 80 err_sys("lseek error"); 81 if (read(fd, buf, 5) < 0) 82 printf("read failed (mandatory locking works)\n"); 83 else 84 printf("read OK (no mandatory locking), buf = %5.5s\n", buf); 85 } 86 exit(0); 87 } 88 </pre> </td> </tr> </tbody> </table> <br /> <p>样例代码中所采用的技术在前文中大都已l介l过了,其基本思想是在首先在父q程中对文g加上写锁Q然后在子进E中文件描q符讄为非d模式Q第 69 行)Q然后对文g加读锁,q尝试读取该文g中的内容。如果系l支持强刉Q则子进E中?read() pȝ调用Q代码中的第 81 行)会立卌?EAGAINQ否则,{父q程完成写文件操作之后,子进E中?read() pȝ调用׃q回父进E刚刚写入的?5 个字节的数据。代码中的几?sleep() 是ؓ了协调父q程与子q程之间的同步而用的?/p> <p>该程序在试pȝ的执行结果如下所C:</p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode"># mount | grep mnt /dev/sdb7 on /mnt type ext3 (rw,mand) /dev/sdb6 on /tmp/mnt type ext3 (rw) # ./mandlock /mnt/testfile read_lock of already-locked region returns 11: Resource temporarily unavailable read failed (mandatory locking works) # ./mandlock /tmp/mnt/testfile read_lock of already-locked region returns 11: Resource temporarily unavailable read OK (no mandatory locking), buf = hello </pre> </td> </tr> </tbody> </table> <br /> <p>我们可以看到Q?dev/sdb7 使用 –o mand 选项挂蝲C /mnt 目录中,?/dev/sdb6 则么有用这个选项挂蝲C /tmp/mnt 目录中。由于在E序中我们完成了Ҏ(gu)试文?SGID 和同l可执行位的讄Q第 44 行)Q因?/mnt/testfile 可以支持强制锁,?/tmp/mnt/testfile 则不能。这也正是ؓ什么前者的 read() pȝ调用会失败返回而后者则可以成功d?hello 的原因?/p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> </td> </tr> </tbody> </table> <br /> <p><a name="outline"><span id="yooggyo" class="atitle">ȝ</span></a></p> <p>Linux 的文仉在以׃n索引节点׃n文g的情况下设计的,文g锁的实现可以使得不同用户同时d同一文g的ƈ发问题得以解冟뀂本文描qC Linux 中各cL仉的概念,使用场景Q内怸描述文g锁的数据l构以及与文仉密切相关的系l调用等内容Q至于与文g锁相关的索引节点数据l构Q以及在Ҏ(gu)件进行加锁时遇到的死锁问题等其他知识Q这里没有做详尽介绍Q感兴趣的读者可以自行参考内核源代码?/p> <p>本文的目的是惛_助读者理?Linux 2.6中文仉的概念以?Linux 2.6 都提供了何种数据l构以及关键的系l调用来实现文g锁,从而可以帮助读者更好地使用文g锁来解决多个q程d同一个文件的互斥问题?/p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="resources"><span id="gukkcis" class="atitle">参考资?</span></a></p> <ul> <li><a cmimpressionsent="1">Linux 内核源代?/a>中包含了文g锁的具体实现Q本文中引用的内总码来自于 Linux  2.6.23 版本的内核?<br /> <br /> <li><a cmimpressionsent="1">File Locking in Linux 2.5</a>一文中介绍了在 Linux 2.5 开发时Ҏ(gu)仉的一些设计考虑?<br /> <br /> <li><a cmimpressionsent="1">The Single UNIX® Specification, Version 3 规范</a>中对 fcntl pȝ调用q行了详l的规定?<br /> <br /> <li><a>Linux 内核情景分析(?一书的文gpȝ一章详l描qC Linux 内核对各U不同类锁的理和控Ӟ讲述?Linux 文g锁的关键的数据结构及其实玎ͼ以及文g锁对其他的文件模式和操作的媄?/a> <br /> <br /> <li><a>?Understanding the Linux Kernel(3<sup>rd</sup> Edition) 中,有关?Linux 中不同种cL仉详细的实现过E?/a> <br /> <br /> <li>更多的关?Linux 开发的资源Q参?developerWorks ?<a cmimpressionsent="1">Linux 专区</a>?</li> </ul> <p><span style="color: #800080"><a title="mandlock.c" href="/Files/joan/mandlock.rar"><em>mandlock.c</em></a><a title="mandlock.c" style="color: #ccffff" href="/Files/joan/mandlock.rar"></span></a></p> <p> </p>   <img src ="http://www.tkk7.com/joan/aggbug/214335.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/joan/" target="_blank">joan</a> 2008-07-11 21:31 <a href="http://www.tkk7.com/joan/articles/214335.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://k5nn.com" target="_blank">eeussӰԺ92242</a>| <a href="http://x5k9.com" target="_blank">ۺɫ߹ۿ</a>| <a href="http://dqmovie.com" target="_blank">ĻƬ</a>| <a href="http://xabcjzx.com" target="_blank">㽶þһ </a>| <a href="http://mp4888.com" target="_blank">Ļ</a>| <a href="http://bearsou.com" target="_blank">˳߹ۿ</a>| <a href="http://wilbysec.com" target="_blank">պƵ </a>| <a href="http://scjcled.com" target="_blank">A޾Ʒ</a>| <a href="http://ebhqd.com" target="_blank">ƷСƵ</a>| <a href="http://xcdys.com" target="_blank">ҹ߹ۿ </a>| <a href="http://www-959kj.com" target="_blank">3pһ</a>| <a href="http://vcnxa.com" target="_blank">ֻˬһëƬѹۿ</a>| <a href="http://hkcdk.com" target="_blank">91ƵѲ</a>| <a href="http://klno1.com" target="_blank">Ļȫ</a>| <a href="http://jinlaifubuxiugang.com" target="_blank">ҵijdzӪѿ</a>| <a href="http://c2277.com" target="_blank">վƵwww</a>| <a href="http://oupur.com" target="_blank">ɫavƷר</a>| <a href="http://jl910.com" target="_blank">պƷĻ</a>| <a href="http://fenxiangceo.com" target="_blank">fuli߹ۿ</a>| <a href="http://yinyinai155.com" target="_blank">ŷ͵ҹɫ</a>| <a href="http://jlzjjy.com" target="_blank">޹һ</a>| <a href="http://pite2.com" target="_blank">aרav</a>| <a href="http://69xjj.com" target="_blank">޾ƷþþþþĻ</a>| <a href="http://dqcjlb.com" target="_blank">պĻպ</a>| <a href="http://625r.com" target="_blank">պƷר߹ۿ</a>| <a href="http://hengzekang.com" target="_blank">߹ۿѾƷ</a>| <a href="http://69xjj.com" target="_blank">ձһ</a>| <a href="http://xtolm.com" target="_blank">ձƵ</a>| <a href="http://hbqueena.com" target="_blank">òƵƽ̨</a>| <a href="http://douhuowang.com" target="_blank">xxxxƵ</a>| <a href="http://ai-xian.com" target="_blank">պһƵ</a>| <a href="http://assbjg.com" target="_blank">ɫƵ</a>| <a href="http://my55572.com" target="_blank">պɫѹۿ</a>| <a href="http://k67m.com" target="_blank">պĻѹۿ</a>| <a href="http://jhc2go.com" target="_blank">ĻӰ߹ۿ</a>| <a href="http://shiliuvip.com" target="_blank">һѹۿ</a>| <a href="http://788qj.com" target="_blank">޹Ʒһ</a>| <a href="http://lebaojj.com" target="_blank">޹Ʒ߲</a>| <a href="http://83k5.com" target="_blank">һպĻ</a>| <a href="http://vankiz.com" target="_blank">һƵ߹ۿ </a>| <a href="http://hbjinmaitang.com" target="_blank">Aһ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>