60天shell脚本计划-6/12-渐入佳境

--作者:飞翔的小胖猪

--创建时间:2021年2月21日

--修改时间:2021年2月25日

说明

 每日上传更新一个shell脚本,周期为60天。如有需求的读者可根据自己实际情况选用合适的脚本,也可在评论区留言提出脚本需求,作者会尽快根据需求编写相关脚本对功能进行实现。

 每篇文章包含5个脚本。

总进度:6/12

上一篇脚本链接:https://www.cnblogs.com/Pigs-Will-Fly/p/14401712.html

下一篇脚本链接:https://www.cnblogs.com/Pigs-Will-Fly/p/14450642.html

主要内容

21年2月21日-/proc/stat文件另存脚本

************************************************************************************************************************************************************************************************************************************

脚本说明

脚本每一秒获取保存一次/proc/stat文件至指定目录,然后自动删除5分钟之前保存的文件,存储文件命名方式为时间戳。

文件说明

cpu_info.sh:脚本主体文件

脚本主体

[root@135 26_cpu_info]# cat Info_collect_cpu.sh 
#!/bin/bash
#清除过期的cpu信息文件
Clear_old_file(){
  #清除掉5分钟以后的文件,因为我用不到
  #判断文件和当前时间戳是否相差超过300秒,如果超过300秒则表示为5分钟以前的就删除它
  #为了谨慎起见我保留310秒的数据
  while :
  do
    d_now_time=`date +%s` #获取当前时间戳
    ls ./.cpu_info_file/| while read file_name
    do
      let interv_time=${d_now_time}-${file_name}
      if [ ${interv_time} -gt 310 ];then
        rm -rf ./.cpu_info_file/${file_name}
        sleep 1
      fi
    done
  done
}

#保存每秒的cpu文件
Info_collect_engine(){
  #循环执行一直在系统钟,没秒获取一次cpu文件,以时间搓为文件名保存
  #就是说实时保存最近5分钟的数据。
  
  #创建一个文件夹保存所有记录文件
  mkdir -p .cpu_info_file
  while :
  do
    now_time=`date +%s`
    cp /proc/stat .cpu_info_file/${now_time}
    #等待1秒再执行以后的操作
    sleep 1
  done
}

#主函数
main(){
  Info_collect_engine &
  Clear_old_file &
}

#调用主函数
main

结果

命令执行结果

 生成的文件

**************************************************************************************************************2021年2月21日脚本结束*****************************************************************************************************************

 

21年2月22日-CPU性能获取脚本

************************************************************************************************************************************************************************************************************************************

脚本说明

脚本读取/proc/stat文件,整理获取CPU当前使用情况。适用于多种操作系统。

如果想要获取到5分钟之内的数据,请参照2月21日的脚本编写一个信息收集引擎脚本,然后对历史数据进行整合。

文件说明

cpu_info.sh:脚本主体文件

配置文件

[root@135 ~]# cat /proc/stat 
cpu  819 39 2046 1109931 41 1306 1151 0 0 0
cpu0 507 29 903 554938 11 906 366 0 0 0
cpu1 311 10 1143 554992 30 399 784 0 0 0
intr 592713 45 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 696 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
ctxt 744120
btime 1613783846
processes 1716
procs_running 1
procs_blocked 0
softirq 943781 1 401759 2028 11283 10519 0 753 226629 0 290809

解释:

user(缩写 us)            代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。
nice(缩写 ni)          代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。
system(缩写 sys)       代表内核态 CPU 时间。
idle(缩写 id)          代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。
iowait(缩写 wa)        代表等待 I/O 的 CPU 时间。
irq(缩写 hi)           代表处理硬中断的 CPU 时间。
softirq(缩写 si)       代表处理软中断的 CPU 时间。
steal(缩写 st)         代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。
guest(缩写 guest)      代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。
guest_nice(缩写 gnice) 代表以低优先级运行虚拟机的时间。 特殊行解释: intr 这行展示系统中断的信息,第一个为自系统启动依赖,发生的所有中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。 ctxt 这行展示自系统启动以来CPU发生的上下文交互的次数 btime 这行展示从系统启动到现在为止的时间(以UTC时间开始计算,单位为秒) processes 这行展示自系统启动以来所创建的任务的个数 procs_runnig 这行显示当前运行队列的任务数目 procs_blocked 这行显示当前被阻塞的任务数目 spftirq 这行显示软中断的情况

