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日脚本结束*****************************************************************************************************************