Linux程序设计环境 实验1《Linux常用命令和Shell编程》

Linux程序设计环境 实验1《Linux常用命令和Shell编程》

一、实验内容

1、脚本一 monitor.sh

脚本代码

#!/bin/bash
# 设置正常屏幕输出
reset_terminal=$(tput sgr0)
# 声明一个数组
declare -A script_array
# 声明并初始化循环控制变量i
i=1
# 声明并初始化提示信息变量tips
tips=""

# 循环遍历当前目录下其他文件
for script_file in `ls -I "monitor.sh" ./`
do
        # 用紫色加粗字体输出前一段,输出可供选择的脚本名称及其代号
        echo -e '\e[1;35m' "The Script:" ${i} '=>' ${reset_terminal} ${script_file}
        # 将脚本名字存入数组
        script_array[$i]=${script_file}
        # 更新变量值
        tips="${tips} | ${i}"
        # 迭代变量+1进行迭代
        i=$((i+1))
done

# 开启另一个循环
while true
do
        # 提示输入一个选择
        read -p "Please input a number [${tips}] (0:exit): " choice
        # 判断输入的是否为数字
        if [[ ! ${choice} =~ ^[0-9]+ ]]; then
                # 非数字,输出错误信息
                echo "The input choice is not a Number!!!"
        else
                # 如果输入0
                if [ ${choice} -eq 0 ]; then
                        # 输出Bye Bye
                        echo "Bye Bye"
                        # 退出执行脚本
                        exit 0
                # 如果输入的数字不在1-3内
                elif [ ${choice} -lt 1 ] || [ ${choice} -gt 3 ]; then
                        # 提示输入1-3的数字
                        echo "Please input a number between 1 and 3!!!"
                else
                        # 如果输入的数字在1-3内,执行数字代表的脚本
                        /bin/bash ./${script_array[$choice]}
                fi
        fi
done

运行截图

初始运行:

Linux程序设计环境 实验1《Linux常用命令和Shell编程》_第1张图片

输入0并按下“Enter”键,退出:

Linux程序设计环境 实验1《Linux常用命令和Shell编程》_第2张图片

2、脚本二 system_info.sh

脚本代码

#!/bin/bash

# 刷新屏幕(但是不会清除之前的内容)
clear