脚本主体

[root@135 27_cpu_info]# cat cpu_info.sh 
#!/bin/bash
#获取当前CPU的性能数据
integrated_data(){
  #定义字符颜色
  red_c='\033[31m'
  gre_c='\033[32m'
  yel_c='\033[33m'
  blu_c='\033[34m'
  title_c='\033[35m'
  end_c='\033[0m'


  #获取间隔一秒的CPU性能数据文件。
  old_data_m=`cat /proc/stat`  
  sleep 1
  new_data_m=`cat /proc/stat`
  old_data=`echo "$old_data_m"|awk '/cpu\>/'`  
  new_data=`echo "$new_data_m"|awk '/cpu\>/'`  


  #获取CPU总时间
  total_time_old=`echo "$old_data "|awk '{for(i=2;i<=NF;i++){sum+=$i}}END{print sum}' `
  total_time_new=`echo "$new_data "|awk '{for(i=2;i<=NF;i++){sum+=$i}}END{print sum}' `
  let total_time=${total_time_new}-${total_time_old}

  #echo "老数据总时间:$total_time_old"
  #echo "新数据总时间:$total_time_new"
  #echo "总时间:$total_time"

  #计算CPU使用率
  idle_old=`echo "$old_data "|awk '{printf $5}' `  
  idle_new=`echo "$new_data "|awk '{printf $5}' `  
  let idle=${idle_new}-${idle_old}
  let cpu_usage_per=100*$idle/$total_time

  #echo "老空闲时间:$idle_old"
  #echo "新空闲时间:$idle_new"
  #echo "空闲时间:$idle"
  

  #队列信息
  r_q_num=`echo "$new_data_m"|awk '/procs_running\>/{printf $2}'`
  b_q_num=`echo "$new_data_m"|awk '/procs_blocked\>/{printf $2}'`

  #如果cpu空闲大于90则输出绿色字体,如果大于50则输出黄色字体,其他情况输出红色字体。
  if [ $cpu_usage_per -gt 90 ];then
     font_c=$gre_c
  elif [ $cpu_usage_per -gt 50 ];then
     font_c=$yel_c
  else
     font_c=$red_c
  fi


  #输出信息
  echo -e "${title_c}------------CPU------------${end_c}"
  echo -e "CPU空闲率为: ${font_c}$cpu_usage_per% ${end_c}"
  echo -e "当前运行队列:${blu_c}$r_q_num ${end_c}"
  echo -e "当前阻塞队列:${blu_c}$b_q_num ${end_c}\n"

}


#主函数
main(){
  integrated_data
}

#调用主函数
main

结果

CPU使用率高

CPU使用率低

**************************************************************************************************************2021年2月22日脚本结束*****************************************************************************************************************

 

21年2月23日-磁盘性能获取脚本

************************************************************************************************************************************************************************************************************************************

脚本说明

脚本读取/proc/diskstats文件,整理获取所有磁盘当前使用情况。适用于多种操作系统。

占坑。

文件说明

disk_io_info.sh:脚本主体文件

配置文件

#rhel8及4.18内核以上版本比其他的会多4列,平常的io计算中不会用到。
[root@135 28_disk_io_info]# awk  '$3~/[svx]d[a-z]$/{print}' /proc/diskstats
   8       0 sda 4247 38 384134 1869 759 259 77160 927 0 2883 798 0 0 0 0
   8      16 sdb 352 0 16640 77 168 48 3213 214 0 324 142 0 0 0 0
   8      32 sdc 414 13 16234 86 3 0 4104 8 0 117 18 0 0 0 0
   8      48 sdd 268 0 13558 44 2 0 4096 11 0 82 18 0 0 0 0
   8      64 sde 176 0 13234 24 1 0 8 4 0 56 4 0 0 0 0

