shell脚本实例

码农天地 -
shell脚本实例
1.hello world脚本
#!/bin/bash
echo "hello world"
2.创建用户:2.1 通过位置变量创建用户
#!/bin/bash
#$1是执行脚本的第一个参数(用户名),$2是执行脚本的第二个参数(密码)
useradd "$1"
echo "$2" | passwd --stdin "$1"
2.2 提示用户输入用户名和密码创建用户
#!/bin/bash
read -p "请输入用户名:" user           #提示输入用户名
if [ -z $user ];then                    #判断变量(用户名)是否为空
echo "您必须输入帐户名"             #变量(用户名)为空则提示必须输入用户名
exit 2                             #设置退出码为2(退出后使用'echo $?'查看返回码为2)
fi
stty -echo                                  #关闭shell回显功能
    read -p "请输入密码" pass               #提示用户输入密码
stty echo                                   #打开shell回显功能
pass=${pass:-123456}                        #设置默认密码(用户未输入密码时默认使用123456)
useradd "$user"                             #创建用户
echo "$pass" | passwd --stdin "$user"       #设置用户的密码
2.3 读取user.txt文件中的用户名批量创建用户
#!/bin/bash
#提前将需要创建的用户名写入user.txt文件(每行1个或使用空格分隔)
for name in `cat user.txt`
do
    useradd $name
    echo "123456" | passwd --stdin $name
done
2.4 读取list.txt文件中的账号密码批量创建用户
#!/bin/bash
#提前准备账号密码文件list.txt
#文件内每行一个账号密码组,使用逗号分隔(username,password)
for line in `cat list.txt`
do
  echo $line | awk -F, '{cmd="useradd "$1"; echo "$2" | passwd --stdin "$1; system(cmd)}'   #awk中调用系统命令
done
3.显示当前计算机中所有账户的用户名
#!/bin/bash
echo "方法①,指定以:为分隔符,打印/etc/passwd文件的第1列"
awk -F: '{print $1}' /etc/passwd
echo "方法②,指定以:为分隔符,打印/etc/passwd文件的第1列"
cut -d: -f1 /etc/passwd
echo "方法③使用sed的替换功能,将/etc/passwd文件中第1个:后面的所有内容替换为空(仅显示用户名)"
sed "s/:.*//" /etc/passwd
4.统计当前Linux系统中可以登陆计算机的账户数量
#!/bin/bash
#方法1grep:
grep "bash$" /etc/passwd | wc -l         #一般默认解释器是bash
#方法2awk:
awk -F: '/bash$/{x++} END{print x}' /etc/passwd
#方法3,更为准确
for shell in `awk -F: '{print $7}' /etc/passwd`         #取出账号文件中各账号的解释器
do
    if [[ "`cat /etc/shells`" =~ "$shell" ]]; then      #检测取出的解释器是否包含在可登录解释器中
        let n++
    fi
done
echo $n
5.找出/etc/passwd中能登录的用户,并将对应在/etc/shadow中第二列密码提出处理
#!/bin/bash
shells=`awk -F: '$7!~"nologin"{print $1","$7}' /etc/passwd`
for shell in $shells
do
    if [[ "`grep -v '^#' /etc/shells`" =~ "`echo $shell | cut -d, -f2`" ]]; then
        users="$users `echo $shell | cut -d, -f1`"
    fi
done
for user in $users
do
    awk -F: -v u=$user '$1~u{print $1,$2}' /etc/shadow
done
6.检查当前用户是否为超级管理员
#!/bin/bash
if [ "$USER" == "root" -o $UID -eq 0 ]; then        #利用用户名或uid检测
    echo "当前用户是超级管理员"
else
    echo "当前用户不是超级管理员"
fi
7.测试用户名与密码是否正确
#!/bin/bash
for i in {1..3}                       #最多测试3次
do
    read -p "请输入用户名:" user
    read -p "请输入密码:" pass
    if [ "$user" == 'tom' -a "$pass" == '123456' ];then    #模拟正确账号tom密码123456
        echo "Login Successful"
        exit
    fi
done
echo "Login Failed"
8.将Linux系统中UID大于1000的普通用户都删除
#!/bin/bash
user=`awk -F: '$3>=1000 {print $1}' /etc/passwd`
for i in $user
do
  userdel -r $i
done
9.点名器
#!/bin/bash
#需要提前准备一个user.txt文件
#文件中要包含所有的姓名,一行一个姓名,脚本每次随机显示一个姓名
while :
do
    line=`cat user.txt | wc -l`    #统计user文件中有多少用户(行)
    num=$[RANDOM%$line+1]          #获取随机值
    sed -n "${num}p" user.txt      #显示随机出的姓名
    sleep 0.2
    clear
done
10.将用户输入的字符串写入数组
#!/bin/bash
i=0                        #用于标识数组下标
name=()                    #声明数字,用于存储字符串
while :
do
    read -p "请输入账户名,输入over结束:" str
    if [ "$str" == "over" ];then
        break              #输入over就结束循环
    else
        name[$i]=$str      #将字符串写入数组
        let i++            #增加下标取值
    fi
done
echo "总账户名数量为:${#name[*]}"
echo "${name[@]}"
11.使用计划任务在指定时间tar打包备份日志
#!/bin/bash
#tar -zcf log-`date +%Y%m%d`.tar.gz /var/log                     #包名中加入当时日期,避免被后边的文件覆盖
echo "00 03 * * 5 `readlink -f $0`" >> /var/spool/cron/$USER; sed -i "2s/^#//" $0; sed -i "3s/^/#/" $0  #写入用户计划任务后,取消上一行注释同时注释此行

命令行
crontab -e

12.自动修改计划任务配置文件
#!/bin/bash
read -p "请输入分钟信息(00-59):" min
read -p "请输入小时信息(00-24):" hour
read -p "请输入日期信息(01-31):" date
read -p "请输入月份信息(01-12):" month
read -p "请输入周几信息(00-06):" weak
read -p "请输入计划任务需要执行的命令或脚本:" program
echo "$min $hour $date $month $weak $USER $program" >> /etc/crontab
13.显示CPU厂商信息
#!/bin/bash
awk '/vendor_id/{print $3}' /proc/cpuinfo | uniq
14.实时监视本机内存、/分区剩余空间,当剩余空间达到阈值发送报警邮件给root管理员
#!/bin/bash
disk_value=1000                                 #设置/分区监测空间
mem_value=500                                   #设置内存监测空间
disk_size=`df -m / | awk '/\//{print $4}'`      #获取/的剩余硬盘空间,单位M
mem_size=`free -m | awk '/Mem/{print $4}'`      #获取剩余内存空间,单位M
while :
do
    if [ $disk_size -le $disk_value -o $mem_size -le $mem_value ]; then     #判断条件
        echo "Insufficient resources,资源不足" | mail -s "Warning" root     #达到阈值发送邮件给root
    fi
done
15.批量下载有序文件(pdf、图片、视频等)
#!/bin/bash
#本脚本进行有序的网络资料批量下载操作(如01.jpg,02.jpg,03.jpg)
url="http://www.test.com"
type=jpg
Dpath=/mnt                                                                                         

echo "开始下载..."
for num in `seq 10`
do
    echo -n "正在下载$num.$type"
    curl -s ${url}/${num}.${type} -o $Dpath/${num}.$type     #-o选项,curl指定下载文件另存为
    if [ $? -eq 0 ]; then
        echo -e  "          [\e[32mOK\e[0m]"
    else
        echo -e "           [\e[31mERROR\e[0m]"
    fi
    sleep 1
done
16.自动优化Linux内核参数
#!/bin/bash
#此脚本针对RHEL7系列
cat >> /usr/lib/sysctl.d/00-system.conf << EOF
fs.file-max=65535
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024 65535
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernek.shmmin = 4096
kernel.sem = 5010 641280 5010 128
net.core.wmem_default=262144 
net.core.wmem_max=262144 
net.core.rmem_default=4194304 
net.core.rmem_max=4194304 
net.ipv4.tcp_fin_timeout = 10 
net.ipv4.tcp_keepalive_time = 30 
net.ipv4.tcp_window_scaling = 0 
net.ipv4.tcp_sack = 0 
EOF 
 