# 判断运行脚本时是否没有传入参数
if [[ $# -eq 0 ]]; then
        # uname是用于显示系统信息的一个命令
        # 获取操作系统信息
        os=$(uname -o)
        # 输出操作系统信息
        echo -e "OS Type: "$os
        # 获取操作系统版本
        os_version=$(cat /etc/centos-release)
        # 输出操作系统版本
        echo -e "OS Version: "$os_version
        # 获取系统架构(x86_x64)
        architecture=$(uname -m)
        # 输出系统架构
        echo -e "Architeture: "$architecture
        # 获取内核信息
        kernel=$(uname -r)
        # 输出内核信息
        echo -e "OS Kernel: "$kernel
        # 获取主机名称
        hostname=$(uname -n)
        # 输出主机名称
        echo -e "Hostname: "$hostname
        # 获取主机所有ip地址并输出
        internal_ip=$(hostname -I)
        echo -e "Internal IP: "$internal_ip
        # 获取主机的对外ip地址并输出
        external_ip=$(curl -s http://ip.3322.net)
        echo -e "External IP: "$external_ip
        # 使用正则表达式获取dns,本机域名并输出
        dns=$(cat /etc/resolv.conf | grep -E "\|awk '{print $NF}')
        echo -e "DNS: "$dns
        # 测试当前网络是否连通,忽略输出信息(/dev/null黑洞)
        ping -c 2 baidu.com &>/dev/null && echo "Internet Connected" || echo "Internet Disconnected"
        # 将登陆者的信息保存至/tmp/who
        who>/tmp/who
        # 打印登陆者信息
        echo -e "Logged In Users..." && cat /tmp/who
        # 删除上面保存的临时信息文件
        rm -f /tmp/who

        # 获取系统使用的内存情况并输出
        system_memory_usages=$(awk '/MemTotal/{total=$2}/MemFree/{free=$2}END {print (total-free)/1024}' /proc/meminfo)
        echo -e "System Memory Usages: "$system_memory_usages
        # 获取应用程序使用的内存情况并输出
        app_memory_usages=$(awk '/MemTotal/{total=$2}/MemFree/{free=$2}/^Cache/{cached=$2}/Buffers/{buffers=$2}END {print (total-free-cached-buffers)/1024}' /proc/meminfo)
        echo -e "Applications Memory Usages: "$app_memory_usages
        # 获取cpu负载情况(平均负载、资源占用等)并输出
        cpu_load_average=$(top -n 1 -b | grep "load average:" | awk '{print $10 $11 $12}')
        echo -e "CPU Load Average: "$cpu_load_average
        # 获取磁盘的使用情况并输出
        disk_usages=$(df -hP | grep -vE 'Filesystem|tmpfs' | awk '{print $1 " " $5}')
        echo -e "Disk Usages: "$disk_usages
fi

运行截图

上述运行monitor.sh的基础上输入3并按下“Enter”键:

Linux程序设计环境 实验1《Linux常用命令和Shell编程》_第3张图片

3、脚本三 app_info.sh

脚本代码

#!/bin/bash

# 输出一句话
echo "This is app_info.sh"
# 创建一个变量nginx_server,并为其赋值为nginx服务器地址
nginx_server='http://192.168.31.5'
# 创建变量mysql_server并赋值为mysql服务地址
mysql_server='192.168.31.5'

# 声明一个函数用于查看nginx状况
Nginx_info(){
        # 通过curl命令请求nginx服务器并获取状态码,将结果即状态码赋值给status_code
        # 这里-m限制最长请求时长为5s,-s减少其他信息(如进度)的输出,-w在成功后输出状态码,测试url是否正常
        status_code=$(curl -m 5 -s -w %{http_code} http://192.168.31.5/nginx_status -o /dev/null)
        # 判断状态码为000或者大于500
        if [ $status_code -eq 000 -o $status_code -ge 500 ]; then
                # 打印错误信息
                echo -e "Check Nginx Server Error!!!"
                # 打印获取的状态码
                echo -e "Response Status Code is : " $status_code
        else
                # 打印成功信息
                echo -e "Check Nginx Server OK!"
                # 将nginx服务器运行成功的网页信息保存至 /tmp/nginx_status
                curl -s http://192.168.31.5/nginx_status > /tmp/nginx_status
                # 显示上面保存的文件
                cat /tmp/nginx_status
                # 将上面的临时文件强制删除
                rm -f /tmp/nginx_status
        fi
}

# 声明一个函数,用于获取mysql的相关运行信息
MySQL_info(){
        # 侦听192.168.31.5:3306 并将输出重定向到无底洞,不进行显示,限制时长2s,扫描时不发送任何数据
        nc -z -w2 ${mysql_server} 3306 &> /dev/null
        # 判断上一条命令的退出状态
        if [ $? -eq 0 ]; then
                # 上一条语句3306端口正常访问,输出访问正常信息
                echo -e "Connect MySQL Server ${mysql_server}:3306 OK!"
                # 先用账号密码登陆mysql,执行sql语句后获取Uptime信息
                mysql_uptimes=$(mysql -uroot -p123456 -hlocalhost -e "show status" 2>/dev/null | grep 'Uptime' | head -1 | awk '{print $2}')
                # 输出mysql更新时间,即Uptime
                echo -e "MySQL Uptime: "$mysql_uptimes
        else
                # 3306访问不正常,输出错误信息
                echo -e "Connect MySQL Server ${mysql_server}:3306 Failure!"
        fi
}
# 执行上述定义的两个函数
Nginx_info
MySQL_info

运行截图

上述运行monitor.sh的基础上输入1并按下“Enter”键:

Linux程序设计环境 实验1《Linux常用命令和Shell编程》_第4张图片

4、脚本四 log_info.sh

脚本代码

#!/bin/bash

# 输出一句话
echo "This is log_info.sh"
# 将nginx的日志文件地址保存在变量logfile_path中
logfile_path='/usr/local/nginx/logs/access.log'

# 定义一个函数用于统计各个区间的状态码的个数以及状态码总数
Get_http_status()
{
        # 通过正则表达式获取一系列包含状态码的信息,使用awk分割出一个个的状态码,统计区间里的状态码个数,保存到变量i,j,k,m,n中,最后形成数组http_status_codes
        http_status_codes=(`cat ${logfile_path} | grep -ioE "HTTP\/1\.[1|0]\"[[:blank:]][0-9]{3}" | awk '{
                if($2>=100&&$2<200)
                        {i++}
                if($2>=200&&$2<300)
                        {j++}
                if($2>=300&&$2<400)
                        {k++}
                if($2>=400&&$2<500)
                        {m++}
                if($2>=500)
                        {n++}
                }END{print i?i:0,j?j:0,k?k:0,m?m:0,n?n:0,i+j+k+m+n}' `)

        # 输出上述统计结果
        echo -e "The counter http status[100+]: "${http_status_codes[0]}
        echo -e "The counter http status[200+]: "${http_status_codes[1]}
        echo -e "The counter http status[300+]: "${http_status_codes[2]}
        echo -e "The counter http status[400+]: "${http_status_codes[3]}
        echo -e "The counter http status[500+]: "${http_status_codes[4]}
        echo -e "The counter http status[ALL]: "${http_status_codes[5]}
}
# 定义一个函数
Get_http_codes()
{
        # 通过正则表达式和awk命令统计404和500的数量并计算所有状态码的总数
        http_codes=(`cat ${logfile_path} | grep -ioE "HTTP\/1\.[1|0]\"[[:blank:]][0-9]{3}" | awk -v total=0 '{
                if($2!="")
                        { code[$2]++; total++ }
                else
                        { exit }
                }END{print code[404]?code[404]:0,code[500]?code[500]:0,total}' `)

        # 输出上述统计结果
        echo -e "The Counter of 404: " ${http_codes[0]}
        echo -e "The Counter of 500: " ${http_codes[1]}
        echo -e "The Counter of All Requests: " ${http_code[2]}
}
# 调用上述写好的两个函数
Get_http_status
Get_http_codes

运行截图

上述运行monitor.sh的基础上输入2并按下“Enter”键:

Linux程序设计环境 实验1《Linux常用命令和Shell编程》_第5张图片

二、实验总结

由于实验之前已经对ppt上的一些范例代码进行了编写,因此犯的低级错误不多,但是还是有。从编写完毕到成功运行脚本中途遇到的问题以及解决方式有如下几个:

1、运行system_info.sh的时候,一直卡在external_ip的输出那里,之前的输出正常。一开始以为是代码敲错了,检查代码无误后感觉应该是指导书中给出的网址——http://ipecho.net/plain有问题。直接访问发现超时,只有挂VPN使用域外IP进行访问才能成功,得知结果是返回当前主机对外(上网等)访问使用的IP地址,于是在网上找了一个可以直接访问的网址http://ip.3322.net进行代替解决了这个问题;

2、有好几个地方如ping命令、获取mysql_uptimes等,少打了一个空格或者多打了一个空格导致跑出来结果不对;

3、运行app_info.sh的时候,status_code的获取有问题,之后的nginx_status的结果也有问题。一开始觉得只有url中的主机地址不对,将其换为自己的地址之后前一个问题解决了,但是nginx_status还是获取不对。查资料之后发现先要对nginx的配置文件进行修改来开启运行状态(status)功能(前提是安装nginx的时候一并安装了nginx的Status模块)。修改配置文件:

在nginx安装目录/usr/local/nginx下编辑conf/nginx.conf文件,在server{……}中添加location节点:

location /nginx_status {
	stub_status on;    # 启用状态
	access_log off;    # 定义日志状态;建议为off
}

随后完成对nginx配置文件的语法检查(-t),并重新启动nginx(退出途中可能会报PID异常,可以使用killall nginx来强制杀死nginx进程,继续重启nginx就好了)、重新加载nginx配置:(注意当前终端是在/usr/local/nginx/sbin目录下)

./nginx –t
./nginx –s quit
./nginx
./nginx -s reload

如果使用nginx命令(如nginx -s reload),这里又会出来一个问题,即nginx命令找不到,原因是没有进行配置,可以对/etc/profile文件添加一个nginx的PATH并export即可。但是随后发现nginx … 的效果和./nginx …的效果是一样的,感觉资料白查了。需要注意的是./nginx的执行需要root权限;

4、获取mysql_uptimes的时候,忘记修改登录用户名和密码导致错误。并且注意到指导书给出的地址是192.168.xxx.xxx,即本机的地址,但是我们安装好mysql之后初始化的用户使用的是localhost,所以其中的-h192.168.xxx.xxx应该改成-hlocalhost,或者修改mysql的用户信息也可以。

你可能感兴趣的:(Linux程序设计环境,linux,shell,脚本语言)