linux shell编程指南------shell工具

浏览:
字体:
发布时间:2013-12-17 09:37:06
来源:

在用户登录时,系统将会执行/etc/profile文件,根用户不希望其他普通用户打断一进程。他通常通过设置trap来屏蔽信号1、2、3和1 5,然后在用户读当天的消息时重新打开这些信号。最后仍然回到屏蔽这些信号的状态。

在编写脚本时也可以采用类似的办法。在脚本运行的某些关键时刻,比如打开了很多文件时,不希望该脚本被中断,以免破坏这些文件。通过设置trap来屏蔽某些信号就可以解决这个问题。在这些关键性的处理过程结束后,再重新打开信号。

忽略信号的一般格式为(信号9除外):
trap""signal no:(s)

注意,在双引号之间没有任何字符,为了重新回到捕捉信号的状态,可以使用如下的命令:
trap"do something" signal no:(s)

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

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

关键性的处理过程trap"my_exit" 1 2 3 15:重新回到捕捉信号的状态,在捕捉到信号后调用myexit函数。下面就是一个这样的例子,其中的“关键”过程实际上是一个while循环,但它能够很好地说明这种方法。在第一个循环中,通过设置trap来屏蔽信号,但是在第二个例子中,又回到捕捉信号的状态。

两个循环都只数到6,不过在循环中使用了一个sleep命令,这样就可以有充分的时间来实验中断该循环。

下面就是脚本。
[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

eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量。该命令对变量进行两次扫描。这些需要进行两次扫描的变量有时被称为复杂变量。不过我觉得这些变量本身并不复杂。

eval命令也可以用于回显简单变量,不一定是复杂变量。
[root@localhost huangcd]# NAME=honeysuckle
[root@localhost huangcd]# eval echo $NAME
honeysuckle
[root@localhost huangcd]# echo $NAME
honeysuckle

我们首先创建一个名为testf的小文件,在这个小文件中含有一些文本。接着,将cat testf0赋给变量MYFILE,现在我们echo该变量,看看是否能够执行上述命令。

[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

从上面的结果可以看出,使用eval命令不但可以置换该变量,还能够执行相应的命令。第一次扫描进行了变量置换,第二次扫描执行了该字符串中所包含的命令cat testf。

eval命令还可以用来显示出传递给脚本的最后一个参数。现在来看下面的这个例子。
[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

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

我们用data文件的第一行来解释上述脚本的执行过程,该脚本读入“PC”和“486”两个词,把它们分别赋给变量NAME和TYPE。Eval命令的第一次扫描把NAME和TYPE分别置换为“PC”和“486”,第二次扫描时将PC作为变量,并将“486”作为变量的值。
下面是运行上述脚本的结果:
[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

系统中含有相当多的日志文件。其中的一个日志文件叫作messages,它通常位于/var/adm或/var/log目录下。一个名为syslog的配置文件可以用来定义记录在messages文件中的消息,这些消息有一定的格式。如果想知道系统中的相应配置,可以查看/etc/syslog.conf文件。该文件中包含了用于发送各种不同类型消息的工具及它们的优先级。

这里我们并不想深入探讨UNIX和LINUX是如何向该文件中记录信息的。我们现在只要知道这些消息有不同的级别,从信息性的消息到关键性的消息。

还可以使用logger命令向该文件发送消息。在使用该命令之前,最好查阅连机手册,因为在不同供应商所提供的操作系统上该命令的语法也有所不同。

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

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

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

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

监控脚本的报告。

下面是/ 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

logger命令的一般形式为:
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

>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2024 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();