关于作者

用户名:今夜无风
笔名:今夜无风
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



优秀网站

访问统计:
文章个数:321
评论个数:58
留言条数:5




Powered by BlogDriver 2.1

莹窗小语

 

喜欢尝试新事物的我,要做好最重要和 最紧急的事情,合理安排学习计划。 希望大家一起分享每份心情!

文章

好久没来了

今天突然想到了自己还有个博客,是要记录些什么。回到老家工作,干的事情,如妈妈的话,

读了这么多年的书,还得像民工样工作。那种整天坐办公室,公务员,事业单位没想法。活该。

我想这是一个过渡期,总有一天创造属于自己的蓝天。

为了美好的明天,平常一定要约束自己,好好提高。

为将来做准备。

- 作者: 今夜无风 2007年08月21日, 星期二 20:10  回复(1) |  引用(0) 加入博采

已锁定
此日志的浏览权限已被作者锁定,请同作者联系,发送短消息,如果你的身份符合作者的要求,点击此处可以进行浏览

- 作者: 今夜无风 2006年11月24日, 星期五 21:17  回复(1) |  引用(0) 加入博采

已锁定
此日志的浏览权限已被作者锁定,请同作者联系,发送短消息,如果你的身份符合作者的要求,点击此处可以进行浏览

- 作者: 今夜无风 2006年11月24日, 星期五 21:15  回复(2) |  引用(0) 加入博采

已锁定
此日志的浏览权限已被作者锁定,请同作者联系,发送短消息,如果你的身份符合作者的要求,点击此处可以进行浏览

- 作者: 今夜无风 2006年11月24日, 星期五 21:15  回复(1) |  引用(0) 加入博采

已锁定
此日志的浏览权限已被作者锁定,请同作者联系,发送短消息,如果你的身份符合作者的要求,点击此处可以进行浏览

- 作者: 今夜无风 2006年11月24日, 星期五 21:14  回复(2) |  引用(0) 加入博采

Linux启动时间的极限优化
作者: s5unty   发表日期: 2006-09-24 00:13   复制链接




   在上次完成嵌入式应用的Linux裁减后, Linux的启动时间仍需要 7s 左右,虽然勉强可以接受,但仍然没有达到我个人所追求的目标——2s 以内。况且,在实际的商用环境中,设备可靠性的要求可是“5个9”(99.999%,即OOS时间低于5分钟/年),这就意味着每减少一秒钟Linux启 动(设备复位)时间,对可靠性都是一个明显的提升。

  言归正传,如何着手对Linux的启动时间进行优化呢?

  CELF(The Consumer Electronics Linux Forum)论坛为我们指引了一个方向。

(1)首先是对Linux启动过程的跟踪和分析,生成详细的启动时间报告。

   较为简单可行的方式是通过PrintkTime功能为启动过程的所有内核信息增加时间戳,便于汇总分析。PrintkTime最早为CELF所提供的一 个内核补丁,在后来的Kernel 2.6.11版本中正式纳入标准内核。所以大家可能在新版本的内核中直接启用该功能。如果你的Linux内核因为某些原因不能更新为2.6.11之后的版 本,那么可以参考CELF提供的方法修改或直接下载它们提供的补丁:http://tree.celinuxforum.org/CelfPubWiki/PrintkTimes

   开启PrintkTime功能的方法很简单,只需在内核启动参数中增加“time”即可。当然,你也可以选择在编译内核时直接指定 “Kernel hacking”中的“Show timing information on printks”来强制每次启动均为内核信息增加时间戳。这一种方式还有另一个好处:你可以得到内核在解析启动参数前所有信息的时间。因此,我选择后一种 方式。

  当完成上述配置后,重新启动Linux,然后通过以下命令将内核启动信息输出到文件:

dmesg -s 131072 > ktime

  然后利用一个脚本“show_delta”(位于Linux源码的scripts文件夹下)将上述输出的文件转换为时间增量显示格式:

/usr/src/linux-x.xx.xx/scripts/show_delta ktime > dtime

  这样,你就得到了一份关于Linux启动时间消耗的详细报告。

(2)然后,我们就来通过这份报告,找出启动中相对耗时的过程。

  必须明确一点:报告中的时间增量和内核信息之间没有必然的对应关系,真正的时间消耗必须从内核源码入手分析。

   这一点对于稍微熟悉编程的朋友来说都不难理解,因为时间增量只是两次调用printk之间的时间差值。通常来说,内核启动过程中在完成一些耗时的任务, 如创建hash索引、probe硬件设备等操作后会通过printk将结果打印出来,这种情况下,时间增量往往反映的是信息对应过程的耗时;但有些时候, 内核是在调用printk输出信息后才开始相应的过程,那么报告中内核信息相应过程的时间消耗对应的是其下一行的时间增量;还有一些时候,时间消耗在了两 次内核信息输出之间的某个不确定的时段,这样时间增量可能就完全无法通过内核信息反应出来了。

  所以,为了准确判断真正的时间消耗,我们需要结合内核源码进行分析。必要的时候,例如上述第三种情形下,还得自己在源码中插入printk打印,以进一步确定实际的时间消耗过程。

  以下是我上次裁减后Linux内核的启动分析:

  内核启动总时间: 6.188s

  关键的耗时部分:
  1) 0.652s - Timer,IRQ,Cache,Mem Pages等核心部分的初始化
  2) 0.611s - 内核与RTC时钟同步
  3) 0.328s - 计算Calibrating Delay(4个CPU核心的总消耗)
  4) 0.144s - 校准APIC时钟
  5) 0.312s - 校准Migration Cost
  6) 3.520s - Intel E1000网卡初始化

  下面,将针对上述各部分进行逐一分析和化解。

