首页 > 代码库 > 常见的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实例