sysctl –p       #重读内核配置
17.修改Linux系统的最大打开文件数量
#!/bin/bash
#在/etc/security/limits.conf 文件的末尾追加两行配置参数,
#修改最大打开文件数量为65535
cat >> /etc/security/limits.conf <<EOF
* soft nofile 65535
* hard nofile 65535
EOF
18.统计/var/log有多少个文件,并显示这些文件名
#!/bin/bash
#方法1
sum=0                           #用于统计数量
for i in `ls /var/log/`
do
    if [ -f $i ];then
        let sum++
        echo "文件名:$i"
    fi
done
echo "文件总量为:$sum"

#方法2
echo "文件总量为:"`find /var/log -maxdepth 1 -type f | wc -l`
19.统计进程19.1 统计Linux进程相关数量信息
#!/bin/bash
running=0           #正在运行的进程
stoped=0            #已经停止的进程
sleeping=0          #睡眠中的进程
zombie=0            #僵尸进程
for pid in /proc/[1-9]*                     #在/proc目录下所有以数字开始的都是运行的进程pid及其信息
do
    procs=$[procs+1]                        #统计进程总数
    stat=`awk '{print $3}' $pid/stat`       #每个pid编号下的stat文件中,第3列是该进程的状态信息
    case $stat in
        R)
            let running++
            ;;
        T)
            let stoped++
            ;;
        S)
            let sleeping++
            ;;
        Z)
            let zombie++
            ;;
        *)
            ;;
    esac
done
echo "进程统计信息如下:"
echo "总进程数:         $procs"
echo "  Running 进程数: $running"
echo "  Stoped  进程数: $stoped"
echo "  Sleeping进程数: $sleeping"
echo "  Zombie  进程数: $zombie" 
19.2 查找Linux系统中的僵尸进程
#!/bin/bash
#awk判断ps命令输出的第8列为z时,显示该进程的PID和进程命令
ps aux | awk '{if($8 == "Z" ){print $2,$11}}'
20.关闭SELinux
#!/bin/bash
sed -i '/^SELINUX/s/=.*/=disabled' /etc/selinux/config
setenforce 0
21.检测所在网段中主机的开/关机状态21.1 for循环检测所处网段主机的开关机状态
#!/bin/bash
for i in {1..254}
do
    ping -c2 -i0.1 -W1 192.168.4.$i &>/dev/null
    if [ $? -eq 0 ] ;then
        echo -e "\e[32;1m192.168.4.$i is up[0m"
    else
        echo "192.168.4.$i is down"
    fi
done
21.2 while循环检测所处网段主机的开关机状态
#!/bin/bash
i=1
while [ $i -le 254 ]
do
    ping -c2 -i0.2 -W1 192.168.4.$i &>/dev/null
    if [ $? -eq 0 ] ;then
        echo -e "\e[32;1m192.168.4.$i is up[0m"
    else
        echo "192.168.4.$i is down"
    fi
    let i++
done
21.3 多线程检测所在网段主机的开关机状态
#!/bin/bash
#定义一个函数,ping某一台主机,并检测主机的存活状态
myping() {
    ping -c2 -i0.3 -W1 $1 &>/dev/null
    if [ $? -eq 0 ];then
        echo "$1 is up"
    else
        echo "$1 is down"
    fi
}
for i in {1..254}
do
    myping 192.168.4.$i &       #用&将命令放入后台执行,无需等待完成即可再次执行下一命令
done
22.循环关闭局域网中所有主机
#!/bin/bash
#假设本机为192.168.4.100,编写脚本关闭除自己外的其他所有主机
#脚本执行,需要提前给所有其他主机传递ssh密钥,满足无密码连接
for i in {1..254}
do
    [ $i -eq 100 ] && continue
    echo "正在关闭192.168.4.$i..."
    ssh 192.168.4.$i poweroff
done
23.使用死循环实时显示网卡收发数据包的流量
#!/bin/bash
eth=enp0s3
while :
do
    echo "本地网卡$eth流量信息如下:"                                                                
    ifconfig $eth | grep "RX pack" | awk '{print $5}'
    ifconfig $eth | grep "TX pack" | awk '{print $5}'
    sleep 1
done
24.获取MAC地址24.1 ip命令获取本机网卡MAC地址
#!/bin/bash
yum -y install iproute              #ip命令的软件
ip a s | awk 'BEGIN{print "MAC地址:"}/^[0-9]/{print $2;getline;if($0~/link\/ether/){print "\t"$2}}' | grep -v "lo:"
#awk 读取 ip 命令的输出,
#输出结果中如果有以数字开始的行,先显示该行的第2列(网卡名称), 
#接着使用 getline 再读取它的下一行数据,判断是否包含 link/ether 
#如果包括该关键词,就显示该行的第 2 列(MAC 地址) 
#lo 回环设备没有 MAC,因此将其屏蔽,不显示
24.2 ifconfig命令获取本机MAC地址
ifconfig | grep -v "lo" | awk 'BEGIN{print "MAC地址:"} /flags/{print $1} /ether/{print "\t"$2}'
24.3 cat命令在文件中获取本机MAC地址
#!/bin/bash
#在/sys/class/net/网卡名/address 文件中有该网卡的MAC地址
eths=`ls /sys/class/net/ | grep -v "lo"`        #在目录中获取网卡名,除去lo回环
echo "MAC"
for eth in $eths
do
    echo "$eth : "                                                                                 
    echo -e "\t `cat /sys/class/net/$eth/address`"      #获取网卡的MAC地址
done
24.4 arp命令查看连接本机的远程ip与mac
#!/bin/bash
#①arp命令获取
arp -n                      #在缓存中以数字显示获取连接本机的ip和mac

