您的位置:首页 > 运维架构 > Shell

linux shell编程指南第二十六章------shell 工具1

2013-12-15 18:23 555 查看
在用户登录时,系统将会执行/ e t c / p r o f i l e文件,根用户不希望其他普通用户打断这一进程。

他通常通过设置t r a p来屏蔽信号1、2、3和1 5,然后在用户读当天的消息时重新打开这些信号。

最后仍然回到屏蔽这些信号的状态。

在编写脚本时也可以采用类似的办法。在脚本运行的某些关键时刻,比如打开了很多文

件时,不希望该脚本被中断,以免破坏这些文件。通过设置t r a p来屏蔽某些信号就可以解决这

个问题。在这些关键性的处理过程结束后,再重新打开信号。

忽略信号的一般格式为(信号9除外):

trap""signal no:(s)

注意,在双引号之间没有任何字符,为了重新回到捕捉信号的状态,可以使用如下的命

令:

trap"do something" signal no:(s)

下面我们来总结一下上述方法。

trap ""1 2 3 15:忽略信号。

关键性的处理过程

trap"my_exit" 1 2 3 15:重新回到捕捉信号的状态,在捕捉到信号后调用m y e x i t函数。

下面就是一个这样的例子,其中的“关键”过程实际上是一个w h i l e循环,但它能够很好

地说明这种方法。在第一个循环中,通过设置t r a p来屏蔽信号,但是在第二个例子中,又回到

捕捉信号的状态。

两个循环都只数到6,不过在循环中使用了一个s l e e p命令,这样就可以有充分的时间来实

验中断该循环。

下面就是脚本。

[root@localhost huangcd]# cat trap_ignore

#!/bin/bash

trap "" 1 2 3 15

LOOP=0

my_exit()

{

echo "Received interrupt on count $LOOP"

echo "Now exiting"

exit 1

}

LOO=0

while :

do

LOOP=`expr $LOOP + 1`

echo "critical processing..$LOOP..you cannot interrupt me"

sleep 1

if [ "$LOOP" -eq 6 ]

then

break

fi

done

LOOP=0

trap "my_exit" 1 2 3 15

while :

do

LOOP=`expr $LOOP + 1`

echo "no-critical processing..$LOOP..interrupt me if you want"

sleep 1

if [ "$LOOP" -eq 6 ]

then

break

fi

done

[root@localhost huangcd]# sh trap_ignore

critical processing..1..you cannot interrupt me

critical processing..2..you cannot interrupt me

critical processing..3..you cannot interrupt me

critical processing..4..you cannot interrupt me

critical processing..5..you cannot interrupt me

critical processing..6..you cannot interrupt me

no-critical processing..1..interrupt me if you want

Received interrupt on count 1

Now exiting

e v a l命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一

次扫描无法实现其功能的变量。该命令对变量进行两次扫描。这些需要进行两次扫描的变量

有时被称为复杂变量。不过我觉得这些变量本身并不复杂。

e v a l命令也可以用于回显简单变量,不一定是复杂变量。

[root@localhost huangcd]# NAME=honeysuckle

[root@localhost huangcd]# eval echo $NAME

honeysuckle

[root@localhost huangcd]# echo $NAME

honeysuckle

我们首先创建一个名为t e s t f的小文件,在这个小文件中含有一些文本。接着,将cat testf

赋给变量M Y F I L E,现在我们e c h o该变量,看看是否能够执行上述命令。

[root@localhost huangcd]# cat testf

May Day, May Day

Going Down

现在我们将cat testf赋给变量M Y F I L E。

[root@localhost huangcd]# MYFILE="cat testf"

[root@localhost huangcd]# echo $MYFILE

cat testf

[root@localhost huangcd]# eval $MYFILE

May Day, May Day

Going Down

从上面的结果可以看出,使用e v a l命令不但可以置换该变量,还能够执行相应的命令。第

一次扫描进行了变量置换,第二次扫描执行了该字符串中所包含的命令cat testf。

e v a l命令还可以用来显示出传递给脚本的最后一个参数。现在来看下面的这个例子。

[root@localhost huangcd]# cat evalit

#!/bin/bash

echo "Total number of arguments passed is $#"

echo "The process ID IS $$"