(3)接下来,进行具体的分项优化。

  CELF已经提出了一整套针对消费类电子产品所使用的嵌入式Linux的启动优化方案,但是由于面向不同应用,所以我们只能部分借鉴他们的经验,针对自己面对的问题作出具体的分析和尝试。

  内核关键部分(Timer、IRQ、Cache、Mem Pages……)的初始化目前暂时没有比较可靠和可行的优化方案,所以暂不考虑。

  对于上面分析结果中的 2、3 两项,CELF已有专项的优化方案:“RTCNoSync”和“PresetLPJ”。

   前者通过屏蔽启动过程中所进行的RTC时钟同步或者将这一过程放到启动后进行(视具体应用对时钟精度的需求而定),实现起来比较容易,但需要为内核打补 丁。似乎CELF目前的工作仅仅是去掉了该过程,而没有实现所提到的“延后”处理RTC时钟的同步。考虑到这个原因,我的方案中暂时没有引入这一优化(毕 竟它所带来的时间漂移已经达到了“秒”级),继续关注中。

  后者是通过在启动参数中强制指定LPJ值而跳过实际的计算过程,这是基于LPJ值在硬件条件不变的情况下不会变化的考虑。所以在正常启动后记录下内核信息中的“Calibrating Delay”数值后就可以在启动参数中以下面的形式强制指定LPJ值了:

lpj=9600700

   上面分析结果中的 4、5 两项都是SMP初始化的一部分,因此不在CELF研究的范畴(或许将来会有采用多核的MP4出现?……),只能自力更生了。研究了一下SMP的初始化代 码,发现“Migrtion Cost”其实也可以像“Calibrating Delay”采用预置的方式跳过校准时间。方法类似,最后在内核启动参数中增加:

migration_cost=4000,4000

   而Intel的网卡驱动初始化优化起来就比较麻烦了,虽然也是开源,但读硬件驱动完全不比读一般的C代码,况且建立在如此肤浅理解基础上的“优化”修改 也实在难保万全。基于可靠性的考虑,我最终在两次尝试均告失败后放弃了这一条路。那么,换一个思维角度,可以借鉴CELF在 “ParallelRCScripts”方案中的“并行初始化”思想,将网卡驱动独立编译为模块,放在初始化脚本中与其它模块和应用同步加载,从而消除 Probe阻塞对启动时间的影响。考虑到应用初始化也可能使用到网络,而在我们的实际硬件环境中,只有eth0是供应用使用的,因此需要将第一个网口初始 化的0.3s时间计算在内。

  除了在我的方案中所遇到的上述各优化点,CELF还提出了一些你可能会感兴趣的有特定针对性的专项优化,如:

  ShortIDEDelays - 缩短IDE探测时长(我的应用场景中不包含硬盘,所以用不上)
  KernelXIP - 直接在ROM或Flash中运行内核(考虑到兼容性因素,未采用)
  IDENoProbe - 跳过未连接设备的IDE口
  OptimizeRCScripts - 优化initrd中的linuxrc脚本(我采用了BusyBox更简洁的linuxrc)

  以及其它一些尚处于设想阶段的优化方案,感兴趣的朋友可以访问CELF Developer Wiki了解详情。

(4)优化结果

   经过上述专项优化,以及对inittab、rcS脚本的冗余裁减,整个Linux内核的启动时间从优化前的 6.188s 下降到了最终的 2.016s,如果不包含eth0的初始化,则仅需 1.708s(eth0初始化可以和系统中间件及部分应用加载并行),基本达到了既定目标。与Kexec配合,可以大大降低软件故障导致的复位时间,有效 的提升了产品的可靠性。

  大家如果对内核启动时间的优化还有什么建议或疑惑,都欢迎与我探讨。:)

  转自http://blog.oasisfeng.com/2006/09/21/linux-bootup-time-optimization/

- 作者: 今夜无风 2006年11月24日, 星期五 21:12  回复(1) |  引用(0) 加入博采

linux rar zip
·linux下的rar和zip使用     -|juwen 发表于 2006-9-12 14:46:00

.rar
带有 .rar 文件扩展名的文件是使用 RAR 和 WinRAR 归档和压缩工具创建的,这些工具由 Eugene Roshal 开发。他先是发行了用于 MS-DOS 操作系统的这些工具。RAR 受到用户的青睐是因为他们看重它的广泛特性和高压缩比率,以及友好的用户界面,它与 Norton Commander 的界面(或 Midnight Commander 的界面)很相似。