#②在文件中获取,arp信息存储在/proc/net/arp
cat /proc/net/arp
24.5 过滤MAC地址
#!/bin/bash
# MAC地址由6段16进制组成,如AA:BB:CC:DD:EE:FF
# [0-9a-fA-F]{2}表示一段十六进制数值,{5}表示连续出现5组:的十六进制
egrep "[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}" /proc/net/arp
25.统计所有连接本机的远程ip(包含ssh、web、ftp等所有连接)
#!/bin/bash
#使用netstat -atn 可以查看本机所有连接的状态,-a查看所有,-t仅显示tcp连接的信息,-n数字格式显示
#Local Address(第四列是本机的IP和端口信息)
#Foreign Address(第五列是远程主机的IP和端口信息)
#使用awk命令仅显示第5列数据,再显示第1列IP地址的信息
#sort可以按数字大小排序,最后使用uniq将多余重复的删除,并统计重复的次数
netstat -tna | awk '$5~"[0-9]"{print $5}' | awk -F: '{print $1}' | sort | uniq -c
26.expect自动交互远程其他主机安装软件
#!/bin/bash
ip=192.168.5.20
pass=123456
yum -y install expect                           #需要的软件
expect <<EOF
spawn ssh -o StrictHostKeyChecking=no $ip       #-o 的内容是第一次ssh其他主机时不进行安全检测
expect "password" {send "$pass\r"}              #遇到关键字"password",输入"$pass"
expect "#" {send "yum -y install httpd\r"}     #安装软件
expect "#" {send "exit\r"}                      #退出
EOF                                             #对应上边的EOF结束符
27.非交互自动生成SSH密钥文件
#!/bin/bash
# -t指定ssh密钥的算法为RSA算法;-N设置密钥的密码为空;-f指定生成的密钥存放路径
#rm -rf ~/.ssh/{known_hosts,id_rsa*}        #可用yes替代,解决密钥已存在时的询问
yes | ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa -C "description"
28.自动添加防火墙规则(开启服务或端口
#!/bin/bash
#适用于RHEL7系列

#firewall-cmd --get-services        #可以查看firewall支持哪些服务
#cat /etc/services                  #可以查看服务、端口的对应表

services="ssh http nfs"      #设置服务
ports="22 80 2049"         #设置端口号 ssh、http 、 nfs

#循环将每个服务添加到防火墙规则中
for service in $services
do
    echo "添加 $service 服务到 防火墙"
    firewall-cmd --add-service=${service}
done

#循环将每个端口添加到防火墙规则中
for port in $ports
do
    echo "添加 $port 端口到 防火墙"
    firewall-cmd --add-port=${port}/tcp
done

#将以上设置的临时防火墙规则,转换为永久有效的规则(确保重启后有效)
firewall-cmd --runtime-to-permanent
29.显示本机Linux系统上所有开放的端口列表
#!/bin/bash
#从端口列表中观测有没有没用的端口,有的话可将其对应的服务关闭,防止意外的攻击可能性
ss -utnlp | awk '{print $1,$5}' | grep "[0-9]" | awk -F"[: ]" 'BEGIN{print "protocol","port"}{print $1,$NF}' | sort | uniq | column -t
#ss(软件包:iproute),与netstat功能基本一致
#sort排序,方便uniq去重,column -t 创建表格
30.自动配置rsyncd服务器的配置文件rsyncd.conf
#!/bin/bash
#man rsyncd.conf                            #可查看更多选项
[ ! -d /home/ftp ] && mkdir /home/ftp
echo 'uid = nobody                                                                                 
gid = nobody
use chroot = yes
max connections = 4
pid file = /var/run/rsyncd.pid
exclude = lost+found/
transfer logging = yes
timeout = 900
ignore nonreadable = yes
dont compress = *.gz  *.tgz  *.zip  *.z  *.Z  *.rpm  *.deb  *.bz2
[ftp]
    path = /home/ftp
    comment = share' > /etc/rsyncd.conf
31.一键配置VNC远程桌面服务器(无密码仅查看版本)
#!/bin/bash
#
#脚本配置的VNC服务器,客户端无需密码即可连接
#客户端仅有查看远程桌面的权限,没有鼠标、键盘的操作权限
rpm --quiet -q tigervnc-server            #--quiet安静,-q查询,vnc的安装情况
if [ $? -ne 0 ];then
  yum -y install tigervnc-server
fi
x0vncserver AcceptKeyEvents=0 AlwaysShared=1 AcceptPointerEvents=0 SecurityTypes=None rfbport=5908
32.fdisk命令自动对磁盘分区、格式化、挂载
#!/bin/bash
#对虚拟机的vdb磁盘进行分区格式化,使用<<将需要的分区指令导入给程序fdisk
#n(新建分区),p(创建主分区),1(分区编号为1),
#两个空白行(两个回车,相当于将整个磁盘分一个区)。
#注意:1后面的两个回车(空白行)是必须的!
fdisk /dev/vdb << EOF
n
p
1


wq
EOF

#格式化刚刚创建好的分区
mkfs.xfs /dev/vdb1

#创建挂载点目录
if [ -e /data ] ;then
    exit                                                                                           
fi
mkdir /data

#自动挂载刚刚创建的分区,并设置开机自动挂载该分区
echo "/dev/vdb1  /data  xfs  defaults  1 2" >> /etc/fstab
mount -a
33.自动创建逻辑卷
#!/bin/bash
#清屏,显示警告信息,创建将磁盘转换为逻辑卷会删除数据
clear
echo -e "\033[33m           !!!!!!警告(Warning)!!!!!!\033[0m"
echo
echo "+++++++++++++++++++++++++++++++++++++++++++++++++" 
echo "脚本会将整个磁盘转换为 PV,并删除磁盘上所有数据!!!" 
echo "This Script will destroy all data on the Disk" 
echo "+++++++++++++++++++++++++++++++++++++++++++++++++" 
lsblk       #显示当前的块设备
echo
read -p "请问是否继续 y/n?:" sure

[ $sure != y ] && exit          #测试用户输入的是否为y,若不是则退出脚本

#提示用户输入相关参数(磁盘、卷组名等数据),并测试用户是否输入了这些值,
#若没输入,则脚本退出
read -p "请输入磁盘名称,如/dev/vdb:" disk
[ -z $disk ] && echo "没有输入磁盘名称" && exit     #-z后边的字符串长度为0则为真
read -p "请输入卷组名称:" vg_name
[ -z $vg_name ] && echo "没有输入卷组名称" && exit
read -p "请输入逻辑卷名称:" lv_name
[ -z $lv_name ] && echo "没有输入逻辑卷名称" && exit
read -p "请输入逻辑卷大小:" lv_size
[ -z $lv_size ] && echo "没有输入逻辑卷大小" && exit

#使用命令创建逻辑卷
pvcreate $disk
vgcreate $vg_name $disk
lvcreate  -L ${lv_size}M  -n ${lv_name}  ${vg_name}

#                                                                                                  
lsblk $disk
34.设置Python支持自动命令补齐功能
#!/bin/bash
if [ ! -f /usr/bin/tab.py ];then            #创建一个自动补全的.py文件
    cat >> /usr/bin/tab.py <<EOF
import readline                             #自动补全模块
import rlcompleter
readline.parse_and_bind('tab:complete')
EOF
#注意:结束符EOF要顶格写                                                                           
fi
sed -i '$a export PYTHONSTATUP=/usr/bin/tab.py' /etc/profile        #向文件末尾追加一行字符串
source /etc/profile                                                 #刷新
35.判断用户输入数据的类型(字母、数字、其他)
#!/bin/bash
read -p "请输入一个字符:" key
case "$key" in
    [a-Z])
        echo "字母"
        ;;
    [0-9])
        echo "数字"
        ;;
    *)
        echo "空格、功能键或其他控制字符"
        ;;                                                                                         
esac
36.猜数字
#!/bin/bash
##################################################
#   Script Name     : guessNum.sh
#   Author          : xinsui1314x
#   Address         : https://segmentfault.com/u/xinsui1314x
##################################################

echo "-----------------------------------"
echo "          猜数字"
echo "  请猜1-100的随机数!"
echo "     不对不准离开!"
echo "-----------------------------------"

#生成随机数0-100
let num=$RANDOM%100+1

#循环判断,不对不走
i=0     #//记次使用
while  read -p "(q退出)你猜什么数:" guess
do
  let i++
  if [ $guess -gt 0 ] &> /dev/null && [ $guess -le 100 ];then
        if [ $guess -eq $num ];then
          echo "猜了 $i 次才对!可以走了"
          exit
        elif [ $guess -gt $num ];then
          echo "猜大了"
        else
          echo "猜小了"
        fi
  elif [ "$guess" == "q" ];then
    echo "退出"
    exit
  else
    echo "输入有误,请重输"
  fi
done
37.猜拳37.1 脚本一般对比猜拳
#!/bin/bash

#   Script Name     : finger-guessing.sh
#   Author          : xinsui1314x
#   Address         : https://segmentfault.com/u/xinsui1314x

echo "石头0  布1  剪子2"

#判断输入是否正确
read -p "请出拳(0,1,2)" player
if [ "$player" == "0" ] || [ "$player" == "1" ] || [ "$player" == "2" ];then
    computer=$[$RANDOM % 3]    #//取3以内随机数
else
    echo "输入有误,退出"
    exit
fi

#判断胜负
result=""
if [ $player -eq $computer ];then
    result="平手"
elif [ $player -gt $computer ] && [ $player -eq 2 ] && [ $computer -eq 0 ];then
    result="电脑胜"
elif [ $player -gt $computer ];then
    result="玩家胜"
elif [ $player -lt $computer ] && [ $player -eq 0 ] && [ $computer -eq 2 ];then
    result="玩家胜"
elif [ $player -lt $computer ];then
    result="电脑胜"
fi

#胜负已定,为显示结果重新赋值变量
#玩家
if [ $player -eq 0 ];then
    player="石头"
elif [ $player -eq 1 ];then
    player="  布"
elif [ $player -eq 2 ];then
    player="剪子"
fi
#电脑
if [ $computer -eq 0 ];then
    computer="石头"
elif [ $computer -eq 1 ];then
    computer="布"
elif [ $computer -eq 2 ];then
    computer="剪子"
fi

