Shell 语法和工作实例
Shell 语法和工作实例
一、Shell 测试运算和流程控制语句
二、监控disk、cpu和处理qmail邮件队列
三、 Shell 脚本是什么
一、Shell 测试运算和流程控制语句
basename 和 dirname 可以截取文件名和路径. ${varible##*string} 从左向右截取最后一个string后的字符串 ${varible#*string}从左向右截取第一个string后的字符串 ${varible%%string*}从右向左截取最后一个string后的字符串 ${varible%string*}从右向左截取第一个string后的字符串 [bo@localhost ~]$ dirname /home/bo/erro.html /home/bo [bo@localhost ~]$ basename /home/bo/erro.html erro.html [bo@localhost ~]$ [bo@localhost ~]$ test_cut=/home/bo/error.html [bo@localhost ~]$ echo ${test_cut##*/} error.html [bo@localhost ~]$ echo ${test_cut#*/} home/bo/error.html [bo@localhost ~]$ echo ${test_cut%/*} /home/bo [bo@localhost ~]$ 学习Shell 前的“热身运动”
预定义变量和环境变量相类似,也是在shell一开始时就定义了的变量,所不同的是,用户只能根据shell的定义来使用这些变量,而不能重定义它。所有预定义变量都是由$符和另一个符号组成的,常用的shell预定义变量有: $#:位置参数的数量 $*:所有位置参数的内容 $?:命令执行后返回的状态 $$:当前进程的进程号 $!:后台运行的最后一个进程号 $0:当前执行的进程名 其中,“$?”用于检查上一个命令执行是否正确(在Linux中,命令退出状态为0表示该命令正确执行,任何非0值表示命令出错)。 “$$”变量最常见的用途是用作临时文件的名字以保证临时文件不会重复。 hadoop@puppet-client:/tmp> sh tesh.sh aaa bbb 333 444 "$#:" 4 "$*:" aaa bbb 333 444 "$?:" 0 "$$:" 9110 "$!:" "$0:" tesh.sh "$@:" aaa bbb 333 444 hadoop@puppet-client:/tmp> hadoop@puppet-client:/tmp> cat te.sh echo '"$#:"' $# echo '"$*:"' $* echo '"$?:"' $? echo '"$$:"' $$ echo '"$!:"' $! echo '"$0:"' $0 echo '"$@:"' $@ hadoop@puppet-client:/tmp>
测试运算
数值测试运算
-eq 判断两个数字是否相等,相等返回“0”,不相等返回“1”
-ge 判断第一个数字是否大于等于第二个数字,大于等于返回0,小于返回“1”
-gt 判断第一个数字是否大于第二个数字,大于返回“0”,不大于返回“1”
-le 判断第一个数字是否小于等于第二个数字,小于等于返回“0”,大于返回“1”
-lt 判断第一个数字是否小于第二个数字,小于返回“0”,不小于返回“1”
-ne 判断两个数不相等,不相等返回“0” ,相等返回“1”
字符串运算测试
string1 = string2 如果两个字符串相等则返回true, 否则返回false。
string1 != string2 如果两个字符串不相等则返回true, 否则返回false。
string1 > string2 如果string 1 大于 string2, 则返回true ,否则返回false。
string1 < string2 如果string 1小于string 2 , 则返回true,否则返回false。
-n string: 如果字符中长度大于0,则返回true , 否则返回false; 通常可以省略-n
-z string: 如果字符串的长度等于0,则返回true, 否则返回false。
文件测试运算
-d filename 判断filename 是否为目录,是则返回0,否则返回1
-f filename 判断filename 是否为文件,是则返回0,否则返回1
-r filename 判断filename 是否可读, 是则返回0,否则返回1
-w filename 判断filename 是否可写, 是则返回0,否则返回1
-x filename 判断filename 是否可执行, 是则返回0,否则返回1
-L filename 判断filename 是否是一个符号链接文件, 是则返回0,否则返回1
-s filename 判断filename 的长度是否大于0, 是则返回0,否则返回1
-u filename 判断filename 是否有suid位设置, 是则返回0,否则返回1
-e 文件存在
-a 文件存在
这个选项的效果与-e相同.但是它已经被弃用了,并且不鼓励使用
-f file是一个regular文件(不是目录或者设备文件)
-s 文件长度不为0
-d 文件是个目录
-b 文件是个块设备(软盘,cdrom等等)
-c 文件是个字符设备(键盘,modem,声卡等等)
-p 文件是个管道
-h 文件是个符号链接
-L 文件是个符号链接
-S 文件是个socket
-t 关联到一个终端设备的文件描述符
这个选项一般都用来检测是否在一个给定脚本中的stdin[-t0]或[-t1]是一个终端
-r 文件具有读权限(对于用户运行这个test)
-w 文件具有写权限(对于用户运行这个test)
-x 文件具有执行权限(对于用户运行这个test)
-g set-group-id(sgid)标志到文件或目录上
如果一个目录具有sgid标志,那么一个被创建在这个目录里的文件,这个目录属于创建
这个目录的用户组,并不一定与创建这个文件的用户的组相同.对于workgroup的目录
共享来说,这非常有用.见<
复合测试运算
逻辑操作包括与、或,分别用“-a” 和 “-o”来表示。
流程控制语句
1、顺序执行语句:只要把语句按照逻辑顺序写好,Shell脚本解释器就会顺序地执行这些语句。
2、条件选择语句
if then 语句
if 条件表达式 then 语句1 fi
if 条件表达式; then 语句1 fi
if then else 语句
if 条件表达式; then 语句1
else
语句2
fi
if 语句的嵌套语法是:
if 条件表达式1; then
语句1
else
if 条件表达式2; then
语句2
else
语句3
fi
fi
if elif 语句
if [ $SYSTEM = "Linux" ] ; then
echo "Linux"
elif [ $SYSTEM = "FreeBSD" ] ; then
echo "FreeBSD"
elif [ $SYSTEM = "Solaris" ] ; then
echo "Solaris"
else
echo "What?"
fi
或 USER=`who |awk '{ print $1 }'`
if [ $USER = "root" ] ; then
echo "root"
elif [ $USER = "cacti" ] ; then
echo "cacti"
elif [ $USER = "nagios" ] ; then
echo "nagios"
elif [ $USER = "mysql" ] ; then
fi
case 语句 就是一个变量的值与期望的值进行匹配
case $1 in
匹配值1) 语句1 语句2 ………… ………… ;;
匹配值2) 语句3 语句 ………… ………… ;;
匹配值3) 语句5 语句6 ………… ………… ;; esac
Shell 脚本中的循环语句包括:for 循环、while循环、until循环
for i in k g h do
echo ok
done
while true do
echo ok
done
until aa > /dev/null do
echo ok
done
函数
hello () {
echo ok
}
function hello () {
echo hello
}
二、监控disk、cpu和处理qmail邮件队列
刚刚开始写一些简单脚本,还是觉得不能得心应手,不过总算写完成了。
面试的时候让写监控disk、cpu使用情况超过90% 后,报警给管理员,当时没有写的很准确,回来了就写了一下。如下:有问题请各位网友指出
2..1
实现硬盘监控。
root@watchout2 ~]# vi watch.sh
#!/bin/bash for i in `df -k |awk '{print $5}' |grep -v ^[a-z] |awk -F"%" '{print $1}'` do if [ $i -ge 90 ]; then /bin/mail -s "$HOSTNAME `date +%Y-%m-%d-%H-%M----%w`Filesystem over" [email]bo@future.com[/email] < /fileawk -- -f [email]source@watchout.com[/email] #/bin/mail -s "fileawk over" [email]bo@future.com[/email] < /fileawk -- -f [email]source@watchout.com[/email] #cat /fileawk | /bin/mail -s "$HOSTNAME$ Filesystem over" [email]bo@future.com[/email] -- -f [email]source@watchout.com[/email] else echo `date` Filesystem up to snuff >> /var/log/filesystem.log fi done
root@watchout2 ~]# cat /fileawk 192.168.1.238 文件系统使用超过了90% 。
注:
1、这个for的赋值采用的方法有所不同,但效果一样。
for disk in `df -h|awk '{print $5}'|sed 's/%//g'|grep -v "U"`
2、date +%Y-%m-%d-%H-%M----%w可阅读性不强,可换成
date +%Y%m%d-%R
2..2 实现对CPU的监控
#!/bin/bash logdir=/var/log logfile=$logdir/cpucheck.log if [ -f $logfile ] then echo "logfile is exist !" else touch $logfile fi
for cpucheck in `sar -u 2 2 |awk '{print $NF}'|sed '1,3d'|sed 's/\([0-9]*\)\..*/\1/g'` do if [ $cpucheck -le 10 ]; then /bin/mail -s "$HOSTNAME `date` cpu USE 90%" bo@future.com < /fileawk -- -f [email]source@watchout.com[/email] echo cpu Use 90% send post to admin. else echo "cpu up to snuff" >> $logfile echo cpu up to snuff! fi done
注:
对sar 理解不深,有错误之处请指出,谢谢!
2..3 服务器上有两块网块,一块配有电信网关eth0,另一块配有网通的网关eth1,正常的用eth1,网通出现问题时,自动切换到电信。
root:/root>cat gateWin.sh #!/bin/bash win=`ping -c 10 192.168.1.138 |grep From |wc -l` winstatu=`ping -c 10 192.168.1.138 |grep From |awk '{print $1}'|tail -n 1` if [ "$winstatu" = From -a "$win" -gt 7 ]; then echo "`date +%y-%m-%d-%R` network error " >> /var/log/gate.log #echo "NETWORKING=yes" > /etc/sysconfig/network #echo "HOSTNAME=dns.secure.net" >> /etc/sysconfig/network #echo "GATEWAY=11.23.55.77" >> /etc/sysconfig/network #/bin/mail -s else echo "`date +%y-%m-%d-%R` network good" >> /var/log/gate.log fi
2..4 qmail 配置过程参考用的是igenus
1、手工删除队列
使用qmailctl queue 查看邮件队列,如下信息
[root@test-linux queue]# qmailctl queue messages in queue: 174 messages in queue but not yet preprocessed: 0 4 Feb 2009 22:52:30 GMT #363764 1722 <> remote so@succine.com 5 Feb 2009 16:07:21 GMT #366929 3162 <> remote courtneyjane@nc.rr.com 5 Feb 2009 11:00:30 GMT #369885 2429 <> remote michaelerkens@ampen.de 5 Feb 2009 08:29:29 GMT #366931 18577 <> remote harrell7q@bergencountycontractors.com 4 Feb 2009 23:14:45 GMT #364400 1737 <> remote plvijayan@successreviews.net 4 Feb 2009 22:52:01 GMT #363767 1779 <> remote successwebsite.com87ways_order@successwebsite.com
#363764 #366929 ……以及都是邮件存在的唯一ID 可以在邮件队列目录下找到这个ID的文件
可以使用find /var/qmail/queue/ -name 363764 -exec rm {} \; 删除队列中某一封邮件
如何一次性删除所有邮件队列,我是采用了下面的方法写一个小脚本
#!/bin/bash qmailctl stop ID=`qmailctl queue |grep "#" |awk '{ print $6 }' |sed s/#//` for i in $ID do #qmailctl stop find /var/qmail/queue/ -name $i -exec rm {} \; #qmailctl start done qmailctl start
2、安装qmail-remove程序删除
下载安装qmail-remove源码包,安装源码包的三部曲。
有一个疑问是上面的红色字体是否代表投递邮件的大小?
2..5 当文件修改时自动邮件到指定的帐户
#!/bin/bash # . name change.sh # function if change zhou send mail !
while ls > /dev/null do YuanLaiTime=`stat zhou |grep Modify |awk '{print $3}' |awk -F "." '{print $1}' |sed s/://g`
sleep 30
ChangeTime=`stat zhou |grep Modify |awk '{print $3}' |awk -F "." '{print $1}' |sed s/://g` if [ $YuanLaiTime -ne $ChangeTime ]; then echo Error >> /tmp/fileEr.log /bin/mail -s "file change " bo@kuailel23.com < /tmp/fileEr.log -- -f ce@watchout.com
else
echo OK >> /tmp/fileOK.log fi done
2..6 ping
#!/bin/bash # function check DNS . name is ping.sh . tim=`date +%Y%m%d-%H` oldtim=`date -d '-60 day' +%Y%m%d-%H` touch /fgn/ping/ping.$tim.txt cd /fgn/ping if [ -f ping.$tim.txt ]; then for i in 1.2.2.6 2.3.1.0 do # touch /tmp/ping/ping.$tim.txt date +%Y%m%d-%H%M%S >> /fgn/ping/ping.$tim.txt ping $i -c 10 >> /fgn/ping/ping.$tim.txt done rm -f /fgn/ping/ping.$oldtim.txt fi
三、Shell 脚本是什么
Shell 脚本是什么? shell 脚本是一个包含命令序列的文本文件。当运行文件(或脚本)时,把执行该文件中包含的命令。术语 shell 仅指与 Linux 内核通信所使用的特定命令行用户界面。目前有多个不同的 shell ,其中包括 C shell (csh) 、 Korn shell (ksh) 、 Bourne shell (sh) 和 Bourne-Again shell (bash) 。 shell 本身就是一个从文件或终端读取命令、解释这些命令并通常执行其他命令的命令。 Bourne-Again shell 合并了上述其他 shell 的特性,本文就使用该脚本进行演示。 脚本文件中的第一行可用于指定使用哪个 shell 来运行该脚本。以下是所有脚本示例中包含的第一行的含义: #!/bin/bash 本文来自ChinaUnix博客,如果查看原文请点:
http://blog.chinaunix.net/u2/60453/showart_480841.html POSIX标准 什么是POSIX标准[可查阅开放系统标准](Open System Standards)。其作用就是为应用软件在不同的平台之间移植提供与unix 类似的标准。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。