首页 > 代码库 > 常见的shell实例
常见的shell实例
1.从磁盘使用统计中排除部分文件
du --exclude “*.iso” dir
2.找出指定目录中最大的10个文件
find -type f -exec du -k {} \; |sort -nrk 1 |head -n 10
3. 列出当前系统最长用的10条命令
cat .bash_history | awk ‘{print $1}‘ | sort | uniq -c | sort -nr | head -10
4. 统计所有进程所占的常驻内存
ps -eo rss | awk ‘BEGIN {print “所占内存是: ”} /^ *[0-9]/ { total += $1 } END { print total “kib”}‘
实例:
实例1:采集系统负载数据,并通过gnuplot绘图分析系统热点。
/opt/cpuload.sh
#!/bin/bash
# Create by wxh 2015-07-05
# Version: v0.1
# 按照一定的格式采集cpu负载数据并存储在/tmp/mydata文件中。
uptime | awk ‘{print $1, $(NF-2), $(NF-1), $NF}‘ | sed ‘s/,//g‘ >> /tmp/mydata
# 调用gnuplot软件根据采集的数据进行绘图。
gnuplot <<EOF
set terminal png tiny font ‘/usr/share/fonts/liberation/LiberationSans-Regular.ttf‘
set output ‘/var/www/html/loadavg.png‘
set xdata time
set timefmt ‘%H:%M:%S‘
set xlabel ‘TIME‘
set format x ‘%H:%M‘
set xtics rotate
set ylabel ‘load average‘
plot ‘/tmp/mydata‘ u 1:2 t ‘1-min‘ with lines, ‘/tmp/mydata‘ u 1:3 t ‘5-min‘ with
lines,‘/tmp/mydata‘ u 1:4 t ‘15-min‘ with lines
EOF
# 定义周期任务,每分钟执行一次脚本。
crontab -e
* * * * * /opt/cpuload.sh
# 通过http服务发布gnuplot绘制的图形,方便用户查看。
cat /var/www/html/gnuplot.html
<html>
<h1>Performance Charts</h1>
<a href="http://www.mamicode.com/loadavg.png">Load Average</a>
</html>
实例2:编写交互式脚本
/opt/check_system.sh
#!/bin/bash
# Create by wxh 2015-07-05
# Version: v0.1
# while循环显示交互界面
while true
do
# 显示交互内容
echo -e "
\033[31m A \033[0m 显示主机ip地址
\033[32m B \033[0m 显示磁盘空闲
\033[33m C \033[0m 显示系统运行时间
\033[34m Q \033[0m 退出
"
# 从终端读取用户输入 read -p "请输入你的选择: " num
# 设置多重任务分支 case $num in
a|A)
ifconfig br0 | grep "inet addr:" | awk ‘{print $2":"$4}‘ | awk -F: ‘{print $2"/"$4}‘ ;;
b|B)
df -h | grep /$ | awk ‘{print $3}‘ ;;
c|C)
uptime | awk ‘{print $3}‘ | tr -d ‘,‘ | awk -F: ‘{print "系统已经运行了"$1"小 时"$2"分钟"}‘
;;
q|Q) exit ;;
*)
echo "请不要任性,需要选择[A|B|C]"
esac
done
实例3:编写nginx服务脚本
/etc/ini.t/nginx
#!/bin/bash
# Create by wxh 2015-07-05
# Version: v0.1
. /etc/rc.d/init.d/functions
nginx=/usr/local/nginx/sbin/nginx
prog=nginx
pidfile=/usr/local/nginx/logs/nginx.pid
RETVAL=0
start() {
echo -n $"Starting $prog: "
$nginx -t &> /dev/null
if [ $? -eq 0 ];then
$nginx &> /dev/null && success || failure
fi
echo
RETVAL=$?
return $RETVAL
}
stop() {
echo -n $"Stopping $prog: "
$nginx -s stop &> /dev/null && success || failure
echo
RETVAL=$?
}
reload() {
echo -n $"Reloading $prog: "
$nginx -s reload &> /dev/null && success || failure
echo
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
reload)
reload
;;
status)
status -p ${pidfile} $nginx
RETVAL=$?
;;
help)
$nginx -h
RETVAL=$?
;;
*)
echo $"Usage: $prog {start|stop|restart|reload|help|status}"
RETVAL=1
esac
exit $RETVAL
实例4:生产环境批量检测web url,邮件、微信报警。
/opt/check_weburl.sh
#!/bin/bash
# Create by wxh 2015-07-08
# Version: v0.1
#应用系统提供的脚本,本脚本中会使用里面的方法,比如action。
. /etc/init.d/functions
RETVAL=0 #定义默认返回值为0
ADDRESS=1206160700 #定义微信好友ID
CONTENT="/tmp/checkurl.txt"
function getstatus(){ #定义函数
FAILCOUNT=0 #定义FAILCOUNT变量的默认值
#使用wget循环检测3次指定url的状态,如果检测失败FAILCONUT的值+1
for ((i=1;i<=3;i++))
do
wget -T5 -t1 --spider http://$1 &>/dev/null
[ $? -ne 0 ] && let FAILCOUNT+=1
done #判断FAILCOUNT的值如果大于1的话就报警。
if [ $FAILCOUNT -gt 1 ];then
RETVAL=1 #检测失败后返回值为1
NTIME=`date +"%Y-%m-%d %H:%M:%S"` #定义时间格式
echo "http://$1 is down, ${NTIME}." > $CONTENT #定义报警内容
php /usr/local/WeiXin-Private-API/test.php $ADDRESS &> /dev/null
#调用微信接口报警
else
RETVAL=0 #检测成功返回值依然为0
fi
return $RETVAL #返回值
}
#判断urllist.txt文件是否存在
if [ ! -f /opt/urllist.txt ];then
echo urllist.txt not found
exit 1
fi
#调用上面定义的函数getstatus()循环检测url列表
for URL in `cat /opt/urllist.txt`
do
echo -n "checking $URL: "
getstatus $URL && action 健康的 /bin/true || action 挂掉了 /bin/false
done
脚本内容到此结束,以下是脚本中调用的urllist.txt文件的内容,一行一个:
# cat /opt/urllist.txt
www.westos.org
192.168.0.145
实例5: 屏蔽密码尝试失败次数过多的ip
/opt/check_secure.sh
#!/bin/bash
# Create by wxh 2015-07-08
# Version: v0.1
#过滤认证失败的主机IP和失败次数,并存储数据到文件
cat /var/log/secure|awk ‘/Failed/{print $(NF-3)}‘|sort|uniq -c|awk ‘{print $2"="$1;}‘ > /tmp/black.txt
#设定变量,超出此值会被脚本屏蔽
BASELINE="20"
#循环检测过滤到的数据文件
for i in `cat /tmp/black.txt`
do
IP=`echo $i |awk -F= ‘{print $1}‘` #取出主机ip
NUM=`echo $i|awk -F= ‘{print $2}‘` #取出失败次数
if [ $NUM -gt $BASELINE ];then
#在屏蔽IP之前先确认是否此IP是否已经存在
grep $IP /etc/hosts.deny > /dev/null
if [ $? -gt 0 ];then
echo "sshd:$IP" >> /etc/hosts.deny
fi
fi
done
可以把脚本放入周期任务,定时自动检测。
Expect用法:
#!/usr/bin/expect
告诉操作系统脚本里的代码使用那一个shell来执行。
set timeout 30
设置超时时间的,单位是:秒 ,timeout -1 为永不超时。
spawn ssh -l user 192.168.0.1
spawn是进入expect环境后才可以执行的 expect内部命令,它主要的功能是给 ssh运行进程加个壳,用来传递交互指令。
expect "password:"
判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则 就等待一段时间后返回,这里等待时长就是前面设置的30秒。
send "ispass\r"
这里执行交互动作,与手工输入密码的动作等效。命令字符串结尾别忘记加上 “\r”。
interact
执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。
$argv 参数数组
expect脚本可以接受从bash传递过来的参数.可以使用[lindex $argv n]获得,n从 0开始,分别表示第一个,第二个,第三个....参数
实例6:expect自动交互脚本
/opt/auto1.sh
#!/usr/bin/expect
spawn ssh 192.168.0.120
expect "(yes/no)?" {
send "yes\r"
expect "password:"
send "westos\r"
} "password:" {send "westos\r"} "*host " {exit 1}
expect "#"
send "df -h\n"
send "exit\n"
expect eof
实例7:文件自动上传脚本
/opt/upload.sh
#!/usr/bin/expect
set DIR [lindex $argv 0]
spawn lftp 192.168.2.251
expect "~>"
send "cd pub\r"
expect "pub>"
send "mput $DIR/*\r"
send "exit\r"
expect eof
实例8:批量主机操作(相同密码)
/opt/auto2.sh
#!/usr/bin/expect
foreach ip {
172.25.0.1
172.25.0.2
} {
spawn ssh -l root $ip
expect "*password: "
sleep 1
send "westos\r"
expect "root"
send "scp root@172.25.0.251:/shell/check.sh /mnt\r"
###注意第一次连接会提示yes/no
expect "pasword:"
send "123456\r"
expect eof
}
实例9:批量主机操作(不同密码)
# cat passwd.txt
192.168.2.60=westos
192.168.2.70=redhat
# cat hello.sh
#!/bin/bash
#for i in `cat passwd.txt`
#do
# ip=`echo $i | awk -F= ‘{print $1}‘`
# pass=`echo $i | awk -F= ‘{print $2}‘`
#done
for ip in `awk -F= ‘{print $1}‘ passwd.txt`
do
pass=`awk -F= -v i="$ip" ‘{if(i==$1)print $2}‘ passwd.txt`
expect login.exp $ip $pass
done
# cat login.exp
#!/usr/bin/expect
set IP [lindex $argv 0]
set PASS [lindex $argv 1]
spawn ssh wxh@$IP
expect "(yes/no)?" {
send "yes\r"
expect "password:"
send "$PASS\r"
} "password:" { send "$PASS\r" } "* host" {exit 1}
expect "$ "
send "hostname;exit\r"
expect eof
常见的shell实例