#输出结果
echo "玩家 VS 电脑"
echo "$player VS $computer"
echo "   $result"
37.2 脚本使用数组对比猜拳
#!/bin/bash

#   Script Name     : finger-guessing.sh
#   Author          : xinsui1314x
#   Address         : https://segmentfault.com/u/xinsui1314x

game=(石头 剪刀 布)
num=$[$RANDOM%3]            #生成出拳随机数
computer=${game[$num]}      #获取对应的出拳中文
echo "请根据提示选择您的出拳手势:"
echo "1.石头"
echo "2.剪刀"
echo "3.布"
read -p "请选择:" player
case $player in
  1)
    if [ $num -eq 0 ];then
        echo "平局"
    elif [ $num -eq 1 ];then
        echo "你赢"
    else
        echo "电脑赢"
    fi;;
  2)
    if [ $num -eq 0 ];then
        echo "电脑赢"
    elif [ $num -eq 1 ];then
        echo "平局"
    else
        echo "你赢"
    fi;;
  3)
    if [ $num -eq 0 ];then
        echo "你赢"
    elif [ $num -eq 1 ];then
        echo "电脑赢"
    else
        echo "平局"
    fi;;
  *)
    echo "必须输入1-3的数字";;
esac
38.从小到大数字排序
#!/usr/bin/env bash
#   Script Name     : sort.sh
#   Author          : xinsui1314x
#   Address         : https://segmentfault.com/u/xinsui1314x
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
read -p "请输入第三个整数:" num3
tmp=0                                       #临时存储用
if [ $num1 -gt $num2 ];then
    tmp=$num1
    num1=$num2                              #num1存最小值
    num2=$tmp
fi
if [ $num1 -gt $num3 ] ;then
    tmp=$num1
    num1=$num3
    num3=$tmp                               #num3存最大值
fi
if [ $num2 -gt $num3 ] ;then
    tmp=$num2
    num2=$num3                              #num2存中间值
    num3=$tmp
fi
echo "从小到大排序:$num1 < $num2 < $num3"      #输出结果
39.进度条39.1 一般进度条
#!/binbash
progress(){
    while :
    do
        echo -n '#'
        sleep 0.5
    done
}
progress &
cp -a $1 $2
killall $!
echo "拷贝结束"
39.2 回旋镖版进度条
#!bin/bash
while :
do
    clear
    for i in {1..20}
    do
        echo -e "\033[3;${i}H*"
        sleep 0.1
    done
    clear
    for i in {20..1}
    do
        echo -e "\033[3;${i}H*"
        sleep 0.1
    done
    clear
done
39.3 数字进度条
#!/bin/bash
for i in {1..100}
do
  echo -e "\033[6;8H["          #设置光标Y;X坐标
  echo -e "\033[6;9H$i%"
  echo -e "\033[6;13H]"
  sleep 0.1
done
39.4.1 表针进度条1(数组)
#!/bin/bash
arr=("|" "/" "-" "\\")                      #使用数组定义符号
for ((i=1;i<=100;i++))
do
    let index=$i%4                          #用于数组下标取值
    printf "[%-c]\r" "${arr[$index]}"       #格式化输出符号
    sleep 0.2
done
39.4.2 表针进度条2(case)
#!/bin/bash
progress(){
interval=0.1    #//设置时间间隔
index=0         #//设置4个形状编号,默认编号为0(不代表任何图像)
while :
do
  index=`expr $index + 1`   #index每次循环加1,负责获取不同符号
  case $index in            #判断index的值,根据值输出符号
    1)                      #//值为1显示-
        echo -e '-'"\b\c"   #\b 退格。 \c 禁止尾随的换行符
        sleep $interval
        ;;
    2)                      #//值为2显示\\,第一个\是转义
        echo -e '\\'"\b\c"
        sleep $interval
        ;;
    3)                      #//值为3显示 |
        echo -e '|'"\b\c"
        sleep $interval
        ;;
    4)                      #//值为4显示 /
        echo -e '/'"\b\c"
        sleep $interval
        ;;
    *)                      #//值为其他时,将index重置为0
        index=0
        ;;
    esac
done
}
progress
40.九九乘法表
#!/bin/bash
nineTab() {
for i in `seq 9`
do
    for j in `seq $i`
    do
        echo -n "$i*$j=$[i*j] "     #输出乘法公式
    done
    echo 
done
}
nineTab | column -t                 #有点乱,对齐一下
41.100以内所有正整数求和
#!/bin/bash
#seq 100可以快速自动生成100个整数
sum=0
for i in `seq 100`
do
    sum=$[sum+i]
done
echo "总和是:$sum"
42.批量修改扩展名
#!/bin/bash
#执行脚本时,需要给脚本添加位置参数
#脚本名 txt doc(可以将txt的扩展名修改为doc)
#脚本名 doc jpg(可以将doc的扩展名修改为jpg)
for i in `ls *.$1`
do
    mv $i ${i%.*}.$2                                                                               
done
43.打印国际象棋棋盘
#!/bin/bash
#设置两个变量,i和j,一个代表行,一个代表列,国际象棋为8*8棋盘
#i=1是代表准备打印第一行棋盘,第1行棋盘有黑色、灰色间隔输出,总共为8列                             
#i=1,j=1代表第1行的第1列;i=2,j=3代表第2行的第3列
#棋盘的规律是i+j如果是偶数,就打印黑色色块,如果是奇数就打印灰色色块
#使用echo -ne打印色块,并且打印完成色块后不自动换行,在同一行继续输出其他色块
for i in {1..8}
do
    for j in {1..8}
    do
        sum=$[i+j]
        if [ $[sum%2] -eq 0 ];then
            echo -ne "\033[40m \033[0m"         #黑色背景
        else
            echo -ne "\033[47m \033[0m"         #灰色背景
        fi
    done
    echo 
done
44.自动为其他脚本添加头部解释器信息
#!/bin/bash
#./test.sh abc.sh //自动为abc.sh添加解释器信息

#先使用grep判断对象脚本是否已经有解释器信息,如果没有则使用sed添加解释器以及描述信息
if [ ! `grep -q "^#!" $1` ] ;then
#if  ! grep -q "^#!" $1  ;then
    sed -i '1i #!/bin/bash' $1
    sed -i '2i #Description: ' $1
fi
                                                                                         
#因为每个脚本的功能不同,作用不同,所以在给对象脚本添加完解释器信息,
#以及Description后还希望继续编辑具体的脚本功能的描述信息,
#这里直接使用vim把对象脚本打开,并且光标跳转到该文件的第2行:vim +2 $1
vim +2 $1 
45.使用脚本循环创建3位数的文本文件(111-999的文件)
#!/bin/bash
path=/mnt                       #声明存储文件的目录
for i in {1..9}
do
    for j in {1..9}
    do
        for k in {1..9}
        do
            touch $path/$i$j$k.txt                                                                 
        done
    done
done
46.判断文件或目录是否存在
#!/bin/bash