因为 RAR For Linux 是该软件的完整移植,因此您可以享受到原始 RAR 的所有好处(除 MC 样式的界面以外)。但要记住,RAR for Linux 不是免费的;必须向总部在芬兰的一家公司 T:mi Softronic 注册它。

RAR for Linux 选项的列表给人的印象深刻,可以用作其它归档和压缩工具开发人员的任务列表。要压缩单个文件,输入 rar a archive file.rar 扩展名将自动附加到档案后(它的完整文件名将是 archive.rar)。如果 archive.rar 已在当前工作目录中存在,您尝试添加到 archive.rar 的文件就将直接添加到现有档案中。只有在 archive.rar 已包含带有相同名称的文件时,旧文件才会被新文件替代。其它存储在档案内部的文件将保持不变。请记住,该操作是 盲目的,意味着 RAR 不检查文件的时间戳记;只有在 a 选项后添加了 -u 选项时才执行这一检查。请注意,a 前面没有减号 (-)(例如,rar a -u archive file)。

多个文件的归档非常简单:要将当前工作目录中的所有文件和目录归档,输入 rar a archive。要将特定目录的内容归档,输入 rar a archive /path/to/directory。要将一组文件归档,将它们括在引号中,象这样: rar a archive '*.cpp'

文件替换规则和 -u 选项对多个文件和单个文件所起的作用是一样的。通配符使用的语法和您在常用的 shell 中所使用的语法相同,但必须记住要用引号括起它们。

