Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103682309
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: LINUX

2008-05-04 15:37:47

 

第四篇


#7确认日期格式

确认工作是一项很大的挑战,而在shell script中比较重要的是确认时间,它必需保証日期是有效的。如果我们在这方面忽视了闰年,工作似乎也不会有太大的影响,因为我们的日历规则每年始终如一。在这个例子中,我们比较需要的是:每个月特定日期的表格。另外,对于闰年而言,在script中我们还必须增加闰年的计算规则如下:

● 年不能被4整除,不是闰年

● 年能被4及400整除,是闰年

● 年能被4及100整除,但不能被400整除,不是闰年

● 上面沒提及的年,重要能被4整除就是闰年

注意这个script在处理前利用normdate(#3的程式)确认日期格式。

程序码





执行

请在命令列上以西元「月日年」的方式输入日期。月份的部分,可以打数字、英文全名或三个字母的英文缩写;年的部分必须要输入4位数的格式。





改进与加強

一个与程式有異曲同工之妙的是判別时间格式,时间的表示可能是24小时制或是上 / 下午制(am/pm)。首先先将时间的时分秒区隔出来,确认分与秒是否在0~60之间,接着检查第一个值是否在0~12间(上/下午制)或0~24间(24小时制)。

(很幸运的,在日期生活上,我们不必去理会闰秒及些微时间的变化。)

# 8 避免使用粗糙的echo

当目前大部份的Unix或Linux都拥有echo命令时,它们大都以「-n」的方式来控制系统不要換新行。但并不是所有的系统都使用这种方式,也有一部份的是利用「c」的方式来控制,其他较简单的系统就不理会换新行这个动作。

想了解你的echo是属于那一种吗? 请在命令列下键入下列指令,並观看系统显示的讯息即可得到答案:





如果echo命令是使用「-n」的参数,系统会显示:





如果不是,系统显示情形如下:





使用者看到script的正确输出结果,是十分重要的。特別是当程式的互动性愈来愈频繁时。就更能显示出它的重要性。

程式码

有许多的办法可以解决echo这个问题,将像这篇文章有许多篇一样。这个程序非常简洁,是笔者喜爱的 程序之一:




你可能不喜欢使用awk命令,如果你的系统有printf命令,则程式可改写为:





如果系统没有printf命令,也不想使用awk,你可以改用tr命令:





这段程序利用tr来完成换行的动作,tr对这个程序而言,是一个非常简单而且有效率的解决方案。

执行

现在我们可以利用echon来取代echo,在输入完成后,别忘了按下enter键:





# 9随心所欲的浮点运算器

在写script的过程中,最常用的一种运算写法是 $(( )),它能帮我们完成各种不同形式的数学运算。这种写法对於一般大量的运算相当的好用,它也提供加減乘除及求余数的运算式, 不过並不提供分数及小数的运算。举个例子来看可能会比较清础一点:





这个运算式的传回是0而不是0.5

因此当运算需要更精密时,你可能就必需仰赖你的双手了。在命令模式下除了bc似乎沒有什麼好的计算机。Bc是一个鲜少人知的程式,这是一个準确度极高的计算机,不过卻缺少提示信息,且隐藏错误讯息,试想如果你使用了这个计算机,你应该要知道你在做什麼才对。不过一切都还好,我们可以搞定一切。

程式码



原理

这个script再次証明了shell的能力。这个「<<」标记允许你在script中引用一些输入资料的工具,在这个例子中允许我们把资料传递给bc命令。这也是笔者首次告诉各位:如何在script中引用系统命令並加上参数,让它能夠更有弹性的运用。在这个script中,如果加上-p的参数,就可以设定小数点后要显示几位数,如果沒有任何的设定,将採用系统的预设值,显示小数点后两位。

当我们使用bc时,长度与位数两者间的差別是必须立刻了解的,长度指的是所有数字的数量,而位数指的是小数点后的数字数量。像10.25它的长度是4,而位数是2;3 .14159它的长度是6,位数是5。在bc中,並沒有预设的长度,不过位数的预设值卻是0,且不能透过何的方式( 像 $ (( )) )修改。不过,很幸运地,如果我们利用scale设定,我们可以看到许多隐藏的资源,如下所示:





这个script程式里具有命令列上执行bc的能力,而且不会显示版权讯息,如果它显示出此讯息,可能因为使用者不是在终端机的模式执行此script。

此程式可以直接设定位数的值,並将所有的运算丟给bc来处理,之后再利用quit的命令离开bc。

执行

执行script时,请务必给命令一个完整的数学运算式。

结果



#10锁定档案

任何一个script在存取分享档案时,就像是记錄档一樣,都需要一个可信赖的方法来锁住档案,这麼一来,其他的script程式就无法異动这个档案了。我们可以利用发讯号的方式来识 别已锁定的档案,並告知此档目前在使用中,不能夠存取。要求存取档案的script等待並且再要求,希望档案可以很快的不受限制,意指解除档案的锁定。

锁定档案的工作是很难处理的。以下的例子是一个典型的处理方式,它可以解释这类型的问题:





看起来像是移除锁定了不是吗?你的回圈会到锁定档案不见了才停止,之后会建立一个锁定档以确认档案可以安全的修改。如果有任何的程式要存取这个档案,必须等到锁定档消失后才可正常运作。不过,实际上它沒有运作,因为当输到其他程序时,这个程式並沒有作交換 的动作。试想会发生什麼事:A程式在执行完loop回圈之后与返回到佇列之前。B 程序取代了它,这个B程式发现系统中沒有锁定档,自行建立了一个锁定档,而此时A程式回来了,並且尝试去存取,这两个程式都各自认为它们是唯一有权存取这个挡案的,这下是不是很糟糕呢?

幸好,Stephen van den Berg与Philip Guenther这两个作者写了procmail的邮件过滤程式,里头包含lockfile的命令,让我们可以安全地在系统上正常的使用锁定档。许多的Unix家族,包括Linux与Mac OS X都已经安装了lockfile程式,你可以利用man 1 lockfile 来检查此档是否存在,如果你看到說明页,表示已存在,如果沒看到,请先从/网站上下载procmail,之后再於系统上安装lockfile命令。笔者假设在你已经有lockfile档了,本章以后如果有需要这个档案(特別是第七章)我们不会再多做敘述。

程式码



执行

我们如果只执行一个lockfile程序可能无法看出它的功用,因此建议你开两个终端窗口,分别执行这个程序。建立锁定档时,请在filelock程序后多加一个欲锁定的挡名,移除锁定档时,请用 -u的参数。


结果

第一、建立一个锁定档:


第二、试图锁定档案,filelock预设会试10次,之后会失败,如同以下的结果:





当第一个动作完成后,你可以试著解除档案的锁定:




为了更清楚filelock的运作,我们可以开2个窗口,当A窗口在试著建立自己独佔的锁定档时,同时也在B窗口中执行unlock命令。

改进与加強

由於锁定档案的动作是靠确认锁定档存不存在而決定。因此如果能在程式执行的过程中,透过参数的方式,指定锁定档的锁定时间,或许会让工作发挥更大的效用。如果锁定的时间点已经到了,程序要能检查锁定档最后一次存取的时间,如果这个值比指定的参数还要久,程序便能移除锁定档,当然如果想要做的更理想一点,可以再给使用者一个警告讯息。另外,Lockfile程式无法在NFS的掛载磁碟上工作,可能不会对你造成任何的影响。但是,事实上要在NFS掛载磁碟上作业是很复杂的一件事,因此直接在本地端锁定档案或许是一个比较完美的做法。



出处:南方Linux
阅读(369) | 评论(0) | 转发(0) |
0

上一篇:Linux管理手记(三)

下一篇:Shell 的环境设定

给主人留下些什么吧!~~