#rhel6数据展示
[root@oracle_pref ~]# awk  '$3~/[svx]d[a-z]$/{print}' /proc/diskstats
   8       0 sda 18294 25 1063344 10154 6620 2298 234816 6234 0 10553 16359
   8      16 sdb 373 0 2848 76 143 2 1192 166 0 159 242

解释:

第4列           读完成次数 ----- 读磁盘的次数,成功完成读的总次数。
第5列           合并读完成次数, 第6个域:合并写完成次数。为了效率可能会合并相邻的读和写。从而两次4K的读在它最终被处理到磁盘上之前可能会变成一次8K的读,才被计数(和排队),因此只有一次I/O操作。这个域使你知道这样的操作有多频繁。
第6列           读扇区的次数,成功读过的扇区总次数。
第7列           读花费的毫秒数,这是所有读操作所花费的毫秒数(用__make_request()到end_that_request_last()测量)。
第8列           写完成次数 ----写完成的次数,成功写完成的总次数。
第9列           合并写完成次数 -----合并写次数。
第10列           写扇区次数 ---- 写扇区的次数,成功写扇区总次数。
第11列           写操作花费的毫秒数  ---  写花费的毫秒数,这是所有写操作所花费的毫秒数(用__make_request()到end_that_request_last()测量)。
第12列           正在处理的输入/输出请求数 -- -I/O的当前进度,只有这个域应该是0。当请求被交给适当的request_queue_t时增加和请求完成时减小。
第13列          输入/输出操作花费的毫秒数  ----花在I/O操作上的毫秒数,这个域会增长只要field 9不为0。
第14列          输入/输出操作花费的加权毫秒数 -----  加权, 花在I/O操作上的毫秒数,在每次I/O开始,I/O结束,I/O合并时这个域都会增加。这可以给I/O完成时间和存储那些可以累积的提供一个便利的测量标准。

脚本主体

[root@135 28_disk_io_info]# cat hello_word.sh 
#!/bin/bash
echo -e "\n\033[31m=============================="
echo -e "\033[32mhello word !"
echo -e "\033[31m==============================\033[0m\n"

结果

现在还没找到如何通过/proc/diskstats文件计算出io性能,先占个位。

**************************************************************************************************************2021年2月23日脚本结束*****************************************************************************************************************

 

21年2月24日-docker镜像版本显示

************************************************************************************************************************************************************************************************************************************

脚本说明

脚本获取用户输入的镜像名称在dockerhub中列出所有该镜像的版本,用户可以根据版本号获取到自己对应版本的镜像。

用户先使用dockers search 镜像获取到所有相关镜像的镜像仓库。

脚本使用步骤:

  第一步:执行  docker  search  镜像名  如:docker search httpd

  第二步:执行脚本,脚本文件后一定要跟第一步查出来的镜像名。

文件说明

docker_image_list.sh:脚本主体文件

脚本主体

[root@135 29_docker_image_list]# cat docker_image_list.sh 
#!/bin/bash
get_all_version(){
  repo_url=https://registry.hub.docker.com/v1/repositories
  image_name=${1:-null}
  if [ $image_name == 'null' ];then
    echo "大哥下次您还是输入点啥吧,谢谢!!!"
    exit 99
  fi
  echo -e  "\nInput values:  \033[34m$1\033[0m"
  echo -e  "Display \033[34m$image_name\033[0m version list\n"
  
  echo -e "The generated image pull command is as follows: \033[32m"
  curl -s ${repo_url}/${image_name}/tags|  sed 's#\}\,#\n#g' | awk -F':' '{print $NF}' | sed  -e 's#\"##g' -e 's# ##g'  | awk 'BEGIN{OFS=""}{print "docker pull  '$image_name':",$1}'
  echo -e "\033[0m"
}


#调用函数
get_all_version $1

结果

执行docker search httpd结果

 

 执行脚本结果

 

**************************************************************************************************************2021年2月24日脚本结束*****************************************************************************************************************

 

21年2月25日-docker安装脚本

************************************************************************************************************************************************************************************************************************************

脚本说明

在可以连接到互联网的设备上执行该脚本实现自动配置yum源安装docker并初始化docker环境,自动pull一个镜像下来测试docker是否安装成功。

在使用脚本时可以手动指定docker-ce版本默认情况下是最新版。

文件说明