以下是其它一些 RAR 选项:

  • l -- 列出档案内容(例如,rar l archive.rar
  • v -- 列出详细格式的档案内容(例如,rar v archive.rar
  • t -- 测试档案的完整性(例如,rar t archive.rar


请注意,不是所有 RAR 选项都以减号 (-) 开头;有关详细信息,请运行不带任何选项和自变量的 RAR(例如,如果 RAR 目录位于当前工作目录中,运行 rar/rar)。有关详细信息,请参阅 RAR 手册文件(它是 rar.txt 文件,同样位于 RAR 目录中)。

使用 RAR,您可以解压缩整个档案(使用 rar e archive.rar)、单个文件(使用 rar e archive.rar file)或一组文件(使用 rar e archive.rar '*.cpp')。因为 RAR 可以对多个文件使用,您可以使用 rar e '*.rar' '*.cpp' 从多个档案中抽取几组文件。

当 RAR 无法从一个档案中抽取文件时,使用修复选项进行挽救:rar r archive.rar

可以从官方 RAR 站点获得自抽取档案形式的 RAR for Linux。需要使用 ./rarlnx271.sfx 命令来运行它(结尾的数字可能会因为发行了新版本的 RAR 而有所不同)。档案将其内容解包到当前工作目录中自动创建的 rar 子目录中。您可以在其中找到 rar 二进制。可以将 rar 二进制移到 /sbin/usr/sbin 目录中,这样所有用户都可以使用它。除了 RAR 本身,您还可以获得 UnRAR,它是一个小型实用程序,用于解压缩 .rar 文件,如果您希望允许其它用户打开这样的档案但不创建它们,这个实用程序使用起来非常方便。

 

.zip
.zip 扩展名表示文件是使用许多 zip 归档程序和压缩程序之一(但不是 gzip)创建的。因为这是一种非常流行的压缩格式,算法的详细描述也有很多,所以可找到用于所有操作系统的有用的移植形式。这包括创建和扩展带有 .zip 文件扩展名的档案的压缩和解压缩实用程序。在 Linux 上有两种这样的工具:免费的 Info-ZIP 和以赢利为目的的 PKZIP for Linux。如果您只是偶尔需要创建或打开 zip 文件,使用 Info-ZIP。如果希望使用在 MS-DOS 或其它系统上使用的相同工具,请选择 PKZIP(PKZIP 可用于许多操作系统)。用于微软 Windows 的 WinZIP 和用于 Mac OS 的 Stufflt 这两种实用程序可以创建和打开相互之间兼容的档案。

Info-ZIP 在无法使用 gzip 或 tar 的情况下可以提供压缩和解压缩的一个不错的选择,这或许是在 Linux、微软 Windows 和 Mac OS 用户之间交换压缩文件的一种最好的形式。有许多不错的 zip 程序(有开放源码的,也有商业的)可用于这些操作系统,它们应该能确保文件的顺利交换(当然,只要是在特定于某个特定工具的特殊功能关闭的情况下)。

要归档单个文件,输入 zip archive file。要压缩多个文件,使用通配符(例如,zip archive picture*jpg)。还有可能将文件定向输出到 zip;输入 man zip 获得详细信息。要归档整个目录,包括其中所有子目录的内容,使用 -r 选项,然后在档案名后输入目录名(例如,zip -r archive directory)。还可以输入 zip -R archive . 来将当前当前工作目录进行归档。.zip 扩展名自动添加到档案名后。

zip 发现已有档案的名称和您尝试创建的名称相同时,它将您希望压缩的文件添加到现有档案中,而不将已存在的文件除去。这一规则有一个例外:如果存储在现有档案中的一个或多个文件和您希望压缩的一个或多个文件具有相同的名称,旧文件将由新文件替换。文件替换规则可以使用 -u 选项来修改(有关详细信息,请参阅 man zip)。

以下是其它一些 zip 选项:

  • -j -- 只存储文件名,不带访问路径(例如,zip -j archive file
  • -t -- 测试档案的完整性(例如,zip -t archive.zip
  • -x -- 排除文件(例如,zip -r archive ./* -x *.tmp



 

请注意,不是所有 zip 选项都以负号 (-) 开头。

PKZIP 选项类似于 Info-ZIP,但您应该阅读 pkzip.htm 手册(它是一个 HTML 文档;使用 lynx pkzip.htmnetscape pkzip.htm 阅读)来确保您的操作正确。

要解压缩 zip 文件,使用 unzip archive.zip 命令。如果想指定将档案扩展到哪个目录中,可以使用 -d 选项(例如,unzip file.zip -d /home/james/zipsfile.zip 的内容抽取到 /home/james/zips 目录中)。

注:Aladdin Expander for Linux 也可以解压缩 zip 文件。有关详细信息,请参阅有关 .sit 文件的那一节。

当 zip 无法抽取档案中的文件时,使用 -F-FF 修复 zip 选项进行挽救(例如 zip -F archive.zipzip -FF archive.zip)。请记住在尝试拯救已破坏的档案之前进行备份。

可以从官方 Info-ZIP 站点获得二进制或源码形式的 Info-ZIP for Linux。

可以从 PKZIP 官方站点下载 PKZIP for Linux。它作为自抽取档案分发。要为它解包,输入 ./pklin251.exe,档的内容将解包到当前工作目录中。您需要将 pkzip25 二进制文件复制到 /sbin/usr/sbin 目录中,这样系统上的所有用户都可以使用它。(但您必须购买相应的许可证,因为它是商业软件包。)

gzip:http://www.gnu.org/software/gzip/gzip.html

tar:http://www.gnu.org/software/tar/tar.html

WinZIP:http://www.winzip.com

StuffIt:http://www.aladdinsys.com

Aladdin Expander: http://www.aladdinsys.com/expander/expander_linux_login.html

下载源码形式的 Info-ZIP:http://www.freesoftware.com/pub/infozip

下载二进制形式的 Info-ZIP:http://www.linux.org/dist/index.html

下载 PKZIP:http://www.pkzip.org/shareware/pkzip_unix.html

- 作者: 今夜无风 2006年11月24日, 星期五 21:11  回复(3) |  引用(0) 加入博采

AWK实例

通用线程:Awk 实例,第 1 部分
一种名称很奇特的优秀语言介绍

Daniel Robbins
总裁兼 CEO,Gentoo Technologies, Inc.
2000 年 12 月

转载自:IBM developerWorks 中国网站

内容:

 

Awk 是一种非常好的语言,同时有一个非常奇怪的名称。在本系列(共三篇文章)的第一篇文章中,Daniel Robbins 将使您迅速掌握 awk 编程技巧。随着本系列的进展,将讨论更高级的主题,最后将演示一个真正的高级 awk 演示程序。

捍卫 awk
在本系列文章中,我将使您成为精通 awk 的编码人员。我承认,awk 并没有一个非常好听且又非常“时髦”的名字。awk 的 GNU 版本(叫作 gawk)听起来非常怪异。那些不熟悉这种语言的人可能听说过 "awk", 并可能认为它是一组落伍且过时的混乱代码。它甚至会使最博学的 UNIX 权威陷于错乱的边缘(使他不断地发出 "kill -9!" 命令,就象使用咖啡机一样)。

的确,awk 没有一个动听的名字。但它是一种很棒的语言。awk 适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行需要特殊技巧程序设计。与某些语言不同,awk 的语法较为常见。它借鉴了某些语言的一些精华部分,如 C 语言、python 和 bash(虽然在技术上,awk 比 python 和 bash 早创建)。awk 是那种一旦学会了就会成为您战略编码库的主要部分的语言。

第一个 awk
让我们继续,开始使用 awk,以了解其工作原理。在命令行中输入以下命令:

$ awk '{ print }' /etc/passwd

您将会见到 /etc/passwd 文件的内容出现在眼前。现在,解释 awk 做了些什么。调用 awk 时,我们指定 /etc/passwd 作为输入文件。执行 awk 时,它依次对 /etc/passwd 中的每一行执行 print 命令。所有输出都发送到 stdout,所得到的结果与与执行catting /etc/passwd完全相同。

现在,解释 { print } 代码块。在 awk 中,花括号用于将几块代码组合到一起,这一点类似于 C 语言。在代码块中只有一条 print 命令。在 awk 中,如果只出现 print 命令,那么将打印当前行的全部内容。

这里是另一个 awk 示例,它的作用与上例完全相同:

$ awk '{ print $0 }' /etc/passwd

awk 中,$0 变量表示整个当前行,所以 printprint $0 的作用完全一样。

如果您愿意,可以创建一个 awk 程序,让它输出与输入数据完全无关的数据。以下是一个示例:

$ awk '{ print "" }' /etc/passwd

只要将 "" 字符串传递给 print 命令,它就会打印空白行。如果测试该脚本,将会发现对于 /etc/passwd 文件中的每一行,awk 都输出一个空白行。再次说明, awk 对输入文件中的每一行都执行这个本。以下是另一个示例:

$ awk '{ print "hiya" }' /etc/passwd

运行这个脚本将在您的屏幕上写满 hiya。:)

多个字段
awk 非常善于处理分成多个逻辑字段的文本,而且让您可以毫不费力地引用 awk 脚本中每个独立的字段。以下脚本将打印出您的系统上所有用户帐户的列表:

$ awk -F":" '{ print $1 }' /etc/passwd

上例中,在调用 awk 时,使用 -F 选项来指定 ":" 作为字段分隔符。awk 处理 print $1 命令时,它会打印出在输入文件中每一行中出现的第一个字段。以下是另一个示例:

$ awk -F":" '{ print $1 $3 }' /etc/passwd

以下是该脚本输出的摘录:

halt7
operator11
root0
shutdown6
sync5
bin1
....etc.

如您所见,awk 打印出 /etc/passwd 文件的第一和第三个字段,它们正好分别是用户名和用户标识字段。现在,当脚本运行时,它并不理想 -- 在两个输出字段之间没有空格!如果习惯于使用 bash 或 python 进行编程,那么您会指望 print $1 $3 命令在两个字段之间插入空格。然而,当两个字符串在 awk 程序中彼此相邻时,awk 会连接它们但不在它们之间添加空格。以下命令会在这两个字段中插入空格:

$ awk -F":" '{ print $1 " " $3 }' /etc/passwd

以这种方式调用 print 时,它将连接 $1" " 和 $3,创建 可读的输出。当然,如果需要的话,我们还可以插入一些文本标签:

$ awk -F":" '{ print "username: " $1 "ttuid:" $3" }' /etc/passwd

这将产生以下输出:

username: halt          uid:7
username: operator      uid:11
username: root          uid:0
username: shutdown      uid:6
username: sync          uid:5
username: bin           uid:1
....etc.

外部脚本
将脚本作为命令行自变量传递给 awk 对于小的单行程序来说是非常简单的,而对于多行程序,它就比较复杂。您肯定想要在外部文件中撰写脚本。然后可以向 awk 传递 -f 选项,以向它提供此脚本文件:

$ awk -f myscript.awk myfile.in

将脚本放入文本文件还可以让您使用附加 awk 功能。例如,这个多行脚本与前面的单行脚本的作用相同,它们都打印出 /etc/passwd 中每一行的第一个字段:

BEGIN {
    FS=":"
}

{ print $1 }

这两个方法的差别在于如何设置字段分隔符。在这个脚本中,字段分隔符在代码自身中指定(通过设置 FS 变量),而在前一个示例中,通过在命令行上向 awk 传递 -F":" 选项来设置 FS。通常,最好在脚本自身中设置字段分隔符,只是因为这表示您可以少输入一个命令行自变量。我们将在本文的后面详细讨论 FS 变量。

BEGIN 和 END 块
通常,对于每个输入行,awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之执行初始化代码。对于这种情况,awk 允许您定义一个 BEGIN 块。我们在前一个示例中使用了 BEGIN 块。因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。

awk 还提供了另一个特殊块,叫作 END 块。awk 在处理了输入文件中的所有行之后执行这个块。通常,END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。

规则表达式和块
awk 允许使用规则表达式,根据规则表达式是否匹配当前行来选择执行独立代码块。以下示例脚本只输出包含字符序列
foo 的那些行:

/foo/ { print }

当然,可以使用更复杂的规则表达式。以下脚本将只打印包含浮点数的行:

/[0-9]+.[0-9]*/ { print }

表达式和块
还有许多其它方法可以选择执行代码块。我们可以将任意一种布尔表达式放在一个代码块之前,以控制何时执行某特定块。仅当对前面的布尔表达式求值为真时, awk 才执行代码块。以下示例脚本输出将输出其第一个字段等于
fred 的所有行中的第三个字段。如果当前行的第一个字段不等于 fredawk 将继续处理文件而不对当前行执行 print 语句:

$1 == "fred" { print $3 }

awk 提供了完整的比较运算符集合,包括 "=="、"<"、">"、"<="、">=" 和 "!="。另外,awk 还提供了 "~" 和 "!~" 运算符,它们分别表示“匹配”和“不匹配”。它们的用法是在运算符左边指定变量,在右边指定规则表达式。如果某一行的第五个字段包含字符序列 root, 那么以下示例将只打印这一行中的第三个字段:

$5 ~ /root/ { print $3 }

条件语句
awk 还提供了非常好的类似于 C 语言的
if 语句。如果您愿意,可以使用 if 语句重写前一个脚本:

{ 
    if ( $5 ~ /root/ ) {
        print $3
    }
}

这两个脚本的功能完全一样。第一个示例中,布尔表达式放在代码块外面。而在第二个示例中,将对每一个输入行执行代码块,而且我们使用 if 语句来选择执行 print 命令。这两个方法都可以使用,可以选择最适合脚本其它部分的一种方法。

以下是更复杂的 awk if 语句示例。可以看到,尽管使用了复杂、嵌套的条件语句,if 语句看上去仍与相应的 C 语言 if 语句一样:

{
    if ( $1 == "foo" ) {
        if ( $2 == "foo" ) {
            print "uno"
        } else {
            print "one"
        }
    } else if ($1 == "bar" ) {
        print "two"
    } else {
        print "three"
    }
}

使用 if 语句还可以将代码:

! /matchme/ { print $1 $3 $4 }

转换成:

{   
    if ( $0 !~ /matchme/ ) {
        print $1 $3 $4
    }
}

这两个脚本都只输出包含 matchme 字符序列的那些行。此外,还可以选择最适合您的代码的方法。它们的功能完全相同。

awk 还允许使用布尔运算符 "||"(逻辑与)和 "&&"(逻辑或),以便创建更复杂的布尔表达式:

( $1 == "foo" ) && ( $2 == "bar" ) { print } 

这个示例只打印第一个字段等于 foo 第二个字段等于 bar 的那些行。

数值变量!
至今,我们不是打印字符串、整行就是特定字段。然而,awk 还允许我们执行整数和浮点运算。通过使用数学表达式,可以很方便地编写计算文件中空白行数量的脚本。以下就是这样一个脚本:

BEGIN   { x=0 }
/^$/    { x=x+1 }
END     { print "I found " x " blank lines. :)" }

BEGIN 块中,将整数变量 x 初始化成零。然后,awk 每次遇到空白行时,awk 将执行 x=x+1 语句,递增 x。处理完所有行之后,执行 END 块,awk 将打印出最终摘要,指出它找到的空白行数量。

字符串化变量
awk 的优点之一就是“简单和字符串化”。我认为 awk 变量“字符串化”是因为所有 awk 变量在内部都是按字符串形式存储的。同时,awk 变量是“简单的”,因为可以对它执行数学操作,且只要变量包含有效数字字符串,awk 会自动处理字符串到数字的转换步骤。要理解我的观点,请研究以下这个示例:

x="1.01"
# We just set x to contain the *string* "1.01"
x=x+1
# We just added one to a *string*
print x
# Incidentally, these are comments :)

awk 将输出:

2.01

有趣吧!虽然将字符串值 1.01 赋值给变量 x,我们仍然可以对它加 一。但在 bash 和 python 中却不能这样做。首先,bash 不支持浮点运算。而且,如果 bash 有“字符串化”变量,它们并不“简单”;要执行任何数学操作,bash 要求我们将数字放到丑陋的 $( ) ) 结构中。如果使用 python,则必须在对 1.01 字符串执行任何数学运算之前,将它转换成浮点值。虽然这并不困难,但它仍是附加的步骤。如果使用 awk,它是全自动的,而那会使我们的代码又好又整洁。如果想要对每个输入行的第一个字段乘方并加一,可以使用以下脚本:

{ print ($1^2)+1 }

如果做一个小实验,就可以发现如果某个特定变量不包含有效数字,awk 在对数学表达式求值时会将该变量当作数字零处理。

众多运算符
awk 的另一个优点是它有完整的数学运算符集合。除了标准的加、减、乘、除,awk 还允许使用前面演示过的指数运算符 "^"、模(余数)运算符 "%" 和其它许多从 C 语言中借入的易于使用的赋值操作符。

这些运算符包括前后加减(i++--foo)、加/减/乘/除赋值运算符( a+=3b*=2c/=2.2d-=6.2)。不 仅如此 -- 我们还有易于使用的模/指数赋值运算符(a^=2b%=4)。

字段分隔符
awk 有它自己的特殊变量集合。其中一些允许调整 awk 的运行方式,而其它变量可以被读取以收集关于输入的有用信息。我们已经接触过这些特殊变量中的一个,FS。前面已经提到过,这个变量让您可以设置 awk 要查找的字段之间的字符序列。我们使用 /etc/passwd 作为输入时,将 FS 设置成 ":"。当这样做有问题时,我们还可以更灵活地使用 FS。

FS 值并没有被限制为单一字符;可以通过指定任意长度的字符模式,将它设置成规则表达式。如果正在处理由一个或多个 tab 分隔的字段,您可能希望按以下方式设置 FS:

FS="t+"

以上示例中,我们使用特殊 "+" 规则表达式字符,它表示“一个或多个前一字符”。

如果字段由空格分隔(一个或多个空格或 tab),您可能想要将 FS 设置成以下规则表达式:

FS="[[:space:]+]"

这个赋值表达式也有问题,它并非必要。为什么?因为缺省情况下,FS 设置成单一空格字符,awk 将这解释成表示“一个或多个空格或 tab”。在这个特殊示例中,缺省 FS 设置恰恰是您最想要的!

复杂的规则表达式也不成问题。即使您的记录由单词 "foo" 分隔,后面跟着三个数字,以下规则表达式仍允许对数据进行正确的分析:

FS="foo[0-9][0-9][0-9]"

字段数量
接着我们要讨论的两个变量通常并不是需要赋值的,而是用来读取以获取关于输入的有用信息。第一个是 NF 变量,也叫做“字段数量”变量。awk 会自动将该变量设置成当前记录中的字段数量。可以使用 NF 变量来只显示某些输入行:

NF == 3 { print "this particular record has three fields: " $0 }

当然,也可以在条件语句中使用 NF 变量,如下:

{   
    if ( NF > 2 ) {
        print $1 " " $2 ":" $3
    }
}

记录号
记录号 (NR) 是另一个方便的变量。它始终包含当前记录的编号(awk 将第一个记录算作记录号 1)。迄今为止,我们已经处理了每一行包含一个记录的输入文件。对于这些情况,NR 还会告诉您当前行号。然而,当我们在本系列以后部分中开始处理多行记录时,就不会再有这种情况,所以要注意!可以象使用 NF 变量一样使用 NR 来只打印某些输入行:

(NR < 10 ) || (NR > 100) { print "We are on record number 1-9 or 101+" }

另一个示例:

{
    #skip header
    if ( NR > 10 ) {
        print "ok, now for the real information!"
    }
}

awk 提供了适合各种用途的附加变量。我们将在以后的文章中讨论这些变量。

现在已经到了初次探索 awk 的尾声。随着本系列的开展,我将演示更高级的 awk 功能,我们将用一个真实的 awk 应用程序作为本系列的结尾。同时,如果急于学习更多知识,请参考以下列出的参考资料。

参考资料

关于作者
Daniel Robbins 居住在新墨西哥州的 Albuquerque。他是 Gentoo Technologies, Inc. 的总裁兼 CEO,Gentoo Linux(用于 PC 的高级 Linux)和 Portage 系统(Linux 的下一代移植系统)的创始人。他还是 Macmillan 书籍 Caldera OpenLinux UnleashedSuSE Linux UnleashedSamba Unleashed 的合作者。Daniel 自二年级起就与计算机某些领域结下不解之缘,那时他首先接触的是 Logo 程序语言,并沉溺于 Pac-Man 游戏中。这也许就是他至今仍担任 SONY Electronic Publishing/Psygnosis 的首席图形设计师的原因所在。Daniel 喜欢与妻子 Mary 和新出生的女儿 Hadassah 一起共度时光。可通过 drobbins@gentoo.org 与 Daniel 联系

参考

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=178145

 

 

 

 

 

 

 

 

 

 

- 作者: 今夜无风 2006年11月24日, 星期五 20:49  回复(1) |  引用(0) 加入博采

UML表示数据流程图

怎样用UML表达业务数据流程图的讨论

明天单位里要求本人从业务数据流的角度讲述系统概念,猛一下子还真不知道具体用什么方式表达和讲解,因此从网上搜到以下论述,感觉和我碰到的问题有些类似。

文章链接:http://www.shecn.com/best/g1/g107.htm

++++++++++++++++++++++
中国UML论坛


原文(kknight于2001/03/07 11:03粘贴)
帮忙讨论一下:我总觉得Rose在画业务流程图上有缺陷
--------------------------------------------------------------------------------


我实在找不到在Rose的哪个功能能很好地画业务流程图。Business use case view, Use case view,Class Diagram都并不合适。好象Activity daigram比较合适点,但不能分层描述,且课件比较简单。我觉得在Business Modeling阶段Rose应该引进数据流图来描述整体的业务流图。
希望大家讨论。
====
Activity daigram 其实跟数据流图很相像的。 UML 中对于一种图形说明不清楚的东西,还可以用文档以及其它的图来说明,这个扩充性是其它工具没有。 - <0b> boss_ch 2001/03/07 11:50 (20次点击)
====
原文(john_zhu于2001/03/07 13:14粘贴)
回复: 帮忙讨论一下:我总觉得Rose在画业务流程图上有缺陷
--------------------------------------------------------------------------------


业务流程图是完全可以由Activity daigram来画的,但首先Rose是一个面向对象的建模工具,在建模时要放弃一部分传统的实现,用传统的思路来使用Rose是大忌。在UML的建立过程中Activity daigram的设立时有争议的,主要是因为使用不好的话会牺牲掉Rose的对象性。Rose中不设数据流图同样有他的道理,但数据流图可以作为发现对象的一种工具。不一定在Rose中实现,当然如果你一定要在Rose中画的话,也是可以的,使用Activity daigram加Business Entity,但有点不伦不类
====
原文(kknight于2001/03/07 14:02粘贴)
回复: 帮忙讨论一下:我总觉得Rose在画业务流程图上有缺陷
--------------------------------------------------------------------------------


我觉得数据流图好的地方是客户方面的人能很容易理解,交流,甚至参与制作。实际上,客户,特别是商业客户,本来就有自己的业务流程图,如票据流转图和操作流程图,它们与数据流图很相识。
我觉得把数据流图加在商业建模或需求分析的前期还是有好处的,我不是强调非要加到设计阶段,因为它确实与OO是不同。
不过确实可以用别的工具来画数据流图,甚至用powerpoint,visio,但我的感觉是Rose就不提倡画这东西,在商业建模阶段就强调用OO的方法来描述现实世界。我想需求分析这东西就是要让人懂的,所以有必要引进一些接近现实的表示方法。


个人看法,希望大家指正。
======
原文(gooses于2001/03/07 15:00粘贴)
回复: 帮忙讨论一下:我总觉得Rose在画业务流程图上有缺陷
--------------------------------------------------------------------------------


业务处理sequence diagram
actor>>form object>>control object>>data object
通过control object控制其流向确定进入哪一个数据库。


业务查询sequence diagram 类似,只是流程有一定区别。


actor再通过角色一般化分类。


====
原文(lcgong于2001/03/07 16:05粘贴)
Activity Diagram, Use Case Model, Collaboration Diagram 要灵活结合使用。
--------------------------------------------------------------------------------


Activity Diagram, Use Case Model, Collaboration/Sequence Diagram是Business Modeling的不同Views。是对系统构架的不同剖面。剖面之间又是有逻辑。所以对于用户只要合适的顺序,层次讲解,客户使可以理解的,因为UML本身的符号并不复杂。
====
原文(liaofan于2001/03/07 20:34粘贴)
系统建模是基础,业务流程是表现形式
--------------------------------------------------------------------------------


UML强调面向对象的建模,强调的是分析结果的重用。最重要的是根据系统面对的问题建立一个稳定的模型框架,而检查框架是否合理的标准之一就是业务流程是否能顺利地实现和业务流程是否能适应变化。所以UML中不强调业务流程图,activity daigram只是一个辅助手段。过多注意业务流程,容易掉入流程分析的陷阱,影响模型的内在合理性。
===
不完全是,ROse内的业务流程不是显示定义的,隐含在Use Case和UseCase的关系中 - <0b> john_zhu 2001/03/08 14:37 (19次点击)
====
原文(omc2000于2001/03/08 09:04粘贴)
回复: 帮忙讨论一下:我总觉得Rose在画业务流程图上有缺陷
--------------------------------------------------------------------------------


you can use Activity Diagram.
===
原文(asiaalien于2001/03/08 09:10粘贴)
回复: 帮忙讨论一下:我总觉得Rose在画业务流程图上有缺陷
--------------------------------------------------------------------------------


可以看看PlayCase啦!我想你一定是在给国内用户做MIS系统之类的软件,否则Rose就很好了。
===
原文(rode于2001/03/09 08:56粘贴)
管见
--------------------------------------------------------------------------------


随笔UML--1
软件需求的业务流程
Use-Case
应用系统构架
Analysis: sequence diagram and interaction diagram 确切的说:Sequence diagram and Interaction diagram 属于对于业务领域的分析模型,基于业务领域的基本概念,而不是抽象出的对象概念;同样设计 时存在sequencediagram and interaction diagram ,此时基于对象的概念,也就是详细设计,同时是从概要设 计发展过来;Data Model :指数据库模式的模型。


注意:UML只是一种建模语言,因此并能代替E-R图,业务流程图(业务流程图将空间平面化,use-case 则是空间的模型),数据字典。
====
原文(john_zhu于2001/03/09 09:32粘贴)
业务流程图,ER图也是系统建模的一种手段
--------------------------------------------------------------------------------


UML和传统的结构化建模方法的区别不止是思路上,还有方法上,我个人认为不要用UML来硬套传统的结构化建模方法。
====
原文(rode于2001/03/09 10:37粘贴)
管见二:
--------------------------------------------------------------------------------


管见二: 我们的目的在于系统的建模,也就是说,从不同的角度和视点来看待整个业务领域的概念,


UML搭构了业务领域的模型,的确是的,他搭建了一个UML世界的活的业务模型,但是如何搭建这模型


之前,必须首先对业务领域(Business Domian)有所了解;然而数据图的确是从功能的角度或者说活动实


体的角度描述了BD,是我们有一个整体的了解(看你用什么眼光看待),于是系统的骨架出来了。那么


我们可以用UML来描述这个骨架,同时添加血和肉,Business Domain Model出现了。
私下认为:流程图不可少。

- 作者: 今夜无风 2006年11月24日, 星期五 20:48  回复(1) |  引用(0) 加入博采

udev答疑
问:什么是udev?
答:udev是一种工具,它能够根据系统中的硬件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在/dev目录下。使用udev后,在/dev目录下就只包含系统中真正存在的设备。

问:udev支持什么内核?
答:udev只支持linux-2.6内核,因为udev严重依赖于sysfs文件系统提供的信息,而sysfs文件系统只在linux-2.6内核中才有。

问:udev是一个内核程序还是用户程序?
答:udev是一个用户程序(user-mode daemon)。

问:udev和devfs有什么差别?
答:udev能够实现所有devfs实现的功能。但udev运行在用户模式中,而devfs运行在内核中。据称:devfs具有一些不太容易解决的先天缺陷。

问:udev的配置文件放在哪里?
答:udev是一个用户模式程序。它的配置文件是/etc/udev/udev.conf。这个文件一般缺省有这样几项:
udev_root="/dev" ; udev产生的设备文件的根目录是/dev
udev_db="/dev/.udevdb" ; 通过udev产生的设备文件形成的数据库
udev_rules="/etc/udev/rules.d" ;用于指导udev工作的规则所在目录。
udev_log="err" ;当出现错误时,用syslog记录错误信息。

参考;http://www.chinaunix.net/

- 作者: 今夜无风 2006年11月24日, 星期五 20:32  回复(2) |  引用(0) 加入博采