本文用于记录学习和日常中使用shell写过的脚本
【脚本1】 打印等腰三角形、直角三角形、倒直角三角形、菱形
#!/bin/bash # 等腰三角形 read -p "Please input the length: " n for i in `seq 1 $n` do for ((j=$n;j>i;j--)) do echo -n " " done for m in `seq 1 $i` do echo -n "* " done echo done # 倒直角三角形 read -p "Please input the length: " len for i in `seq 1 $len` do for j in `seq $i $len` do echo -n "* " done echo done # 直角三角形 read -p "Please input the length: " len for i in `seq 1 $len` do for((j=1;j<=$i;j++)) do echo -n "* " done echo done # 菱形 read -p "Please input the length: " n for i in `seq 1 $n` do for ((j=$n;j>i;j--)) do echo -n " " done for m in `seq 1 $i` do echo -n "* " done echo done for i in `seq 1 $n` do for((j=1;j<=$i;j++)) do echo -n " " done for((k=$i;k<=$len-1;k++)) do echo -n "* " done echo done
<br />
【脚本2】 根据以下要求截取出字符串中的字符:字符串 var=http://www.aaa.com/root/123.htm
1.取出www.aaa.com/root/123.htm
2.取出123.htm
3.取出http://www.aaa.com/root
4.取出http:
5.取出http://
6.取出www.aaa.com/root/123.htm
7.取出123
8.取出123.htm
#!/bin/bash var="http://www.aaa.com/root/123.htm" #1. echo $var |awk -F '//' '{print $2}' #2. echo $var |awk -F '/' '{print $5}' #3. echo $var |grep -o 'http.*root' #4. echo $var |awk -F '/' '{print $1}' #5. echo $var |grep -o 'http://' #6. echo $var |grep -o 'www.*htm' #7. echo $var |grep -o '123' #8. echo $var |grep -o '123.htm'
<br />
【脚本3】 emm。。这个脚本是因为tomcat没有自带的能够给service开机启动的脚本,我就琢磨着自己写了一个简单的启动脚本,如下:
#!/bin/bash # chkconfig:2345 64 36 # description: Tomcat start/stop/restart script. ### BEGIN INIT INFO # Provides: tomcat # required-Start: # Should-Start: # required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: start and stop Tomcat # Description: Tomcat Service start&restart&stop script ### END INIT INFO ##Written by zero.## JAVA_HOME=/usr/local/jdk1.8/ JAVA_BIN=/usr/local/jdk1.8/bin JRE_HOME=/usr/local/jdk1.8/jre PATH=$PATH:/usr/local/jdk1.8/bin:/usr/local/jdk1.8/jre/bin CLASSPATH=/usr/local/jdk1.8/jre/lib:/usr/local/jdk1.8/lib:/usr/local/jdk1.8/jre/lib/charsets.jar TOMCAT_BIN=/usr/local/tomcat/bin RETVAL=0 prog="Tomcat" start() { echo "Starting $prog......" /bin/bash $TOMCAT_BIN/startup.sh RETVAL=$? return $RETVAL } stop() { echo "Stopping $prog......" /bin/bash $TOMCAT_BIN/shutdown.sh RETVAL=$? return $RETVAL } restart(){ echo "Restarting $prog......" stop start } case "$1" in start) start ;; stop) stop ;; restart) restart ;; *) echo $"Usage: $0 {start|stop|restart}" RETVAL=1 esac exit $RETVAL
<br />
【脚本4】 linux系统的rm命令太危险,一不小心就会删除掉系统文件。 写一个shell脚本来替换系统的rm命令,要求当删除一个文件或者目录时,都要做一个备份,然后再删除。下面分两种情况,做练习:
- 简单:
假设有一个大的分区/data/,每次删除文件或者目录之前,都要先在/data/下面创建一个隐藏目录,以日期/时间命名,比如/data/.201703271012/,然后把所有删除的文件同步到该目录下面,可以使用rsync -R 把文件路径一同同步,示例:
#!/bin/bash fileName=$1 now=`date +%Y%m%d%H%M` read -p "Are you sure delete the file or directory $1? yes|no: " input if [ $input == "yes" ] || [ $input == "y" ] then mkdir /data/.$now rsync -aR $1/ /data/.$now/$1/ /bin/rm -rf $1 elif [ $input == "no" ] || [ $input == "n" ] then exit 0 else echo "Only input yes or no" exit fi
<br /> 2.复杂:
不知道哪个分区有剩余空间,在删除之前先计算要删除的文件或者目录大小,然后对比系统的磁盘空间,如果够则按照上面的规则创建隐藏目录,并备份,如果没有足够空间,要提醒用户没有足够的空间备份并提示是否放弃备份,如果用户输入yes,则直接删除文件或者目录,如果输入no,则提示未删除,然后退出脚本,示例:
#!/bin/bash fileName=$1 now=`date +%Y%m%d%H%M` f_size=`du -sk $1 |awk '{print $1}'` disk_size=`LANG=en; df -k |grep -vi filesystem |awk '{print $4}' |sort -n |tail -n1` big_filesystem=`LANG=en; df -k |grep -vi filesystem |sort -n -k4 |tail -n1 |awk '{print $NF}'` if [ $f_size -lt $disk_size ] then read -p "Are you sure delete the file or directory: $1 ? yes|no: " input if [ $input == "yes" ] || [ $input == "y" ] then mkdir -p $big_filesystem/.$now && rsync -aR $1 $big_filesystem/.$now/ && /bin/rm -rf $1 elif [ $input == "no" ] || [ $input == "n" ] then exit 0 else echo "Only input 'yes' or 'no'." fi else echo "The disk size is not enough to backup the file: $1." read -p "Do you want to delete "$1"? yes|no: " input if [ $input == "yes" ] || [ $input == "y" ] then echo "It will delete "$1" after 5 seconds whitout backup." for i in `seq 1 5`; do echo -ne "."; sleep 1; done echo /bin/rm -rf $1 elif [ $input == "no" ] || [ $input == "n" ] then echo "It will not delete $1." exit 0 else echo "Only input 'yes' or 'no'." fi fi
<br />
【脚本5】 编写shell脚本,要求输入一个数字,然后计算出从1到输入数字的和,要求,如果输入的数字小于1,则重新输入,直到输入正确的数字为止,示例:
#!/bin/bash while : do read -p "Please enter a positive integer: " n if [ $n -lt 1 ] then echo "It can't be less than 1" else break fi done num=1 for i in `seq 2 $n` do num=$[$num+$i] done echo $num
<br />
【脚本6】 编写shell脚本,把/root/目录下的所有目录(只需要一级)拷贝到/tmp/目录下:
#!/bin/bash cd /root/ list=(`ls`) for i in ${list[@]} do if [ -d $i ] then cp -r $i /tmp/ fi done
<br />
【脚本7】 编写shell脚本,批量建立用户user_00,user_01,... user_100并且所有用户同属于users组:
#!/bin/bash group=`cat /etc/group |grep -o users` if [ $group == "users" ] then for i in `seq 0 100` do if [ $i -lt 10 ] then useradd -g users user_0$i else useradd -g users user_$i fi done else echo "users group not found!" exit 1 fi
#!/bin/bash for i in `seq 0 100` do if [ $i -lt 10 ] then userdel -r user_0$i else userdel -r user_$i fi done
<br />
【脚本8】 要求:请按照这样的日期格式(xxxx-xx-xx)每日生成一个文件,例如今天生成的文件为)2017-07-05.log, 并且把磁盘的使用情况写到到这个文件中,(不用考虑cron,仅仅写脚本即可)
#!/bin/bash fileName=`date +%F` c=`df -h` echo "$c" > /root/$fileName.log
<br />
【脚本9】 有一个日志文件,日志片段:如下:
> 112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com “/seccode.PHP?update=0.5593110133088248″ 200″http://formula-x.haotui.com/registerbbs.PHP” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)” 61.147.76.51 – [25/Sep/2013:16:08:31 +0800]xyzdiy.5d6d.com “/attachment.PHP?aid=4554&k=9ce51e2c376bc861603c7689d97c04a1&t=1334564048&fid=9&sid=zgohwYoLZq2qPW233ZIRsJiUeu22XqE8f49jY9mouRSoE71″ 301″http://xyzdiy.×××thread-1435-1-23.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)”
要求: 统计出每个IP的访问量有多少? > awk '{print $1}' 1.log |sort -n |uniq -c |sort -n
**解释:**sort -n会按照数值而不是ASCII码来排序awk截取出来的IP。然后uniq命令用于报告或忽略文件中的重复行,加上-c选项后会在每列旁边显示该行重复出现的次数,在这一步就完成了统计。不过最后还得再让sort -n排序一下uniq -c统计出来的结果。
<br />
【脚本10】 写一个脚本计算一下linux系统所有进程占用内存大小的和。 代码:
#!/bin/bash count=0 # 这个循环会遍历出每个进程占用的内存大小 for i in `ps aux |awk '{print $6}' |grep -v 'RSS'` do # 将遍历出来的数字进行累加 count=$[$count+$i] done # 就得到所有进程占用内存大小的和了 echo "$count/kb"
也可以使用awk 一条命令计算: > ps aux |grep -v 'RSS TTY' |awk '{sum=sum+$6};END{print sum}'
**解释:**grep -v是忽略 'RSS TTY' 所存在的那一行,后面的awk声明了一个变量sum,sum将前面命令列出来的数字进行累加,END之后就将累加后的sum打印出来,就得到所有进程占用内存大小的和了。
<br />
【脚本11】 设计一个简单的脚本,监控远程的一台机器(假设ip为123.23.11.21)的存活状态,当发现宕机时发一封邮件给你自己。
#!/bin/bash ip="123.23.11.21" email="user@example" while 1 do ping -c10 $ip > /dev/null 2>/dev/null if [ $? != "0" ] then # 调用一个用于发邮件的脚本 python /usr/local/sbin/mail.py $email "$ip down" "$ip is down" fi sleep 30 done
mail.py 脚本代码:
#!/usr/bin/env python #-*- coding: UTF-8 -*- import os,sys reload(sys) sys.setdefaultencoding('utf8') import getopt import smtplib from email.MIMEText import MIMEText from email.MIMEMultipart import MIMEMultipart from subprocess import * def sendqqmail(username,password,mailfrom,mailto,subject,content): # 邮箱的服务地址 gserver = 'smtp.qq.com' gport = 25 try: msg = MIMEText(unicode(content).encode('utf-8')) msg['from'] = mailfrom msg['to'] = mailto msg['Reply-To'] = mailfrom msg['Subject'] = subject smtp = smtplib.SMTP(gserver,gport) smtp.set_debuglevel(0) smtp.ehlo() smtp.login(username,password) smtp.sendmail(mailfrom,msg.as_string()) smtp.close() except Exception,err: print "Send mail Failed. Error: %s" % err def main(): to=sys.argv[1] subject=sys.argv[2] content=sys.argv[3] #定义QQ邮箱的账号和密码,你需要修改成你自己的账号和密码 sendqqmail('1234567@qq.com','aaaaaaaaaa','1234567@qq.com',to,content) if __name__ == "__main__": main() #####脚本使用说明###### #1. 首先定义好脚本中的邮箱账号和密码 #2. 脚本执行命令为:python mail.py 目标邮箱 "邮件主题" "邮件内容"
<br />
【脚本12】 需求: - 找到/123目录下所有后缀名为.txt的文件 - 批量修改.txt为.txt.bak - 把所有.bak文件打包压缩为123.tar.gz - 批量还原文件的名字,即把增加的.bak再删除
代码:
#!/bin/bash now=`date +%F_%T` mkdir /tmp/123_$now for txt in `ls /123/*.txt` do mv $txt $txt.bak for f in $txt do cp $txt.bak /tmp/123_$now done done cd /tmp/ tar czf 123.tar.gz 123_$now/ for txt in `ls /123/*.txt.bak` do name=`echo $txt |awk -F '.' '{OFS="."} {print $1,$2}'` mv $txt $name done
<br />
【脚本13】 需求: 写一个脚本,判断本机的80端口(假如服务为httpd)是否开启着,如果开启着什么都不做,如果发现端口不存在,那么重启一下httpd服务,并发邮件通知你自己。脚本写好后,可以每一分钟执行一次,也可以写一个死循环的脚本,30s检测一次。 发邮件的脚本参考【脚本11】的示例代码。 代码:
#!/bin/bash email="user@example.com" if netstat -lntp |grep ':80' |grep 'httpd' then echo "80 port no problem" exit else /usr/local/apache2.4/bin/apachectl restart python mail.py $email "check_80port" "The 80 port is down." n=`ps aux |grep httpd|grep -cv grep` if [ $n -eq 0 ] then /usr/local/apache2/bin/apachectl start 2>/tmp/apache_start.err fi if [ -s /tmp/apache_start.err ] then python mail.py $mail 'apache_start_error' `cat /tmp/apache_start.err` fi fi原文链接:https://www.f2er.com/bash/389470.html