auto_install_docker.sh:脚本主体文件

脚本主体

[root@136-b 30_auto_install_docker]# cat auto_install_docker.sh 
#!/bin/bash
#该安装脚本只适用于rhel系列的操作系统,官方也有自动安装脚本
#https://get.docker.com
#https://get.daocloud.io/docker
#执行命令如下:
#1.curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
#2.curl -sSL https://get.daocloud.io/docker | sh


#检查环境,设置yum源
check_and_init_env(){
  #判断是否存在docker容器,通过是否有命令来判断
  if which docker &>/dev/null;then
    echo  -e "\033[31mWaring: Docker Container installed !!!!!\033[0m"
    exit 99
  fi  


  #backup repo file
  mkdir -p /etc/yum.repos.d/install_docker_begin_bakcup
  mv /etc/yum.repos.d/* /etc/yum.repos.d/install_docker_begin_bakcup &> /dev/null
  

  #截取系统版本号
  version=`awk -F '=' '/VERSION_ID=/{print $2 }' /etc/os-release  | sed 's#\"##g' | awk -F'.' '{print $1}'`
  

  #配置repo文件,使用的是清华大学的源谢谢。
  > /etc/yum.repos.d/system_base.repo
  > /etc/yum.repos.d/docker-ce.repo
  if [ $version -eq 6 ];then      
    echo "System is 6, not install。"      
  elif  [ $version -eq 7 ];then
    echo -e "System is 7。\n"
    echo -e '[System_Base] \nname=System_Base \nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/7/os/x86_64/ \nenabled=1 \ngpgcheck=0' >> /etc/yum.repos.d/system_base.repo
  elif  [ $version -eq 8 ];then
    echo "System is 8。\n"
    echo -e '[System_Base] \nname=System_Base \nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/8/BaseOS/x86_64/os/ \nenabled=1 \ngpgcheck=0' >> /etc/yum.repos.d/system_base.repo
    echo -e '[System_AppStream] \nname=System_AppStream \nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/8/AppStream/x86_64/os/ \nenabled=1 \ngpgcheck=0' >> /etc/yum.repos.d/system_base.repo
  fi


  > /etc/yum.repos.d/docker-ce.repo
  echo -e '[docker-ce-stable] \nname=Docker-stable \nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/$releasever/$basearch/stable \nenabled=1 \ngpgcheck=0' >>/etc/yum.repos.d/docker-ce.repo
  echo -e '[docke-edge] \nname=Docker-edge \nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/$releasever/$basearch/edge \nenabled=1 \ngpgcheck=0' >>/etc/yum.repos.d/docker-ce.repo
  echo -e '[docker-nightly] \nname=docker-nightly \nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/$releasever/$basearch/nightly \nenabled=1 \ngpgcheck=0' >>/etc/yum.repos.d/docker-ce.repo
  echo -e '[docker-test] \nname=Docker-test \nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/$releasever/$basearch/test \nenabled=1 \ngpgcheck=0' >>/etc/yum.repos.d/docker-ce.repo
  
  echo -e "\033[34m"
  if yum clean all && yum repolist;then
    echo -e "\033[32mInfo: yum repofile configuration successful.\033[0m"
  else
    echo -e "\033[31mError: yum repofile configuration failed.\033[0m"
    exit 77
  fi


}

#安装docker软件
install_docker(){
  #使用yum源安装docker-ce
  #保存清单文件,待会从屏幕接受用户的信息选择对应的版本安装。
  version_list=`yum list docker-ce --showduplicates | grep '^docker' | sort -r  | awk '{print NR,$0}'`
  echo -e '\033[34mAll docker version list:\033[36m'
  echo -e "$version_list\033[0m"
  read -p "Please chose you Version to be installed,Fill in the corresponding numbers,Default stable version.: " input_n

  echo "Your input nuber values: $input_n"
  
  
  if [ ! ${input_n} ];then
    input_n=`yum list docker-ce --showduplicates | grep '^docker' | sort -r  | awk '{print NR,$0}' |grep stable | awk 'NR==1{printf $1}'`
    echo -e "\033[33mUser not input values,default chose number: ${input_n}\033[0m"
  fi

  echo "测试节点1"
  #获取到对应的版本
  docker_v=`echo "${version_list}"|awk -v var=$input_n '$1==var{printf $3}'|awk -F':' '{printf $2}'`

  #安装containerd.io
  echo "测试节点2" 


  #测试安装containerd软件
  if rpm -qa | grep -i containerd &>/dev/null || yum install containerd.io -y ;then
    echo -e "\033[32mcontainerd软件安装完成或已经安装\033[0m"
    docker_r=0
  else
    echo -e "\033[31mcontainerd软件安装失败\033[0m"
    docker_r=1
  fi


  #安装docker-ce
  yum install docker-ce-${docker_v} -y
  if [ $? -eq 0 ];then
    echo -e '\033[32mdocker-ce install successful.\033[0m'
    docker_r=0
  else
    echo -e '\033[31mdocker-ce install failed.\033[0m'
    docker_r=1
  fi

  #安装docker-ce-cli
  if rpm -qa docker-ce-cli &>/dev/null || yum install docker-ce-cli-${docker_v} -y ;then
    echo -e '/033[32mdocker-ce-cli install successful./033[0m'
    docker_c_r=0
  else
    echo -e '/033[31mdocker-ce-cli install failed./033[0m'
    docker_c_r=1
  fi

  #判断次安装命令是否执行成功。
  if [ $docker_r -eq 0 ] && [ $docker_c_r -eq  0 ];then  
    echo -e "\033[32mInfo:Docker install successful.\033[0m"
  else
    echo -e "\033[31mError:Dockerinstall failed.\033[0m"
  fi
 
  #判断软件是否存在于系统中,再次确认谨慎点好
  soft_num=`rpm -qa  |grep docker |wc -l`
  if [  ${soft_num} -ge 2 ];then
    echo -e "\033[32mInfo:Check again Docker install successful.\033[0m"
  else
    echo -e "\033[31mError:Check again Dockerinstall failed.\033[0m"
  fi
}


#初始化docker容器,加入到开机启动项,设置镜像仓库加速,并启动docker软件
init_docker(){
  #再次判断是否有docker软件
  soft_num=`rpm -qa  |grep docker |wc -l`
  if [  ${soft_num} -lt 2 ];then
    echo -e "\033[31mDocker 软件是否安装?\033[0m"
    exit 88
  fi


  #开机启动
  systemctl  enable  docker
   
  #添加daemon文件
  if [ -f /etc/docker/daemon.json ];then
    cp -rp /etc/docker/daemon.json /etc/docker/daemon.json.bak
  fi
  echo -e '{\n"registry-mirrors": ["https://sdmy9bft.mirror.aliyuncs.com"]\n}' > /etc/docker/daemon.json
  systemctl  daemon-reload

  #启动软件
  echo "测试节点3"
  systemctl  restart docker
  echo "测试节点4"
}


#使用命令拉取一个busybox镜像下来输出一个hello word命令
test_docker(){
  systemctl  status docker &>/dev/null
  if [ ! $? -eq 0 ];then
    echo -e "\033[31mdocker服务运行异常,不进行容器测试操作。\033[0m"
    exit 99
  fi

  docker_name=`date +"%k"`
  
  if docker pull busybox &>/dev/null;then
    echo -e "\033[32m镜像拉取成功,哈哈。\033[0m"
    docker run --name  test_${docker_name:-test}  busybox echo "hello word!"
    if [ $? -eq 0 ];then
      echo -e "\033[32m测试运行镜像成功,哈哈。\033[0m"
      docker rm test_${docker_name:-test} &>/dev/null
    else
      echo -e "\033[31m测试运行镜像失败,哈哈。\033[0m"
    fi
  else
    echo -e "\033[31m镜像拉取失败,哈哈。\033[0m"

  fi
}



main(){
#按实际需求选择启用对应的函数,不使用的使用#号注释掉. check_and_init_env install_docker init_docker test_docker } main

结果

环境中没有docker

docker软件已安装

**************************************************************************************************************2021年2月25日脚本结束*****************************************************************************************************************

posted @ 2021-02-19 14:11  飞翔的小胖猪  阅读(69)  评论(0编辑  收藏  举报