if [ $# -eq 0 ];then
    echo "未输入任何参数,请输入参数"
    echo "用法:$0 [文件名 | 目录名]"
fi

if [ -f $1 ]; then
    echo "该文件 存在"
    ls -l $1
elif [ -d $1 ]; then
    echo "该目录 存在"
    ls -ld $1
else
    echo "该文件or目录 不存在"
fi
47.根据md5校验码,检测文件是否被修改
#!/bin/bash
#脚本示例检测/etc目录下的所有.conf结尾的文件,可根据需要修改
#脚本在目标数据没被修改时执行一次,当怀疑数据被人篡改,再执行一次
#将两次执行的结果做对比,MD5码发生改变的文件,就是被篡改的文件
for i in $(ls /etc/*.conf)
do
    md5sum "$i" >> /var/log/conf_file.log
done
48.删除某个目录下大小为0的文件
#!/bin/bash
dir=/tmp
find $dir  -type f  -size 0  -exec rm -rf {} \;
49.将文件中所有小写字母转换为大写字母
#!/bin/bash
#使用方法:脚本名 /文件名
tr "[a-z]" "A-Z" < $1
50.检查特定的软件包是否已经安装
#!/bin/bash

if [ $# -eq 0 ];then
    echo "需要指定一个软件包名称作为脚本参数"
    echo "用法:$0 软件包名称 ..."
fi
# $@变量提取所有的位置变量的值,类似于$*,但可以当作数组使用                                       
for package in "$@"
do
    if `rpm -q ${package} &> /dev/null` ;then
        echo -e "${package}\t\033[32;1m已安装\033[0m"
    else
        echo -e "${package}\t\033[31;1m未安装\033[0m"
    fi
done
51.提示用户输入年份后测试判断是否为闰年
#!/bin/bash

#闰年条件:
#能被4整除并且能被100整除
#或被400整除

read -p "请输入一个年份:" year
if [ "$year" = "" ];then
    echo "没有输入年份"
    exit
fi
#使用正则测试变量year中是否包含大小写字母
if [[ "$year" =~ [a-Z] ]];then                                                                     
    echo "你输入的不是数字"
    exit
fi

#判断闰年
if [ $[year % 4] -eq 0 ] && [ $[year % 100] -ne 0 ];then
    echo "$year 是闰年"
elif [ $[year % 400] -eq 0 ];then
    echo "$year 是闰年"
else
    echo "$year 不是闰年"
fi
52.生成随机密码52.1 urandom生成随机密码
#!/bin/bash
#/dev/urandom文件是Linux内置的随机设备文件
#cat /dev/urandom可以查看里边的内容,ctrl+c退出
#查看该文件内容后,发现内容包括很多特殊符号,需要使用的密码不要这些符号
#tr -dc '_A-Za-z0-9' < /dev/urandom
# -d可以将随机文件中其他的字符删除,-c指定保留下划线、大小写字母、数字,
#继续优化,将内容管道给head命令,在大量数据中仅显示头10个字节
#注意A前面有个下划线
tr -dc '_A-Za-z0-9' < /dev/urandom | head -c 10
52.2 字符串截取随机密码
#!/bin/bash
#设置变量key,存储密码的所有可能性(密码库),若还需其他字符请自行添加其他密码字符
#使用$#统计密码库的长度
key="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
num=${#key}
#设置初始密码为空
pass=''
#循环8次,生成8位随机密码
#每次都是随机数对密码库的长度取余,确保提取的密码字符不超过密码库的长度
#每次循环提取一位随机密码,并将该随机密码追加到pass变量的最后
for i in {1..8}
do
    index=$[RANDOM%num]                                                                            
    pass=$pass${key:$index:1}
done
echo $pass
52.3 用进程pid生成随机密码
#!/bin/bash
echo $$            # $$ 这个程式的PID(脚本运行的当前进程ID号)
52.4 uuid生成16进制随机密码
#!/bin/bash
uuidgen
53.Shell脚本的fork炸弹
#!/bin/bash
#快速消耗计算机资源,致使计算机死机
#定义函数名为.(点),函数中递归调用自己并放入后台执行
.() { .|.& };.
54.统计文件中某字符串出现的次数
#!/bin/bash
file=/etc/passwd
str="root"
#每读取一行文件内容,就从第1列循环到最后1列,
#依次判断是否包含root关键词,若包含则x++
awk -F: -v str=$str '
    BEGIN{i=0;x=0}
    {while(i<=NF)
        {if($i~str)
            {x++}
            i++
        }
    }
    END{print str"的数量是:" x}
' $file
55.打印斐波那契数列
#!/bin/bash
#斐波那契数列:后一个数字,永远都是前2个数字之和
#如:0 1 1 2 3 5 8 13...
read -p "要生成多少位的数列(默认10)?" num
let num=${num:-10}-1
list=(0 1)
echo -en "计算中...\r"
for i in `eval seq 2 $num`
do
    list[$i]=`expr ${list[-1]} + ${list[-2]}`
done
echo "${list[@]}"
56.判断用户输入的是Yes或No
#!/bin/bash
read -p "Are you sure?[y/n]:" sure
case $sure in
    y|Y|yes|YES)
        echo "you enter $sure"
        ;;
    n|N|no|NO)
        echo "you enter $sure"
        ;;
    *)
        echo "error"
        ;;
esac
57.Shell脚本对信号的处理,执行脚本后,按键盘Ctrl+C无法终止的脚本
#!/bin/bash
#
#使用trap命令可以拦截用户通过键盘或kill命令发送过来的信号
#使用kill -l可以查看Linux系统中所有的信号列表,其中2代表ctrl+c
#trap当发现有用户ctrl+c希望中断脚本时,就执行echo "暂停10s";sleep 10这两条命令
#当用户使用命令【kill -2 脚本的pid】,也可以中断脚本和ctrl+c效果相同,都会被trap拦截
trap 'echo "暂停10s";sleep 10' 2
while :
do
  echo "脚本pid=$$"
done
#停止脚本可以使用命令【kill 脚本pid】
58.画图
#!/bin/bash
"""
1
22
333
4444
55555
666666
7777777
88888888
999999999
|_ 
| |_ 
| | |_ 
| | | |_ 
| | | | |_ 
*
* *
* * *
* * * *
* * * * *
* * * * *
* * * *
* * *
* *
*
"""
#for(())为类C语言的语法格式,也可以使用for i in; do ; done的格式替换
#for((i=1;i<=9;i++))循环会执行9次,i从1开始到9,每次循环一次i自加1
clear
echo "打印第一组图片"
for (( i=1; i<=9; i++ ))
do
    for (( j=1; j<=i; j++ ))
    do
        echo -n "$i"
    done
    echo ""
done
read -p "按任意键继续" key

clear
echo "打印第二组图片"
for (( i=1; i<=5; i++ ))
do
    for (( j=1; j<=i; j++ ))
    do
        echo -n " |"
    done
    echo "_ "
done
read -p "按任意键继续" key

clear
echo "打印第三组图片"
for (( i=1; i<=5; i++ ))
do
    for (( j=1; j<=i; j++ ))
    do
        echo -n " *"
    done
    echo ""
done
for (( i=5; i>=1; i--))
do
    for (( j=1; j<=i; j++ ))
    do
        echo -n " *"
    done
    echo ""
done
59.根据计算机当前时间,返回字符串(可用于开机自启)
#!/bin/bash
#使用date命令获取时间后,if判断时间的区间,确定返回的字符串                                            
tm=`date +%H`
if [ $tm -le 12 ];then
    msg="Good Morning"
elif [ $tm -gt 12  -a  $tm -le 18 ];then
    msg="Good Afternoon"
else
    msg="Good Night"
fi
echo "当前时间是:`date +"%Y-%m-%d %H:%M:%S"`"
echo -e "\033[1;34m$msg $USER\033[0m"
60.打印各种时间格式
#!/bin/bash
echo "显示星期简称(如:Sun)" 
date +%a 
echo "显示星期全称(如:Sunday)" 
date +%A 
echo "显示月份简称(如:Jan)" 
date +%b 
echo "显示月份全称(如:January)" 
date +%B 
echo "显示数字月份(如:12)" 
date +%m 
echo "显示数字日期(如:01 号)" 
date +%d 
echo "显示数字年(如:01 号)" 
date +%Y
echo "显示年‐月‐日" 
date +%F 
echo "显示小时(24 小时制)" 
date +%H 
echo "显示分钟(00..59)" 
date +%M 
echo "显示秒" 
date +%S 
echo "显示纳秒" 
date +%N 
echo "组合显示" 
date +"%Y%m%d %H:%M:%S"
61.统计数色球各个数字的中将概率
#!/bin/bash
#往期双色球中奖号码写入文件: 
cat >> his.txt <<EOF
01 04 11 28 31 32 16
04 07 08 18 23 24 02
02 05 06 16 28 29 04
04 19 22 27 30 33 01
05 10 18 19 30 31 03
02 06 11 12 19 29 06
EOF
#统计蓝球和红球数据出现的概率次数(蓝球不分顺序,统计所有蓝球混合在一起的概率)
awk '{print $1"\n"$2"\n"$3"\n"$4"\n"$5"\n"$6"\n"}' his.txt | sort | uniq -c | sort
awk '{print $7}' his.txt |sort |uniq -c | sort

rm -f his.txt       #删除历史号码文件
62.使用awk编写的wc程序
#!/bin/bash
#自定义变量chars变量存储字符个数,自定义变量words变量存储单词(列)个数                                
#awk内置变量NR存储行数
#length()为awk内置函数,用来统计每行的字符数量,因为每行都会有一个隐藏的$,所以每次统计后都+1
#wc程序会把文件结尾符$也统计在内,可以使用【cat -A 文件名】,查看该隐藏字符
if [ $# -eq 0 ]; then
    echo -e "Usage:\n\t $0 file_name"
    exit
fi
awk '{chars+=length($0)+1; words+=NF} END{print "NR="NR,"words="words,"chars="chars}' $1
63.yum一键部署LAMP
#!/bin/bash
n=`yum repolist | awk '/repolist/{print $2}' | sed "s/,//"`     #获取repo数量
if [ $n -gt 0 ];then                                            #判断repo数量
    yum -y install httpd                                        #安装Apache
    yum -y install mariadb mariadb-server mariadb-devel         #安装Mariadb
    yum -y install php php-mysql                                #安装Php及mysql支持php插件
    systemctl start httpd mariadb                               #启服务
    systemctl enable httpd mariadb                              #设置服务自启
else
    echo "yum源有问题,请检查。。。"
fi
64.统计某时间内来访apache服务器的ip及其次数
#!/bin/bash
read -p "请输入查询时间段(0:00 24:00):" tm1 tm2
tm1=${tm1:-"0:00"}
tm2=${tm2:-"24:00"}
echo "$tm1~$tm2 期间apache的访问情况:"
awk -F "[ /:]"  -v tm1="$tm1" -v tm2="$tm2" '
    BEGIN{print "访问次数","访问ip"}
    $7":"$8>=tm1 && $7":"$8<=tm2{ip[$1]++}
    END{for(i in ip){print ip[i],i}}
' /var/log/httpd/access_log | column -t
65.监控HTTP服务器的状态(测试返回码)
#!/bin/bash                                                           #设置变量,url是需要检测的目标网站的网址(ip或域名)                    url=http://192.168.31.1/index.html                                    
#定义函数check_http:
#使用curl命令检查http服务器的状态
# -m设置curl不管访问成功或失败,最大消耗时间为5秒,5s连接服务未响应则>视为无法连接
# -s设置静默连接,不显示连接时的连接速度、时间消耗等信息              # -o将curl下载的页面内容导出到/dev/null(默认会在屏幕显示页面内容)     # -w设置curl命令需要显示的内容%{http_code},指定curl返回服务器的状态码
  # $$当前运行进程的pid
check_http() {
    status_code=$(curl  -m 5  -s  -o /dev/null  -w %{http_code}  $url)
}

while :
do
    check_http
    date=$(date +%Y%m%d-%H:%M:%S)

    #指定测试服务器状态的函数,
    #并根据返回码决定是发送邮件报警或将正常信息写入日志
    if [ $status_code -ne 200 ];then
        #生成报警邮件的内容
        echo "当前时间为:$date
        $url服务器异常,状态码为${status_code}.
        请尽快排查异常。" > /tmp/http$$.pid                           
        mail -s Warning root < /tmp/http$$.pid
    else
        echo "$date $url连接正常" >> /var/log/http.log
    fi
    sleep 5
done
66.生成自签名私钥和证书
#!/bin/bash
read -p "请输入存放证书的目录:" dir
if [ ! -d $dir ]; then
    echo "该目录不存在"
    exit
fi
read -p "请输入密钥名称:" name
#使用openssl生成私钥
openssl genrsa -out ${dir}/${name}.key
#使用openssl生成证书
#subj选项可以在生成证书时,非交互自动填写Common Name信息
openssl req -new -x509 -key ${dir}/${name}.key -subj "/CN=common/" -out ${dir}/${name}.crt
67.一键部署LNMP(源码安装)
#!/bin/bash
check_yum(){
    yum clean all &>/dev/null
    local repolist=yum repolist | awk '/repolist/{print $2}' | sed "s/,//"
    if [ $repolist -eq 0 ];then
        echo -e "ERROR:请检查yum源"
        exit
    fi

menu(){
    clear
    echo " ##########----Menu----##########"
    echo "# 1.Install Nginx"
    echo "# 2.Install MySQL"
    echo "# 3.Install PHP"
    echo "# 4.Exit Program"
    echo " ##############################################"
}

choice(){
    read -p "Please choice a menu[1-4]:" select
}

install_nginx(){
    id nginx &>/dev/null
    if [ $? -ne 0 ];then
        useradd -s /sbin/nologin nginx
    fi
    yum -y install  gcc  pcre-devel  openssl-devel zlib-devel
    cd /usr/local/src
    http://nginx.org/download/nginx-1.10.3.tar.gz
    tar -zxvf nginx-1.10.3.tar.gz
    cd nginx-1.10.3
    ./configure \
    --prefix=/usr/local/nginx \
    --user=nginx \
    --group=nginx \
    --with-http_ssl_module \
    --with-http_gzip_static_module
    make && make install
}
    
install_mysql(){
    read -p "此操作会删除本机原有的Mysql、mariadb及其相关文件、数据库。是否执行?[y/n]"  sure
    sure=${sure:-n}
    if [ "$sure" != "y" ]; then
        exit
    fi
    rpms=`rpm -qa | grep -Ei "mariadb|mysql"`       #卸载已安装的mysql相关软件
    [ ! -z "$rpms" ] && for rpm in $rpms
    do
        rpm -e --nodeps $rpm
    done
    cd /usr/local/src                               #准备安装
    wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.16.tar.gz
    mv /etc/my.cnf /etc/my.cnf.bak
    rm -rf /var/lib/mysql
    yum -y install cmake make gcc gcc-c++ wget ncurses-devel cmake make perl ncurses-devel openssl-devel bison-devel libaio libaio-devel
    mkdir -p /usr/local/mysql
    mkdir -p /usr/local/mysql/data
    useradd mysql
    chown -R mysql:mysql /usr/local/mysql
    chown -R mysql:mysql /usr/local/mysql/data
    tar -zxvf mysql-5.7.16.tar.gz
    cd mysql-5.7.16
    cmake .
    make
    make install
    /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/usr/local/mysql/data/ --basedir=/usr/local/mysql
    cp -f /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
    chmod +x /etc/init.d/mysqld
    cp -f /usr/local/mysql/support-files/my-default.cnf /etc/my.cnf
    echo "/usr/local/mysql/lib/" >> /etc/ld.so.conf
    ldconfig
    echo 'PATH=\$PATH:/usr/local/mysql/bin/' >> /etc/profile
    export PATH
}

install_php(){
#安装php时没有指定启动哪些模块功能,用户可以根据实际情况自行添加额外功能,如--with-gd等
    yum -y install gcc libxml2-devel
    wget https://www.php.net/distributions/php-5.4.24.tar.gz
    tar -xf php-5.4.24.tar.gz
    cd php-5.4.24
    ./configure --prefix=/usr/local/php5 --with-mysql=/usr/local/mysql --enbale-fpm --enable-mbstring --with-mcrypt --with-mhash --with-config-file-path=/usr/local/php5/etc --with-mysqli=/usr/local/mysql/bin/mysql_config
    make && make install
    cp -f php.ini-production /usr/local/php5/etc/php.ini
    cp -f /usr/local/php5/etc/php-fpm.conf.default /usr/local/php5/etc/php-fpm.conf
    cd ..
}

check_yum
while :
do
    menu
    choice
    case $select in
        1)
          install_nginx
          ;;
        2)
          install_mysql
          ;;
        3)
          install_php
          ;;
        4)
          exit
          ;;
        *)
          echo "乱点木有用!!!"
          ;;
    esac
done
68.编写nginx启动脚本
#!/bin/bash

#本脚本编写完成后,放置在/etc/init.d/目录下,就可以被linux系统自动识别到该脚本
#如果脚本名为/etc/init.d/nginx,则service nginx start 就可以启动该服务
#service nginx stop 就可以关闭服务
#service nginx restart 就可以重启服务
#service nginx status 可以查看服务状态

program=/usr/local/nginx/sbin/nginx
pid=/usr/local/nginx/logs/nginx.pid
start(){
    if [ -f $pid ] ;then
        echo "nginx服务已经处于开启状态"
    else
        $program
    fi
}
stop(){
    if [ ! -f $pid ] ;then
        echo "nginx服务已关闭"
    else
        $program -s stop
        echo "关闭服务OK"
    fi
}
status(){
    if [ -f $pid ] ;then
        echo "服务正在运行"
    else
        echo "服务已经关闭"
    fi
}

case $1 in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 1
        start
        ;;
    status)
        status
        ;;
    *)
        echo "你输入的语法格式错误"
esac
69. 切割 Nginx 日志文件(防止单个文件过大,后期处理很困难)
#!/bin/bash
logs_path="/usr/local/nginx/logs/" 
mv ${logs_path}access.log ${logs_path}access_$(date +"%Y%m%d" -d yesterday).log  #以前一天时间标识
kill ‐USR1  `cat /usr/local/nginx/logs/nginx.pid`     #USR1无需重启而平滑的生成已经移走的日志文件
#需要先执行一次本脚本,
#或crontab -e手动写入计划任务,并注释下边命令
once=0
if [ $once -eq 0 ]; then
    echo "0 1 * * * `readlink -f $0`" >> /var/spool/cron/$USER
    sed -i "/^once=/s/0/1/" $0
fi
70.检测MySQL服务是否存活
#!/bin/bash

host=检测的MySQL主机ip
user=MySQL用户名
passwd=密码

mysqladmin -h$host -u$user -p$passwd ping &> /dev/null
if [ $? -eq 0 ];then
    echo "MySQL is UP"
else
    echo "MySQL is down"
fi
71.检测MySQL数据库连接数量
#!/bin/bash
#本脚本每2秒检测一次MySQL并发连接数,可以将本脚本设置为开机自启,或指定时间执行
#以满足对MySQL数据库的监控需求,查看MySQL连接是否正常
log_file=/var/log/mysql_count.log
user=用户名
passwd=密码
while :
do
    sleep 2
    count=`mysqladmin -u"$user" -p"$passwd" status | awk '{print $4}'`
    echo "`date +%Y-%m-%d` 并发连接数为:$count" >> $log_file
done
72.mysqldump命令备份MySQL数据库
#!/bin/bash

user=数据库用户名
passwd=密码
dbname=需要备份的数据库名称
date=$(date +%Y%m%d)

#测试备份目录是否存在,不存在则自动创建该目录
[ ! -d /mysqlbackup ] && mkdir /mysqlbackup
#使用mysqldump命令备份数据库
mysqldump -u$user -p$passwd  $dbname > /mysqlbackup/${dbname}-${date}.sql
73.从键盘读取一个论坛积分,判断论坛用户等级
#!/bin/bash
#
read -p "请输入积分(0-100):" JF
if [ $JF -ge 90 ];then
  echo "$JF分,神功绝世"
elif [ $JF -ge 80 ];then
  echo "$JF分,登峰造极"
elif [ $JF -ge 70 ];then
  echo "$JF分,炉火纯青"
elif [ $JF -ge 60 ];then
  echo "$JF分,略有小成"
else
  echo "$JF分,初学乍练"
fi
74.自动部署varnish源码包
#!/bin/bash

cd /usr/local/src
wget https://varnish-cache.org/_downloads/varnish-3.0.6.tgz
yum -y install  gcc readline-devel pcre-devel
useradd -s /sbin/nologin varnish
tar -xf varnish-3.0.6.tgz
cd varnish-3.0.6

#使用configure , make , make install源码安装软件包
./configure --prefix=/usr/local/varnish
make && make install

#在源码包目录下,将相应的配置文件拷贝到Linux系统文件系统中
#默认安装完成后,不会自动拷贝或安装配置文件到Linux系统,需手动cp复制配置文件,
#并用uuidgen生成一个随机密钥的配置文件
cp redhat/varnish.initrc /etc/init.d/varnish
cp redhat/varnish.sysconfig /etc/sysconfig/varnish
cp redhat/varnish_reload_vcl /usr/bin
ln -s /usr/local/varnish/sbin/varnishd /usr/sbin/
ln -s /usr/local/varnish/bin/* /usr/bin
mkdir /etc/varnish
cp /usr/local/varnish/etc/varnish/default.vcl /etc/varnish/
uuidgen > /etc/varnish/secret
75.自动部署memcached源码包
#!/bin/bash
#
cd /usr/local/src
wget http://www.memcached.org/files/memcached-1.5.10.tar.gz
yum -y install gcc
tar -xf memcached-1.5.10.tar.gz
cd memcached-1.5.10
./configure
make
make install
76.自动安装KVM虚拟机
#!/bin/bash

egrep "vmx|smv" /proc/cpuinfo >/dev/null        #确认主机cpu是否支持虚拟化
if [ $? -eq 0 ]; then
    yum -y install qemu-kvm qemu-img virt-manager virt-viewer libvirt libvirt-client
    systemctl start libvirtd && systemctl enable libvirtd
    echo "KVM安装已完成"
else
    echo "主机CPU不支持虚拟化,退出!"
    exit 2
fi
77.KVM安装虚拟系统
#!/bin/bash
cat <<EOF
#脚本针对RHEL7系列
#此脚本并不能完全自动安装虚拟机,安装过程中需要手动设置各项参数
#此脚本存在的意义是:衔接后边的脚本
#需要提供iso文件
EOF

read -p "请输入iso安装镜像路径[/ISO/CentOS-7-x86_64-Everything-1708.iso]:" iso
iso=${iso:-"/ISO/CentOS-7-x86_64-Everything-1708.iso"}
if [ ! -f "$iso" ]; then
    echo "iso文件路径有误!!!"
    exit
fi

name=rh7_template
memSize=1024
cpus=1
diskSize=8

yum -y install virt-install        #提供virt-install命令

virt-install \
    --name=$name --memory=$memSize --vcpus=$cpus \
    --location=$iso \
    --disk path=/var/lib/libvirt/images/$name.qcow2,format=qcow2,size=$diskSize,bus=virtio,sparse \
    --graphics=none \
    --extra-args="console=ttyS0 serial" \
    --accelerate \
    --force
#登陆后手动关闭即可
78.快速克隆KVM虚拟系统
#!/bin/bash
#本脚本针对RHEL7系列
#本脚本需要提前准备一个qcow2格式的虚拟机模版,名称为/var/lib/libvirt/images/rh7_template的虚拟机模版
#该脚本使用qemu-img命令快速创建快照虚拟机
#脚本使用sed修改模版虚拟机的配置文件,将虚拟机名称、UUID、磁盘文件名、MAC地址
# exit code:
#    65 -> user input nothing
#    66 -> user input is not a number
#    67 -> user input out of range
#    68 -> vm disk image exists

xml_DIR=/etc/libvirt/qemu
IMG_DIR=/var/lib/libvirt/images
BASEVM=rh7_template
read -p "Enter VM number:" VMNUM
if [ $VMNUM -le 9 ];then
    VMNUM=0$VMNUM
fi

if [ -z "${VMNUM}" ];then
    echo "You must input a number."
    exit 65
elif [[ ${VMNUM} =~ [a-z] ]];then
    echo "You must input a number."
    exit 66
elif [ ${VMNUM} -lt 1 -o ${VMNUM} -gt 99 ];then
    echo "Input out of range"
    exit 67
fi

NEWVM=rh7_node${VMNUM}

if [ -e $IMG_DIR/${NEWVM}.qcow2 ];then
    echo "File exists."
    exit 68
fi

echo -en "Creating Virtual Machine disk image......\t"
qemu-img create -f qcow2 -b $IMG_DIR/${BASEVM}.qcow2 $IMG_DIR/${NEWVM}.qcow2 &> /dev/null
echo -e "\e[32;1m[OK]\e[0m"

cat $xml_DIR/${BASEVM}.xml > ${xml_DIR}/${NEWVM}.xml
sed -i "/<name>${BASEVM}/s/${BASEVM}/${NEWVM}/" ${xml_DIR}/${NEWVM}.xml
sed -i "/uuid/s/<uuid>.*<\/uuid>/<uuid>$(uuidgen)<\/uuid>/" ${xml_DIR}/${NEWVM}.xml
sed -i "/${BASEVM}\.qcow2/s/${BASEVM}/${NEWVM}/" ${xml_DIR}/${NEWVM}.xml

blkMAC=`openssl rand -hex 3 | sed 's/\(..\)/\1:/g; s/.$//'`
sed -ri "s#(<mac address='..:..:..:).*('/>)#\1$blkMAC\2#" ${xml_DIR}/${NEWVM}.xml

echo -en "Defining new virtaul machine......\t\t"
virsh define ${xml_DIR}/${NEWVM}.xml &> /dev/null
echo -e "\e[32;1m[OK]\e[0m"

virsh list --all
79.使用脚本开关虚拟机
#!/bin/bash
#
#脚本通过virsh命令实现对虚拟机的管理,若没有该命令,需要安装libvirt-client软件包
# $1是脚本的第1个参数,输入需要虚拟机执行的操作指令
# $2是脚本的第2个参数,输入虚拟机的名称
case $1 in
  list)
    virsh list --all ;;
  start)
    virsh start $2 ;;
  stop)
    virsh shutdown $2 ;;
  enable)
    virsh autostart $2 ;;
  disable)
    virsh autostart --disable $2 ;;
  *)
    echo "Usage:$0 list"
    echo "Usage:$0 [start | stop | enable | disable] VM_name"
    cat <<EOF
      list     显示虚拟机列表
      start    启动虚拟机
      stop     关闭虚拟机
      enable   设置虚拟机为开机自启
      disable  关闭虚拟机开机自启
EOF
    ;;
esac
80.调整虚拟机内存参数的shell脚本
#!/bin/bash
#
#脚本通过调用virsh命令实现对虚拟机的管理,若没有该命令,需要安装libvirt-client软件包
vms=`virsh list --name`
for vm in $vms
do
    echo -n "$vm     "
    virsh dommemstat $vm | awk '/actual/{print $2}'        #获取虚拟机实际内存
done
echo
cat <<EOF
提示:虚拟机要处于开机状态
  1.调整虚拟机最大内存
  2.调整实际分配给虚拟机的内存数值
EOF
read -p "请选择[1-2]:" select
case $select in
  1)
    read -p "请输入虚拟机名称:" name
    read -p "请输入最大内存数值(单位:k):" size
    virsh setmaxmem $name --size $size --config ;;
  2)
    read -p "请输入虚拟机名称:" name
    read -p "请输入实际分配内存数值(单位:k):" size
    virsh setmem $name $size ;;
  *)
    echo "Error" ;;
esac
81.查看所有虚拟机磁盘使用量及cpu使用量信息
#!/bin/bash
#
# libguestfs-tools-c软件包,提供virt-df命令
# virt-top需要单独安装
rpm --quiet -q libguestfs-tools-c
[ $? -ne 0 ] && yum -y install libguestfs-tools-c --nogpgcheck
virt-df | column -t
read -n1 "按任意键继续" key
rpm --quiet -q virt-top
[ $? -ne 0 ] && yum -y install virt-top
virt-top
82.破解虚拟机密码,无密码登录虚拟机系统
#!/bin/bash
#
#该脚本使用guestmount工具,libguestfs-tools-c中包含guestmount工具
read -p "请输入虚拟机名称:" name
if virsh domstate $name | grep -q running; then
  echo "破解,需先关闭虚拟机"
  virsh shutdown $name
fi
mountpoint="/media/virtimage"
[ ! -d $mountpoint ] && mkdir $mountpoint
echo "请稍后。。。"
if mount | grep -q "$mountpoint"; then
 umount $mountpoint
fi
guestmount -d $name -i $mountpoint
#将passwd中密码占位符x删除,该账户即可实现无密码登录系统
sed -i "/^root/s/x//" $mountpoint/etc/passwd
83.查看KVM虚拟机中的网卡信息(不用进入或启动虚拟机)
#!/bin/bash
#
#该脚本使用guestmount工具,可以将虚拟机的磁盘系统挂载到真实机文件系统中
#虚拟机启动与否都不影响此脚本的使用
#将虚拟机磁盘文件挂载到文件系统后,就可以直接读取磁盘文件中的网卡配置文件中的数据
#可获取写入配置文件的静态ip
if ! rpm -q --quiet libguestfs-tools-c ; then
    yum -y install libguestfs-tools-c        #提供guestmount工具
fi
clear
mountpoint="/media/virtimage"
[ ! -d $mountpoint ] && mkdir $mountpoint
read -p "输入虚拟机名称:" name
echo "准备中。。。"
#若有设备已挂载到该挂载点,则先umount卸载
if mount | grep -q "$mountpoint" ;then        #grep -q选项,安静(quiet)模式,不向标准输出写任何东西
    umount $mountpoint
fi
#只读的方式,将虚拟机的磁盘文件挂载到特定的目录下,这里是/media/virtimage目录
#guestmount -r只读 -d 域名 -i 挂载点
guestmount -r -d $name -i $mountpoint
echo
echo "--------------------------------------------------"
echo -e "\033[32m$name 虚拟机中网卡列表如下:\033[0m"
dev=`ls /media/virtimage/etc/sysconfig/network-scripts/ifcfg-* | awk -F"[/-]" '{print $9}'`
echo "$dev"
echo "--------------------------------------------------"
echo
echo
echo "++++++++++++++++++++++++++++++++++++++++++++++++++"
echo -e "\033[32m 网卡ip地址信息如下:\033[0m"
for i in $dev
do
    echo -n "$i:"            #-n不输出行尾的换行符
    grep -q "ipaddr" /media/virtimage/etc/sysconfig/network-scripts/ifcfg-$i
done
echo "++++++++++++++++++++++++++++++++++++++++++++++++++"
umount $mountpoint
84.不登录虚拟机,修改虚拟机网卡ip地址
#!/bin/bash
#
#该脚本使用guestmount工具,安装libguestfs-tools-c获取guestmount工具
#脚本在不登录虚拟机的情况下,修改虚拟机的ip地址信息
#在某些环境下,虚拟机没有ip或ip地址与真实主机不再一个网段
#真实主机在没有virt-manager图形的情况下,远程连接虚拟机很麻烦
#该脚本可以解决类似问题
read -p "请输入虚拟机名称:" name
if virsh domstate $name | grep -q running ;then
  echo "修改虚拟机网卡数据,需要关闭虚拟机"
  virsh shutdown $name
fi
mountpoint="/media/virtimage"
[ ! -d $mountpoint ] && mkdir $mountpoint
echo "准备中。。。"
if mount | grep -q "$mountpoint" ;then
  umount $mountpoint
fi
guestmount -d $name -i $mountpoint
read -p "请输入需要修改的网卡名称:" dev
read -p "请输入ip地址:" addr
#判断原本网卡配置文件中是否有ip地址,有则修改该ip,没有则添加一个新的ip
if grep -q "IPADDR" $mountpoint/etc/sysconfig/network-scripts/ifcfg-$dev ;then
  sed -i "/IPADDR/s/=.*/=$addr/" $mountpoint/etc/sysconfig/network-scripts/ifcfg-$dev
else
  echo "IPADDR=$addr" >> $mountpoint/etc/sysconfig/network-scripts/ifcfg-$dev
fi
#若网卡配置文件中有客户配置的ip地址,则脚本提示修改ip完成
awk -F= -v x=$addr '$2==x {print "完成..."}' $mountpoint/etc/sysconfig/network-scripts/ifcfg-$dev
特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。
上一篇: linux基本介绍

Tags 标签

加个好友,技术交流

1628738909466805.jpg