echo "Last argument is "$(eval echo \$$#)

[root@localhost huangcd]# sh evalit huang cheng du

Total number of arguments passed is 3

The process ID IS 5351

Last argument is du

可以给一个值一个变量名。下面我对此做些解释,假定有一个名为d a t a的文件:

[root@localhost huangcd]# cat data

PC 486

MONITOR svga

NEWWORD yes

你希望该文件中的第一列成为变量名,第二列成为该变量的值,这样就可以:

我们用d a t a文件的第一行来解释上述脚本的执行过程,该脚本读入“ P C”和“4 8 6”两个

词,把它们分别赋给变量N A M E和T Y P E。E v a l命令的第一次扫描把N A M E和T Y P E分别置换

为“P C”和“4 8 6”,第二次扫描时将P C作为变量,并将“4 8 6”作为变量的值。

下面是运行上述脚本的结果:

[root@localhost huangcd]# cat eval_it

#!/bin/bash

while read NAME TYPE

do

eval `echo "${NAME}=${TYPE}"`

done < data

echo "you have a $PC,with a $MONITOR monitor"

echo "and are you network?$NEWWORK"

[root@localhost huangcd]# sh eval_it

you have a 486,with a svga monitor

and are you network?yes

系统中含有相当多的日志文件。其中的一个日志文件叫作m e s s a g e s,它通常位于/ v a r / a d m

或/ v a r / l o g目录下。一个名为s y s l o g的配置文件可以用来定义记录在m e s s a g e s文件中的消息,这

些消息有一定的格式。如果想知道系统中的相应配置,可以查看/ e t c / s y s l o g . c o n f文件。该文件

中包含了用于发送各种不同类型消息的工具及它们的优先级。

这里我们并不想深入探讨U N I X和L I N U X是如何向该文件中记录信息的。我们现在只要知

道这些消息有不同的级别,从信息性的消息到关键性的消息。

还可以使用l o g g e r命令向该文件发送消息。在使用该命令之前,最好查阅连机手册,因为

在不同供应商所提供的操作系统上该命令的语法也有所不同。

不过,由于这里只涉及到信息性的消息,因此不必担心下面的命令不安全。

你可能会出于下列的原因向该文件中发送消息:

• 在某一个特定的时间段出现的访问或登录。

• 你的某些执行关键任务的脚本运行失败。

• 监控脚本的报告。

下面是/ v a r / a d m / m e s s a g e s文件的例子。在系统上所看到的相应文件可能和下面的例子有

少许差别。

[root@localhost huangcd]# cat /var/log/messages|more

Dec 11 09:49:29 localhost syslogd 1.4.1: restart.

Dec 11 09:49:44 localhost vmsvc[3122]: [ warning] [guestinfo] RecordRoutingInfo:

Unable to collect IPv4 routing table.

Dec 11 09:50:44 localhost last message repeated 2 times

Dec 11 09:52:14 localhost last message repeated 3 times

Dec 11 09:53:44 localhost last message repeated 3 times

Dec 11 09:55:14 localhost last message repeated 3 times

Dec 11 09:56:44 localhost last message repeated 3 times

Dec 11 09:58:14 localhost last message repeated 3 times

Dec 11 09:59:44 localhost last message repeated 3 times

Dec 11 10:01:14 localhost last message repeated 3 times

Dec 11 10:02:44 localhost last message repeated 3 times

Dec 11 10:04:14 localhost last message repeated 3 times

Dec 11 10:05:44 localhost last message repeated 3 times

l o g g e r命令的一般形式为:

logger -p -I message

其中:

- p:为优先级,这里只涉及到提示用户注意的优先级,这也是缺省值。

- i:在每个消息中记录发送消息的进程号。

可以使用如下命令向message文件写入一下数据,可能要几分钟以后才能看到:

[root@localhost huangcd]# logger -p notice "this id a test message.ignore $LOGNAME"

[root@localhost huangcd]# tail /var/log/messages

Dec 15 18:02:47 localhost syslogd 1.4.1: restart.

Dec 15 18:03:00 localhost vmsvc[3157]: [ warning] [guestinfo] RecordRoutingInfo: Unable to collect IPv4 routing table.

Dec 15 18:04:00 localhost last message repeated 2 times

Dec 15 18:04:02 localhost root: this id a test message.ignore root

如你所见,发送这一消息的用户也被记录了下来。

向日志文件中发送信息的一个更为合理的用途就是用于脚本非正常退出时。如果希望向

日志文件中发送消息,只要在捕获信号的退出函数中包含l o g g e r命令即可。

在下面的清除脚本中,如果该脚本捕获到信号2、3或1 5的话,就向该日志文件发送一个

消息。

[root@localhost huangcd]# cat cleanup1

#!/bin/bash

trap "my_exit" 2 3 15

my_exit()

{

logger -p notice "`basename $0`:was killed whilst cleaning up system log"

exit 1

}

while [ "1" -lt "2" ]

do

sleep 1

done

[root@localhost huangcd]# sh cleanup1

[root@localhost huangcd]# cat /var/log/messages

Dec 15 18:02:47 localhost syslogd 1.4.1: restart.

Dec 15 18:03:00 localhost vmsvc[3157]: [ warning] [guestinfo] RecordRoutingInfo: Unable to collect IPv4 routing table.

Dec 15 18:04:00 localhost last message repeated 2 times

Dec 15 18:04:02 localhost root: this id a test message.ignore root

Dec 15 18:04:30 localhost vmsvc[3157]: [ warning] [guestinfo] RecordRoutingInfo: Unable to collect IPv4 routing table.

Dec 15 18:20:30 localhost last message repeated 3 times

Dec 15 18:21:00 localhost vmsvc[3157]: [ warning] [guestinfo] RecordRoutingInfo: Unable to collect IPv4 routing table.

Dec 15 18:21:06 localhost root: cleanup1:was killed whilst cleaning up system log

Dec 15 18:21:30 localhost vmsvc[3157]: [ warning] [guestinfo] RecordRoutingInfo: Unable to collect IPv4 routing table.

Dec 15 18:21:37 localhost root: cleanup1:was killed whilst cleaning up system log
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: