鸟哥的 Linux 私房菜
网络快照,版权归"http://linux.vbird.org"网站所有。
网络快照,版权归"http://linux.vbird.org"网站所有。
| 最近更新日期:2005/09/18
1. 什么是程序 (Process): 1.1 程序与执行档 (process & program) 1.2 Linux 的多人多工环境 2. 工作管理 (job control): &, [ctrl]-z, jobs, fg, bg, kill 3. 程序管理 3.1 程序的观察: ps, top, pstree 3.2 程序的删除: kill, killall 3.3 系统资源的观察: free, uname, uptime, netstat, dmesg, sar 4. 关于程序的执行顺序: nice, renice 5. 特殊档案与程序: 5.1 SUID/SGID/SBIT 的概念 5.2 /proc/* 代表的意义 5.3 查询已开启档案或已执行程序开启之档案: fuser, lsof, pidof 6. 本章习题练习 由前面一连几个章节的资料看来,我们一直强调在 Linux 底下所有的指令与您能够进行的动作都与权限有关, 而系统如何判定你的权限呢?当然就是前面 帐号管理 章节当中提到的 UID/GID 的相关概念,以及档案的属性相关性�!再进一步来解释, 您现在大概知道,在 Linux 系统当中:'触发任何一个事件时, 系统都会将他定义成为一个程序,并且给予这个程序一个 ID ,称为 PID,同时依据启发这个程序的使用者与相关属性关系, 给予这个 PID 一组有效的权限设定。' 从此以后,这个 PID 能够在系统上面进行的动作,就与这个 PID 的权限有关了! 看这个定义似乎没有什么很奇怪的地方,不过,您得要了解什么叫做'触发事件'才行啊! 我们在什么情况下会触发一个事件?而同一个事件可否被触发多次?呵呵!来了解了解先! 我们如何产生一个 Process ID (PID) 呢?其实很简单啦,就是'执行一个程式或指令' 就可以触发一个事件了而取得一个 PID �!我们说过,硬体应该是仅认识 binary file 的, 那么当我们要让硬体工作的时候,当然就是需要启动一个 binary file �, 那个 binary file 就是程式 (program) 啦! 那我们知道,每个程式都有三组人马的权限,每组人马都具有 r/w/x 的权限, 所以:'不同的使用者身份执行这个 program 时,系统给予的权限也都不相同!' 举例来说,我们可以利用 touch 来建立一个空的档案,当 root 执行这个 touch 指令时,他取得的是 UID/GID = 0/0 的权限,而当 dmtsai (UID/GID=501/501) 执行这个 touch 时,他的权限就跟 root 不同啦! 再举个更常见的例子,我们要操作系统的时候,通常是利用连线程式或者直接在主机前面登入, 然后取得我们的 shell 对吧!那么,我们的 shell 是 bash 对吧,这个 bash 在 /bin/bash 对吧, 那么同时间的每个人登入都是执行 /bin/bash 对吧!不过,每个人取得的权限就是不同! 也就是说,我们可以这样看: 图一、程式与程序之间的差异 也就是说,当我们登入并执行 bash 时,系统已经给我们一个 PID 了, 这个 PID 就是依据登入者的 UID/GID (/etc/passwd) 来的啦~ 以上面的图来做说明的话,我们知道 /bin/bash 是一个程式 (program),当 dmtsai 登入后,他取得一个 PID 号码为 2234 的程序,这个程序的 User/Group 都是 dmtsai, 而当这个程式进行其他作业时,例如上面提到的 touch 这个指令时, 那么由这个程序衍生出来的其他程序在一般状态下,也会沿用这个程序的相关权限的! 在上面的说明里面,我们有提到所谓的'衍生出来的程序',那是个啥咚咚? 这样说好了,当我们登入系统后,会取得一个 bash 的 shell ,然后,我们用这个 bash 提供的介面去执行另一个指令,例如 /usr/bin/passwd 或者是 touch 等等, 那些另外执行的指令也会被触发成为 PID ,呵呵!那个 PID 就是'子程序'了, 而在我们的 bash 环境下,就称为'父程序'了! 另外,是否还记得我们在 bash shell 那一篇里面有提到 '环境变数'在不同程序之间的呼叫呢?现在稍微晓得是什么意思了吗? 是啦!因为我们有执行不同的 bash 嘛!既然执行两次,自然就会取得两个 PID, 而因为要让两个 PID 之间具有一些相关性,我们的 bash 就使用了环境变数�!
重点来啦!所以说,在系统上面的各个程序可能是有相关性的喔! 也就是有所谓的父程序与子程序的关系~至于程序的相关性,我们可以使用 pstree 这支程式去查验, 就能知道彼此之间的关系了。 另外要注意的是:所谓'擒贼先擒王', 如果哪天你一直发现'奇怪,怎么有个程式关闭后,不久又会自动产生? 而且自动产生的 PID 还不一样!',呵呵!大概不需要怀疑的是,如果不是 例行性命令 的影响, 肯定有一支父程序存在,他会一直重新触发你想要关闭的那个程序, 导致你老是关不了。那怎么办?不是说过擒贼先擒王吗?关闭那支父程序啦! ^_^ 其实子程序与父程序之间的关系还挺复杂的,最大的复杂点在于程式互相之间的呼叫, 以及两者权限的相关性!这个可能就得要您自己多多建立自己的经验了~ 如果就我们之前学到的一些指令资料来看,其实我们下达的指令都很简单, 包括用 ls 显示档案啊、用 touch 建立档案啊、rm/mkdir/cp/mv 等指令管理档案啊、 chmod/chown/passwd 等等的指令来管理权限等等的,不过,这些指令都是执行完就结束了。 也就是说,该项指令被触发后所产生的 PID 很快就会终止呢! 那有没有一直在执行的程序啊?当然有啊!而且多的是呢! 举个简单的例子来说好了,我们知道系统每分钟都会去扫瞄 /etc/crontab 以及相关的设定档, 来进行工作排程吧?那么那个工作排程是谁负责的?当然不是鸟哥啊! 呵呵!是 crond 这个程式所管理的,我们将他启动在背景当中一直持续不断的运作, 套句以前 DOS 年代常常说的一句话,那就是'常驻在记忆体当中的程序'啦! 这些常驻在记忆体当中的程序有很多,不过主要大致分成系统本身所需要的服务, 例如刚刚提到的 crond 及 atd ,还有 syslog 等等的。还有一些则是负责网路连线的服务, 例如 Apache, named, postfix, vsftpd... 等等的。这些网路服务比较有趣的地方, 在于这些程式被执行后,他会启动一个可以负责网路监听的埠口 (port) , 以提供外部用户端 (client) 的连线要求。 这部分我们会在认识系统服务的地方再好好的讲一讲, 在这里,您先有个概念,大概知道一下,系统上面的 PID 几乎都是透过执行一些指令所产生的, 而这些指令可能会负责一些重要的工作,例如网路伺服器啊、系统效能维持啊、 或是其他系统重要工作等等。若有兴趣的话,可以先以 netstat 检查一下您主机上的网路服务喔! 我们现在知道了,其实在 Linux 底下执行一个指令时,系统会给予这个动作一个 ID, 我们称为 PID,而根据启用这个指令的使用者与相关的指令功能,而给予这个特定 PID 一组权限, 该指令可以进行的行为则与这个 PID 的权限有关。根据这个说明,我们就可以简单的了解, 为什么 Linux 这么多用户,但是却每个人都可以拥有自己的环境了吧!^_^ Linux 最棒的地方就在于他的多人多工环境了!那么,什么是'多人多工'?!在 Linux 上面允许不同的人使用,而且每个人都有其特殊的权限,只有一个人具有至高无上的权力,那就是 root (系统管理员),除了他之外,其他人都必须要受一些限制的!而每个人进入 Linux 的环境设定都可以随着每个人的喜好来设定 (还记得我们在 BASH 那一章提过的 ~/.bashrc 吧!?对了!就是那个光!)!现在知道为什么了吧? 因为每个人登入后取得的 shell 的 PID 不同嘛! 我想,在某些其他作业系统中,您可能会遇到这样的事情:'这个档案正在使用中, 您无法开启这个档案!'我哩勒!还得将正在执行当中的程式关掉之后才能开这个中间暂存档!! 而且这个时候还只有我自己一个人在使用呢~受不了~呵呵!不过, Linux 就不会这样�!您可以同时在不同的画面,同时由不同的人 (当然�,有的是经由 SSH 网路连线过来,有的是直接在萤幕前面的朋友�!)使用'同一个档案', 不论是开启或者是修改,只要您有权限,就可以使用该档案!! 这个东西可有用的紧!由于鸟哥是很常使用程式的 (就是 Fortran 啦,吃饭的工具!) ,而由于我们有一部主机专门用来工作的,所以配备比较高档一点 PIII 的双 CPU ),那么我就可以同时的进行两个 compiler 的程序,而且还不会互相的影响, 并且资源分配的还蛮均匀的!哈哈!怎么会跑得这么顺畅呀!爽毙了! 其实作业系统的多工是很复杂的行为啦!尤其涉及将多个工作直接丢给一颗 CPU 来处理~ 现在我们应该比较清楚的是,所谓的'工作'其实是将多个指令触发成为系统程序 (PID), 而这些程序若同时被触发时,那么一颗 CPU 就得要同时负责许多工作了。 但我们晓得的是,并非每个程序都很耗系统资源,例如前一节提到的 crond 与 atd 这两个系统服务, 他们并没有消耗很多系统资源的。此时,当然�, CPU 就可以进行其他工作, 这就是所谓的多工! 在 Linux 当中,预设提供了六个文字界面登入视窗,以及一个图形界面,你可以使用 [Alt]+[F1].....[F7] 来切换不同的终端机界面,而且每个终端机界面的登入者还可以不同人! 很炫吧!这个东西可就很有用啦!尤其是在某个程序死掉的时候! 其实,这也是多工环境下所产生的一个情况啦! 我们的 Linux 预设会启动六个终端机登入环境的程式,所以我们就会有六个终端机介面。 您也可以减少啊!就是减少启动的终端机程式就好了。详细的资料可以先查阅 /etc/inittab 这个档案,未来我们在开机管理流程会再仔细的介绍的! 以前的鸟哥笨笨的,总是以为使用 Windows 98 就可以啦!后来,因为工作的关系,需要使用 Unix 系统,想说我只要在工作机前面就好, 才不要跑来跑去的到 Unix 工作站前面去呢!所以就使用 Windows 连到我的 Unix 工作站工作! 好死不死,我一个程序跑下来要 2~3 天,唉~偏偏常常到了第 2.5 天的时候, Windows 98 就给他挂点去!当初真的是给他怕死了~后来因为换了新电脑,用了随机版的 Windows 2000 ,呵呵,这东西真不错 (指对单人而言) ,在当机的时候, 他可以仅将错误的程序踢掉,而不干扰其他的程序进行,呵呵! 从此以后,就不用担心会当机连连�!不过,2000 毕竟还不够好,因为有的时候还是会死当!! 那么 Linux 呢?哈哈!更棒了,几乎可以说绝对不会当机的!因为他可以在任何时候, 将某个被困住的程序杀掉,然后在重新执行该程序而不用重新开机!够炫吧!那么如果我在 Linux 下以文字界面登入,在萤幕当中显示错误讯息后就挂了~动都不能动,该如何是好!? 这个时候那预设的七个视窗就帮上忙啦!你可以随意的再按 [Alt]+[F1].....[F7] 来切换到其他的终端机界面,然后以 ps -aux 找出刚刚的错误程序,然后给他 kill 一下,哈哈,回到刚刚的终端机界面!恩~棒!又回复正常�! 为什么可以这样做呢?我们刚刚不是提过吗?每个程序之间可能是独立的,也可能有相依性, 只要到独立的程序当中,删除有问题的那个程序,当然他就可以被系统移除掉啦!^_^ 我们在上一个小节有提到所谓的'父程序、子程序'的关系,那我们登入 bash 之后, 就是取得一个名为 bash 的 PID 了,而在这个环境底下所执行的其他指令, 就几乎都是所谓的子程序了。那么,在这个单一的 bash 介面下,我可不可以进行多个工作啊? 当然可以啦!可以'同时'进行喔!举例来说,我可以这样做:
多人多工确实有很多的好处,但其实也有管理上的困扰,因为使用者越来越多, 将导致你管理上的困扰哩!另外,由于使用者日盛,当使用者达到一定的人数后, 通常你的机器便需要升级了,因为 CPU 的运算与 RAM 的大小可能就会不敷使用! 好了!废话说完了!开始来谈一谈几个常用的指令吧! 举个例子来说,鸟哥之前的网站管理的有点不太好,因为使用了一个很复杂的人数统计程式, 这个程式会一直去取用 MySQL 资料库的资料,偏偏因为流量大,造成 MySQL 很忙碌。 在这样的情况下,当鸟哥要登入去写网页资料,或者要去使用讨论区的资源时, 哇!慢的很!简直就是'龟速'啊!后来终于将这个程式停止不用了, 以自己写的一个小程式来取代,呵呵!这样才让 CPU 的负载 (loading) 整个降下来~ 用起来顺畅多了! ^_^ 这个工作管理 (job control) 是用在 bash 环境下的,也就是说:' 当我们登入系统取得 bash shell 之后,在单一终端机介面下同时进行多个工作的行为管理 '。举例来说,我们在登入 bash 后, 想要一边复制档案、一边进行资料搜寻、一边进行编译,还可以一边进行 vi 程式撰写! 当然我们可以重复登入那六个文字介面的终端机环境中,不过,能不能在一个 bash 内达成? 当然可以啊!就是使用 job control 啦! ^_^ 从上面的说明当中,您应该要了解的是:'进行工作管理的行为中, 其实每个工作都是目前 bash 的子程序,亦即彼此之间是有相关性的。 我们无法以 job control 的方式由 tty1 的环境去管理 tty2 的 bash !' 这个概念请您先建立起来,后续的范例介绍之后,您就会清楚的了解�! 或许你会觉得很奇怪啊,既然我可以在六个终端介面登入,那何必使用 job control 呢? 真是脱裤子放屁,多此一举啊!不要忘记了呢,我们可以在 /etc/security/limit.conf 里面设定使用者同时可以登入的连线数,在这样的情况下,某些使用者可能仅能以一个连线来工作呢! 所以�,您就得要了解一下这种工作管理的模式了! 此外,这个章节内容也会牵涉到很多的资料流重导向,所以,如果忘记的话, 务必回到 BASH Shell 看一看喔! 总之,要进行 bash 的 job control 必须要注意到的限制是:
瞎密?将某个指令'丢到背景'当中?在一个 bash 的环境下,什么叫做'前景 (foreground) '与'背景 (background) '?我们先来简单的定义一下:
此外,将工作丢到背景当中要特别注意资料的流向喔!举例来说,如果我将刚刚那个指令改成:
想个情况:如果我正在使用 vi ,却发现我有个档案不知道放在哪里,需要到 bash 环境下去搜寻,此时,是否要结束 vi 呢?呵呵!当然不需要啊!只要暂时将 vi 给他丢到背景当中等待即可。 例如以下的案例:
刚刚提到的都是将工作丢到背景当中去执行的,那么有没有可以将背景工作拿到前景来处理的? 有啊!就是那个 fg 啦!举例来说,我们想要将上头范例当中的工作拿出来处理时:
我们刚刚提到,那个 [ctrl]-z 可以将目前的工作丢到背景底下去'暂停', 那么如何让一个工作在背景底下' Run '呢?我们可以在底下这个案例当中来测试! 注意喔!底下的测试要进行的快一点!^_^
刚刚我们可以让一个已经在背景当中的工作继续工作,也可以让该工作以 fg 拿到前景来, 那么,如果想要将该工作直接移除呢?或者是将该工作重新启动呢?呵呵! 这个时候就得需要给予该工作一个讯号 (signal) ,让他知道该怎么作才好啊! 此时, kill 这个指令就派上用场啦!
其实, kill 的妙用是很无穷的啦!他搭配 signal 所详列的资讯 (用 man 7 signal 去查阅相关资料) 可以让您有效的管理工作与程序 (Process),此外,那个 killall 也是同样的用法! 至于常用的 signal 您至少需要了解 1, 9, 15 这三个 signal 的意义才好。 此外, signal 除了以数值来表示之外,也可以使用讯号名称喔! 举例来说,上面的范例二就是一个例子啦!至于 signal number 与名称的对应, 呵呵,使用 kill -l 就知道啦(L的小写)! 本章一开始就提到所谓的'程序'的概念,包括程序的触发、子程序与父程序的相关性等等, 此外,还有那个'程序的相依性'以及所谓的'僵尸程序'等等需要说明的呢! 为什么程序管理这么重要呢?
既然程序这么重要,那么我们如何查阅系统上面正在运作当中的程序呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅程序树之间的关系喔!
在预设的情况下, ps 仅会列出与目前所在的 bash shell 有关的 PID 而已,所以, 当我使用 ps -l 的时候,只有三个 PID (范例一)。注意一下,我有一个 bash 的 PID , 而且也有一个 ps 的 PID ,了解了吧?呵呵!在 bash 里面执行程式时,是会触发一个新的 process 的喔!而且,两者之间是有相关性的,看 PID 与 PPID 的号码,你就会晓得两者的差异了! 那么,什么是'有效使用者 ID '呢?还记得我们提过的 SUID 吧?我以 dmtsai 去执行 /usr/bin/passwd 取得的那个 process 竟然是 root 的权限喔! 此时,实际的使用者 (real user) 是 dmtsai ,但是有效的使用者 (effective user) 是 root 啦! 这样说,可以理解吧!? 一般来说,鸟哥会建议您,直接使用'ps aux'这个指令参数即可, 显示的结果例如上面的范例二�。在范例二的各个显示项目代表的意义为:
除此之外,我们必须要知道的是'疆尸 (zombie) '程序是什么? 通常,造成疆尸程序的成因是因为该程序应该已经执行完毕,或者是因故应该要终止了, 但是该程序的父程序却无法完整的将该程序结束掉,而造成那个程序一直存在记忆体当中..... 如果您发现在某个程序的 CMD 后面还接上 <defunct> 时,就代表该程序是疆尸程序啦,例如:
top 主要分为两个画面,上面的画面为整个系统的资源使用状态,基本上总共有六行, 显示的内容依序是:
我们在前几个小节提到的'背景工作管理'当中提到过, 要给予某个已经存在的工作某些动作时,是直接给予一个讯号 (signal) 给该 PID 即可。 常见的工作可以使用 kill -l (L 的小写) 来查阅!而主要的讯号代号与名称对应及内容是:
而 kill 可以帮我们将这个 signal 传送给某个工作 (%jobnumber) 或者是某个 PID (直接输入数字), 也就是说, kill 后面直接加数字与加上 % 的情况是不同的!这个很重要喔!不要搞错了。 我们就活用一下 kill 与刚刚上面提到的 ps 来做个简单的练习吧!
由于 kill 后面必须要加上 PID (或者是 job number),所以,通常 kill 都会配合 ps, pstree 等指令,因为我们必须要找到相对应的那个程序的 ID 嘛!但是,如此一来,很麻烦~ 有没有可以利用'下达指令的名称'来给予讯号的?举例来说,能不能直接将 syslog 这个程序给予一个 SIGHUP 的讯号呢?可以的!用 killall 吧!
除了系统的程序之外,我们还必须就系统的一些资源进行检查啊! 举例来说,我们使用 top 可以看到很多系统的资源对吧!那么,还有没有其他的工具可以查阅的? 当然有啊!底下这些工具指令可以玩一玩!
仔细的看到范例一的输出喔,我的 Linux 主机是很平凡的,根本没有什么工作, 但是,我的实体记忆体是几乎被用光光的情况呢!不过,至少有 129 MB 用在缓冲记忆工作, 94 MB 则用在快取工作,也就是说,系统是'很有效率的将所有的记忆体用光光', 目的是为了让系统的存取效能加速啦! 很多朋友都会问到这个问题'我的系统明明很轻松,为何记忆体会被用光光?' 现在了了吧?没有错!被用光是正常的!而需要注意的反而是 swap 的量。一般来说, swap 最好不要被使用,尤其 swap 最好不要被使用超过 20% 以上, 如果您发现 swap 的用量超过 20% ,那么,最好还是买实体记忆体来插吧! 因为, Swap 的效能跟实体记忆体实在差很多,而系统会使用到 swap , 绝对是因为实体记忆体不足了才会这样做的!如此,了解吧!
这个指令很单纯呢!就是显示出目前系统已经开机多久的时间,以及 1, 5, 15 分钟的平均负载就是了。还记得 top 吧?没错啦! 这个 uptime 可以显示出 top 画面的最上面一行!
这个 netstat 也是挺好玩的,其实,这个指令比较常被用在网路的监控方面, 不过,在程序管理方面也是需要了解的啦!这个指令的执行如下所示:基本上, netstat 的输出分为两大部分,上面是网路介面相关的连线,下方则是与 unix 程序有关的项目。
在开机的时候你会发现有很多的讯息出现吧,例如 CPU 的形式、硬碟、 光碟型号及硬碟分割表等等,这些资讯的产生都是核心 (kernel) 在进行硬体的测试与驱动啦。 但是讯息都是'刷'的一声就跑过去了!完全来不及看!伤脑筋~ 这些讯息有时候对于系统管理员是很重要的,因为他提供了系统的资讯呀! 要看这些讯息你可以用 dmesg 这个指令来观看! 因为讯息实在太多了,所以可以加入这个管线指令' | more '来使画面暂停!
这个 sar 并不是系统预设的安装套件,如果您不是选择全部安装的话,这个套件预设是不装的。 不过,如果您是选择全部安装,嘿嘿!那就可以玩这个 sar 了。 这个 sar 的功能倒是可以玩一玩的,因为他可以在您想要主动侦测主机的资源状态, 然后绘制成为图表时,相当好用的一个工具喔!
还记得我们提过的多人多工环境吧?因为目前的 x86 平台的 CPU 可以做到多工的行为, 所以�,我们的 Linux 可以在 x86 上面'同时进行多个工作'的呢!那么多个工作是如何进行的呢? 其实每个工作都会进入到 CPU 的工作排程当中,并等待 CPU 来执行, 而 CPU 会根据每个工作的优先执行序 (priority) 来判断谁比较重要, 所以某个工作就可能会比较优先被执行完毕啦! 也就是说, Linux 系统中,每个 process 都会拥有一个所谓的'优先执行序 (priority)'的属性, 利用该属性来让 CPU 判断那个工作是比较重要的,那个工作在一群工作当中就会优先被执行, 也让系统资源可以分配的更恰当。我们可以使用 ps 还观察优先执行序:
刚好,由上面这个范例当中我们也看的出来,虽然修改的是 bash 那个 PID 为 18852 的程序, 但是该程序所触发的 ps 指令当中的 PID 同样的也有一个 nice = 10 的结果喔! 了解了吧?整个 nice 值是可以在父程序 --> 子程序之间传递的呢! 另外,除了 renice 之外,其实那个 top 同样的也是可以调整 nice 值的! top 也是可以调整已经存在的某个 process 的 nice 喔! 我们在 档案与目录管理当中的 SUID/SGID/SBIT 提到这一些奇怪的特殊权限的档案,这些档案到底是怎么产生特殊权限的行程?还有, 在磁碟挂载的时候,有时老是出现' device is busy '的字样,真麻烦~到底是怎么回事啊? 我们底下就来谈一谈。 虽然已经在前面的章节提过 SUID/SGID 等等的特殊权限,但是到底他是如何产生的? 首先,我们以条列式的方法列出使用者是否能够操作 SUID/SGID 的指令吧!
那么既然 SUID/SGID 的权限是比较可怕的,您该如何查询整个系统的 SUID/SGID 的档案呢? 应该是还不会忘记吧?使用 find 即可啊!
其实,我们之前提到的所谓的程序都是在记忆体当中嘛!而记忆体当中的资料又都是写入到 /proc/* 这个目录下的,所以�,我们当然可以直接观察 /proc 这个目录当中的档案啊! 如果您观察过 /proc 这个目录的话,应该会发现他有点像这样:
其实,上面这些档案鸟哥在此建议您可以使用 cat 去查阅看看,不必深入了解, 不过,观看过档案内容后,毕竟会比较有感觉啦!如果未来您想要自行撰写某些工具软体, 那么这个目录底下的相关档案可能会对您有点帮助的喔! 其实还有一些与程序相关的指令可以值得参考与应用的,我们来谈一谈: 如果当我们要卸载某个装置时,他老是告诉我们' device is busy ', 那么到底是那个程序在使用这个装置呢?举例来说,当无法 umount /home 时, 该怎么办?此时我们可以使用 fuser 来帮忙啦!
相对于 fuser 是由档案或者装置去找出使用该档案或装置的程序,反过来说, 如何查出某个程序开启或者使用的档案与装置呢?呼呼!那就是使用 lsof �~
( 要看答案请将滑鼠移动到'答:'底下的空白处,按下左键圈选空白处即可察看 )
2002/06/28:第一次完成 2003/02/10:重新编排与加入 FAQ 2005/09/07:将旧的文章移动到 此处 。 2005/09/18:哈哈,终于将这篇写完�。新增了一些简单的小指令啦。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| http://blog.csdn.net/lovevc2002/archive/2007/06/29/1671400.aspx |
No comments:
Post a Comment