100个shell脚本【持续更新】

前端之家收集整理的这篇文章主要介绍了100个shell脚本【持续更新】前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本文用于记录学习和日常中使用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&amp;restart&amp;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命令,要求当删除一个文件或者目录时,都要做一个备份,然后再删除。下面分两种情况,做练习:

  1. 简单:

假设有一个大的分区/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 &amp;&amp; rsync -aR $1 $big_filesystem/.$now/ &amp;&amp; /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" &gt; /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 &gt; /dev/null 2&gt;/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&gt;/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

猜你在找的Bash相关文章