目录

shell编程学习笔记

案例01:每次用户登录后显示系统基本信息

01_check_sys_cat.sh
下载
#!/bin/bash
##########################################
# File Name:01_check_sys_cat.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例01:每次用户登录后显示系统基本信息
###########################################

#1.vars变量
hostname=`hostname`
username=`whoami`
loadavg=`w | awk 'NR==1 {print$(NF-2),$(NF-1),$NF}'`
cpus=`lscpu | grep "CPU(s):" | awk 'NR==1 {print $2}'`
#procs=`top -bn1 | awk 'NR==2 {print $2}'`
procs=`ps -e --no-headers | wc -l`
zombies=`top -bn1 | awk 'NR==2 {print $(NF-1)}'`
#top_mem_processes=$(ps -eo %mem,comm --sort=-%mem | awk 'NR<=11 && NR>1 {print $2}')
#top_mem_processes=`top -bn1 -w 512 -o %MEM | awk 'NR>=8&&NR<13 {print $12}'` 显示内存占用前10但发现有重复值
top_mem_processes=`top -bn1 -w 512 -o %MEM | awk 'NR>=8&&NR<21 {print $12}' | uniq -c | awk '{print $NF}'`  #去重处理,只显示前13个进程中靠前的几个

mem_total=`free -h | awk 'NR==2 {print $2}'`
mem_sy=`free -h | awk 'NR==2 {print $NF}'`
swap_total=`free -h | awk 'NR==3 {print $2}'`
swap_sy=`free -h | awk 'NR==3 {print $NF}'`
ips=`hostname -I`
#实现登录时提示,切换用户不提示:判断两个变量是否存在,存在表示远程登陆,不存在就是切换用户
# 严格判断:只有 SSH 登录且父进程是 sshd 时才输出
if [ -n "$SSH_CLIENT" ] && [ -n "$SSH_TTY" ] && [ "$(ps -o comm= -p $PPID)" = "sshd" ]; then
cat<<EOF
主机名:$hostname
ip地址:$ips
用户名:$username
系统负载:$loadavg
CPU核心总数:$cpus
进程总数:$procs
僵尸进程数量:$zombies
内存大小/内存剩余:$mem_total $mem_sy
swap大小/swap剩余:$swap_total $swap_sy
Top 10 内存占用进程:
$top_mem_processes
EOF
else
   exit 1
fi
weather.sh
下载
#!/bin/bash
#curl -s wttr.in/longfeng?lang=zh | awk 'NR <= 17; END { print lines[40 - 2] } { lines[NR] = $0 }'


function redstrongecho(){
	input="$@"
	echo -e "\E[1;41m${input}\E[0m"
}
function greenstrongecho(){
	input="$@"
	echo -e "\E[1;42m${input}\E[0m"
}
#if [ -n "$SSH_CLIENT" ] && [ -n "$SSH_TTY" ] && [ "$(ps -o comm= -p $PPID)" = "sshd" ]
#then
redstrongecho "今天的天气是:"

curl -s wttr.in/Jiamusi?lang=zh | awk 'NR <= 17; END { print lines[40 - 2] } { lines[NR] = $0 }'
#else
#	exit 1
#fi

案例02:执行脚本时输入用户名判断用户名是否存在

02_check_user_exist.sh
下载
#!/bin/bash
##########################################
# File Name:02check_user_exist.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例02:执行脚本时输入用户名判断用户名是否存在
###############
############################

#1.vars
user=$1
#2.检查参数数量是否不为1,stop and exit
if [ $# -ne 1 ]
then
	echo "参数数量不对,请重新运行脚本!"
	echo "正确格式:sh *.sh username"
	exit 1
fi
#执行命令,下一步根据此处是否执行成功判断输出信息
id ${user} &>/dev/null
#3. id user--check
if [ $? -eq 0 ]
then
	echo "${user} is exist,detailed information:"
	id ${user}
else
	echo "${user} not exist"
fi

案例03:检查ip或域名是否可以访问

03_check_ip_connect.sh
下载
#!/bin/bash
##########################################
# File Name:03_check_ip_connect.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例03:检查ip或域名是否可以访问
###########################################
#1 vars
ip=$1
#2.检查参数数量是否不为1,stop and exit
if [ $# -ne 1 ]
then 
	echo "脚本参数数量不对,请输入1个ip或域名"
        echo "正确格式:sh *.sh ipaddress/domain name"
	exit 1
fi
#3执行命令,下一步根据此处是否执行成功判断输出信息
ping -c1 ${ip}  &>/dev/null
#4 judge $?
if [ $? -eq 0 ]
then
	echo "connected"
else
	echo "please check your net or input"
fi

案例04:shell中的位置变量$n,当n>9时怎么处理?-----${10} ${11}

04_test_arg.sh
下载
#!/bin/bash
##########################################
# File Name:04_test_arg.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例04:shell中的位置变量$n,当n>9时怎么处理?-----${10} ${11}
###########################################
echo $1 $2 $3... $9 ${10} ${11} ${12}

案例05:$#表示运行脚本时输入参数的个数,一般用于与判断结合 (检查输入参数的数量是否正确)

05_test_jing.sh
下载
#!/bin/bash
##########################################
# File Name:05_test_jing.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例05:$#表示运行脚本时输入参数的个数,一般用于与判断结合 (检查输入参数的数量是否正确)
###########################################
echo $1 $2 $3
echo $#

案例06:执行脚本输入1个或多个用户名通过脚本进行输出 (检查这些用户是否存在)

06_check_multi_users.sh
下载
#!/bin/bash
##########################################
# File Name:06_check_multi_users.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例06:执行脚本输入1个或多个用户名通过脚本进行输出 (检查这些用户是否存在)
###########################################
#1.vars
names="$@"

#2.检查脚本参数个数是否为0(输入是否为空),如果输入为空则退出
if [ $# -eq 0 ];then
	echo "please check your input"
	echo "help: sh  $0 user..."
	exit 1
fi

#3.for
for i in ${names}
do
	#用id命令检查用户是否存在
	id ${i} &>/dev/null
if [ $? -eq 0 ]
then
	id ${i}
else
	echo "$i is not exist"
fi
done

案例07:替代rm的回收站脚本

07_rm.sh
下载
#!/bin/bash
##########################################
# File Name:07_rm.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:替代rm的回收站脚本
###########################################

#1. 创建临时目录
tmp_dir=$(mktemp -d -p /tmp rm_sh_XXXXX)
input_dir="$1"  # 直接使用 $1 更简洁

#2. 校验输入非空
if [ -z "$input_dir" ]; then
    echo "错误:未提供目录参数!"
    exit 1
fi

#3. 解析绝对路径(使用 readlink -f 增强兼容性)
jueduipath=$(readlink -f "$input_dir" 2>/dev/null)
if [ $? -ne 0 ] || [ -z "$jueduipath" ]; then
    echo "failed: $input_dir is not exist"
    exit 1
fi

#4. 检查是否为根目录
if [ "$jueduipath" = "/" ]; then
    echo "this is /, stop your rm !"
    exit 1
fi

#5. 移动目标到临时目录
mv -- "$jueduipath" "$tmp_dir"
if [ $? -eq 0 ]; then
    echo "success save to $tmp_dir"
else
    echo "failed"
fi

案例10:通过脚本传参输入任何一个命令并执行,检查这个命令的执行结果是否正确

10_check_cmd.sh
下载
#!/bin/bash
##########################################
# File Name:10_check_cmd.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例10:通过脚本传参输入任何一个命令并执行,检查这个命令的执行结果是否正确
###########################################
#1.vars
cmd="$@"


#2.检查脚本参数个数是否为0(输入是否为空),如果输入为空则退出
if [ $# -eq 0 ]
then
	echo "error!!! please input correct command"
	echo "help: sh $0 cmd"
	exit 1
fi

#3.执行输入的命令,输出定向到空
$cmd &> /dev/null

#4.进行判断上一条命令的返回值,为0则成功
if [ $? -eq 0 ]
then
	echo "${cmd} success!"
else
	echo "${cmd} error!"
fi

案例11:for循环打印下面这一段话中字母数不大于6的单词

I am a teacher welcome to my home thanks everybody yes or no

11_calc_strings.sh
下载
#!/bin/bash
##########################################
# File Name:11_calc_strings.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例11:for循环打印下面这一段话中字母数不大于6的单词
###########################################

#I am a teacher welcome to my home thanks everybody yes or no
#1.vars
strs="I am a teacher welcome to my home thanks everybody yes or no"
num=6
#2.for
for str in $strs
do
	#begin if <= 6 echo $str
	if [ ${#str} -le $num ]
	then
		echo "$str"
	else
	       echo "$str" &>/dev/null	
	fi
done

案例12:书写脚本检查输入的域名(一个或多个)是否可以ping通--通过read命令实现

12_ping_url.sh
下载
#!/bin/bash
##########################################
# File Name:12_ping_url.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例12:书写脚本检查输入的域名(一个或多个)是否可以ping通--通过read命令实现
source /funcs/func_diy.sh
#调用个人函数库
###########################################
#1.vars:
read -t 40 -p "please input domains: " urls
#-t:40s内无输入则退出 -p:打印后面的提示信息
#2.检查变量是否为空
if [ -z $urls ];then
    echo "Help: 请输入1个或多个域名"
fi
#3.for
for i in ${urls}
do
	ping -c1 ${i} &>/dev/null
	if [ $? -eq 0 ]
	then
		redstrongecho "${i} is yes"
	else
		greenstrongecho "${i} is no"
	fi
done

案例13:计算器传入脚本中2个参数,进行计算,输出结果①命令行传参②read传参

13_num_calc.sh
下载
#!/bin/bash
##########################################
# File Name:13_num_calc.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例13:计算器传入脚本中2个参数,进行计算,输出结果  ①命令行传参
###########################################
#1.vars
num1=$1
num2=$2

#2.检查脚本参数个数是否为2,如果不为2则输出帮助信息并退出
if [ $# -ne 2 ]
then
	echo "help: sh $0 num1 num2"
	exit 3
fi
#3.检查输入的是否为数字
expr 1 + $num1 + $num2 &>/dev/null
if [ $? -ge 2 ]
then
	echo "sh $0 num1 num2"
	exit 1
fi
	
#使用awk计算加减乘除
jia=`awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1+n2}'`
jian=`awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1-n2}'`
cheng=`awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1*n2}'`
chu=`awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1/n2}'`
#4.按照两种格式输出运算结果
cat <<EOF
$num1 + $num2 = $jia
$num1 - $num2 = $jian
$num1 * $num2 = $cheng
$num1 / $num2 = $chu
EOF
echo "
$num1 + $num2 = $jia
$num1 - $num2 = $jian
$num1 * $num2 = $cheng
$num1 / $num2 = $chu"

#3.直接计算并输出
echo "$1 + $2=`echo $num1 + $num2 | bc -l`"
echo "$1 - $2=`echo $num1 - $num2 | bc -l`"
echo "$1 * $2=`echo "$num1 * $num2" | bc -l`"
echo "$1 / $2=`echo $num1 / $num2 | bc -l`"

echo "$1 + $2= `awk -v a=$num1 -v b=$num2 'BEGIN{print a+b}'`"
echo "$1 - $2= `awk -v a=$num1 -v b=$num2 'BEGIN{print a-b}'`"
echo "$1 * $2= `awk -v a=$num1 -v b=$num2 'BEGIN{print a*b}'`"
echo "$1 / $2= `awk -v a=$num1 -v b=$num2 'BEGIN{print a/b}'`"
14_num_calc_read.sh
下载
#!/bin/bash
##########################################
# File Name:13_num_calc_read.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例13:计算器传入脚本中2个参数,进行计算,输出结果  ②read传参
###########################################
#1.vars
read -p "please input two parmeters: " num1 num2

#检查脚本输入是否为空,最多有一个为空则退出
if [ -z "$num1" -o -z "$num2" ]
then
	echo "help: sh $0 num1 num2"
	exit 1
fi
#2.检查参数是否为数字
expr 1 + $num1 + $num2 &>/dev/null
if [ $? -gt 1 ]
then
	echo "error, need input two numbers"
	exit 2
fi

#3.进行计算
#使用 bc计算并直接输出结果
echo "$num1 + $num2= `echo $num1+$num2 | bc -l`"
echo "$num1 - $num2= `echo $num1-$num2 | bc -l`"
echo "$num1 * $num2= `echo $num1*$num2 | bc -l`"
echo "$num1 / $num2= `echo $num1/$num2 | bc -l`"
#使用 awk计算并输出
jia=`awk -v a=$num1 -v b=$num2 'BEGIN{ print a+b}'`
jian=`awk -v a=$num1 -v b=$num2 'BEGIN{print a-b}'`
cheng=`awk -v a=$num1 -v b=$num2 'BEGIN{print a*b}'`
chu=`awk -v a=$num1 -v b=$num2 'BEGIN{print a/b}'`
cat <<EOF
$num1 + $num2 = $jia
$num1 - $num2 = $jian
$num1 * $num2 = $cheng
$num1 / $num2 = $chu
EOF


案例17:通过脚本传参方式传输1个参数,判断是否为文 件,是否为目录,是否具有执行权限.(字符串比较)

17_check_file.sh
下载
#!/bin/bash
##########################################
# File Name:17_check_file.sh
# Version:V3.0
# Author:zhangpeng
# Organization:linuxjk.cn
# Desc: 检查是否为文件,是否为目录,是否具有执行权限.增强文件类型检测(支持软链接)
###########################################

# 参数检查
[ $# -ne 1 ] && { echo "用法: sh $0 文件/目录"; exit 1; }

file="$1"

# 存在性检查
[ ! -e "$file" ] && { echo "错误:$file 不存在!"; exit 1; }

# 类型检测(按检测顺序排序)
#如果软连接指向文件/目录,先检测-f/-d会检测软连接指向的那个文件/目录,所以先检测软连接
if [ -L "$file" ]; then
    type="软链接"
   # target=$(readlink -f "$file")
    
    # 检查目标文件权限
    if [ -x "$target" ]; then
        perm="目标文件有执行权限"
    else
        perm="目标文件无执行权限"
    fi
    
elif [ -f "$file" ]; then
    type="普通文件"
    [ -x "$file" ] && perm="有执行权限" || perm="没有执行权限"
    
elif [ -d "$file" ]; then
    type="目录"
    [ -x "$file" ] && perm="有执行权限" || perm="无执行权限"
    
else
    echo "$file 存在,但无法识别类型(可能是设备文件、管道文件等)"
    exit 1
fi

echo "$file 类型:${type},${perm}"
17_check_file_easy.sh
下载
#!/bin/bash
##########################################
# File Name:17_check_file_1.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:检查是否为文件,是否为目录,是否具有执行权限.(简化版)
###########################################

#1.vars
file=$1

#2.检查参数个数是否为1
[ $# -ne 1 ] && {
	echo "help: sh $0 file"
        exit 1
}
#3.-d 检查是否为目录
if [ -d $file ]
then
	echo "$file is dir"
else
	echo "$file is not a dir"
fi

#4.-f 检查是否为文件
if [ -f $file ]
then
	echo "$file is file"
else
	echo "$file is not a file"
fi
#5. -x 检查是否具有执行权限.
if [ -x $file ];then
		echo "$file has +x"
else
		echo "$file has not +x"
fi

#6.-L 检查是否为软连接
if [ -L $file ];then
	echo "$file is a softlink"
else
	echo "$file is not a softlink"
fi

案例18-检查selinux是否关闭脚本,如果没有关闭提示是否要关闭,yes则关闭,其他就不关闭

18_check_selinux.sh
下载
#!/bin/bash
##########################################
# File Name:18_check_selinux.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:检查selinux是否关闭,如果未关闭,提示是否要关闭,yes则关闭,其他就不关闭
###########################################
#1.vars
#/etc/selinux/config中显示的SELINUX=$perm
#getenforce显示的$temp

#2.取出配置文件/命令行中selinx的状态
#awk -F= '/^SELINUX=/ {print $2}' /etc/selinux/config
perm=`sed -nr '/^SELINUX=/p' /etc/selinux/config | awk -F= '{print $NF}'`
temp=`getenforce`
#3.判断字符串是否为空
if [[ -z "$perm"  ||  -z "$temp" ]]
then
	echo "无法获取selinux策略:请检查配置文件:/etc/selinux/config"
	exit 1
fi

#3.判断以上两个字符串是否同时等于disabled→→→selinux彻底关闭
if [[ "$perm" = "disabled" ]] &&  { [[ "$temp" = Disabled ]] ||  [[ "$temp" = Permissive ]] ;}
then
	echo "SELINUX 已经关闭"
	exit 1
else
	 
#4.此时需要用户输入是否要关闭,yes
        read -p "SELINUX未关闭,是否关闭selinux:关闭请输入yes:" input
	if [ "$input" = yes ];then
		sed -i "s#SELINUX=.*#SELINUX=disabled#g" /etc/selinux/config
		setenforce 0
		echo "已关闭selinux,重启生效"
		exit 1
	else
		echo "selinux is $temp"
		exit 1
	fi
fi
18_check_selinux_easy.sh
下载
#!/bin/bash
##########################################
# File Name:18.check_selinux_1.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例18-检查selinux是否关闭脚本,如果没有关闭提示是否要关闭,yes则关闭,其他就不关闭
###########################################
#1.vars
selinux_config=`awk -F= '/^SELINUX=/ {print $2}' /etc/selinux/config`
selinux_cmd=`getenforce`
#2 判断是否关闭
#两个条件同时成立在[]中需要使用-a,[ 条件1 -a 条件2 ]相当于[]&&[]或[[ 条件1 && 条件2 ]]
if [ "$selinux_config" = "disabled" -a "$selinux_cmd" = "Disabled" ]
then
	echo "SELINUX已经关闭"
else
	read -p "是否关闭selinux,请输入yes/no: " xuan
	if [ "$xuan" = "yes" ];then
		sed -i '/^SELINUX=/s#=.*#=disabled#g' /etc/selinux/config
		setenforce 0
		echo "关闭成功!"
	else
		echo "SELINUX 未关闭!"
	fi
fi

案例20: 书写一个脚本通过read读取输入,判断 输入是整数,浮点数(小数),还是字符.

20_check_type.sh
下载
#!/bin/bash
##########################################
# File Name:20_check_type.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例20: 书写一个脚本通过read读取输入,判断输入数据类型(整数/浮点/字符串)
###########################################

#1. 获取输入
read -p "pls input: " input

#2. 检查输入非空
if [ -z "$input" ]; then
    echo "error Help: sh $0 input"
    exit 1
fi

#3. 判断数据类型
if [[ $input =~ ^[+-]?[0-9]+$ ]]; then           # 整数(含正负)
    echo "zhengshu"
elif [[ $input =~ ^[+-]?[0-9]+\.[0-9]+$ ]]; then  # 浮点数(含正负)
    echo "fudian"
elif [[ $input =~ ^[a-zA-Z0-9]+$ ]]; then        # 纯字母数字组合字符串
    echo "str"
else
    echo "unknown data"
fi
exit 0

案例21: 书写服务检查脚本,执行的时候输入服务名字检查是否运 行,检查是否开启自启动.

21_check_service.sh
下载
#!/bin/bash
##########################################
# File Name: 21_check_service.sh
# Version: V1.1
# Author: zhangpeng
# Organization: linuxjk.cn
# Desc: 服务状态检查脚本
##########################################

# 1. 获取服务名称read -r禁用转义符
read -rp "Please input a service name: " service

# 2. 检查输入是否为空
if [ -z "$service" ]; then
    echo "Usage: sh $0 <service_name>"
    exit 1
fi

# 3. 检查服务是否存在--type确保只检查服务文件
# 直接通过 systemctl 查询(无需管道)
#if ! systemctl list-unit-files --type=service "$service.service" &>/dev/null
if ! systemctl list-unit-files --type=service | grep -qw "^$service.service"; then
    echo "Error: Service '$service' does not exist."
    exit 2
fi

# 4. 获取状态信息
run=$(systemctl is-active "$service")
auto=$(systemctl is-enabled "$service")

# 5. 判断逻辑优化
# 修正后的代码片段
#systemctl is-active "$service" &>/dev/null
#if [ $? -eq 0 ];then
#echo "$service is running"
#else
#echo "$service is running"
#fi
#和下面的格式不同效果一样:命令返回值为0则正确输出,不为0进入else,
#把命令放在if后的弊端:类似于expr那种成功的返回值为0或1 的命令不行
if systemctl is-active "$service" &>/dev/null
then
	echo "$service is running"
else
	echo "$service is not runing"
fi

if systemctl is-enabled "$service" &>/dev/null
then
	echo "$service is enabled"
else
	echo "$service is disenabled"
fi













#if [ "$run" = "active" ]; then
#    status1="running"
#else
#    status1="not running"
#fi

#if [ "$auto" = "enabled" ]; then
#    status2="enabled"
#else
#    status2="disabled"
#fi

#if [ "$run" = "active" ] && [ "$auto" = "enabled" ]; then
#    echo "$service is $status1, and $status2"
#elif [ "$run" = "active" ] && [ "$auto" != "enabled" ]; then
#    echo "$service is $status1"
#elif [ "$auto" = "disabled" ] && [ "$run" = "active" ]; then
#    echo "$service is $status2"
#else
#    echo "$service is not running and disabled"
#    exit 3
#fi
#exit 0

案例22:检查磁盘分区的情况

22_check_disk.sh
下载
#!/bin/bash
##########################################
# File Name:22_check_disk.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:检查磁盘分区情况1.有几个分区2.每个分区使用率,超过70%显示磁盘空间不足,没超过显示异常
###########################################
#1.vars
#分区数量
part_cnt=`egrep -v '^$|#|swap' /etc/fstab | wc -l`
#分区名字
part_names=`egrep -v '^$|#|swap' /etc/fstab | awk '{print $2}'`

#2.for 循环依次处理
for part  in $part_names
do
	size=`df -h $part | awk 'NR==2{print $2}'`
	uselv=`df -h $part | awk -F '[ %]+' 'NR==2{print $5}'`
	if [ "$uselv" -le 70 ]  ;then
	echo "$part 磁盘大小:$size,使用率: $uselv%,空间正常"
else
	echo "$part 磁盘大小:$size,使用率: $uselv%,空间不足!!!"
	let i++
	fi
done
echo "磁盘分区数量:$part_cnt"
echo "磁盘分区空间不足分区数量: ${i:-0}"

案例23:书写多分支格式比较大小脚本

23_num_compare.sh
下载
#!/bin/bash
##########################################
# File Name:23_num_compare.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:多分支格式比较两个数字大小
###########################################
#1.vars
read -p "请输入两个数字进行比较大小: " num1 num2
#2.判断输入是否为空
if [ -z $num1 ] || [ -z $num2 ]
then
	echo "Help: sh $0 num1 num2"
	exit 1
fi
#3.判断输入是否为数字
# expr 1 + $num1 + num2 &>/dev/null
#if [ $? -ge 2 ]
#	echo "请输入数字 格式:sh $0 num1 num2"
#	exit 2
#fi
#字符串比较是否为数字(繁琐)
if [[ ! $num1 =~ ^[+-]?[0-9]+(\.[0-9]+)?$ ]] || [[ ! $num2 =~ ^[+-]?[0-9]+(\.[0-9]+)?$ ]]
then
	echo "请输入数字 格式:sh $0 num1 num2"
	exit 2
fi

#4.比较大小
if [ $num1 -gt $num2 ];then
	echo "$num1 > $num2"
elif [ $num1 -lt $num2 ];then
	echo "$num1 < $num2"
else
	echo "$num1 == $num2"
fi

案例24:根据磁盘空间不同使用率设置不同的警告提示

24_check_disk.sh
下载
#!/bin/bash
##########################################
# File Name:22_check_disk.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:检查磁盘分区情况1.有几个分区2.每个分区使用率,根据不同使用率设置不同的警告提示
###########################################
#1.vars
#分区数量
part_cnt=`egrep -v '^$|#|swap' /etc/fstab | wc -l`
#分区名字
part_names=`egrep -v '^$|#|swap' /etc/fstab | awk '{print $2}'`


#2.for 循环依次处理
for part  in $part_names
do
	size=`df -h $part | awk 'NR==2{print $2}'`
	uselv=`df -h $part | awk -F '[ %]+' 'NR==2{print $5}'`
#根据不同使用率设置不同的警告提示
if [ $uselv -ge 60 ] && [ $uselv -le 70 ]
then
	msg="警告"
	let i++
elif [ $uselv -ge 70 ] && [ $uselv -le 80 ];then
	msg="严重"
	let i++	
elif [ $uselv -ge 80 ] && [ $uselv -le 90 ];then
	msg="故障"
	let i++
elif [ $uselv -ge 90 ] && [ $uselv -le 100 ];then
	msg="灾难"
	let i++
else
	msg="磁盘空间充足,利用率为 $uselv"
fi
echo "$part 大小:$size $msg%"

done
echo "磁盘分区数量:$part_cnt"
echo "磁盘空间不足分区数量:${i:-0}"

案例25:输出指定用户信息(用户巡检脚本),未来可以做安全检查

25_check_user.sh
下载
#!/bin/bash
##########################################
# File Name:25_check_user.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:用户巡检脚本,检查用户信息
###########################################

#一次检查一个用户
#1.vars
#read -p "请输入用户名:" user
#2.check -z
#[ -z $user ] && echo "Help: sh $0 username" && exit 1;
#3.check 输入的是否为用户名(用户是否存在)
#id $user &>/dev/null
#if [ $? -ne  0 ]
#then
#	echo "用户不存在"
#	exit 2
#fi
#


#一次检查多个用户
# 提示用户输入用户名(支持多个,空格分隔)
read -p "请输入要检查的用户名(多个用户名用空格分隔):" input_names

# 检查输入是否为空
if [[ -z "$input_names" ]]; then
    echo "错误:未提供任何用户名。" >&2
    exit 1
fi
# 将输入转换为数组(兼容多个空格/制表符分隔)
names=($(echo "$input_names" | tr -s ' '))  # tr -s ' ' 压缩连续空格
#1.vars
names=("$@")  # 声明为数组
# 检查参数数量
if [ $# -eq 0 ]; then
    echo "错误:请提供至少一个用户名作为参数。"
    echo "用法:bash $0 用户名1 用户名2 ..."
    exit 1
fi

for name in "${names[@]}"; do  # 正确遍历数组
    if id "${name}" &>/dev/null; then
        echo "用户 ${name} 存在。"
        # 获取用户信息
        passwd_entry=$(getent passwd "${name}")
        perm=$(awk -F: '{print $NF}' <<<"$passwd_entry")
        [[ "$perm" == "/bin/bash" || "$perm" == "/bin/zsh" ]] && login="可以登录" || login="不可以登录"
        uid=$(id -u "${name}")
        gid=$(id -g "${name}")
        homedir=$(awk -F: '{print $(NF-1)}' <<<"$passwd_entry")
        situation=$(lastlog -u "${name}")

        # 输出用户信息
	echo "正在检查用户:$name"
echo "----------------------------------------"
        cat <<EOF
用户 ${name} 的详细信息:
- 登录权限:${login}
- UID:${uid}
- GID:${gid}
- 家目录:${homedir}
- 最近登录情况:
${situation}
EOF
echo "========================================"
    else
        echo "错误:用户 ${name} 不存在。"
    fi
done

案例26:case语句格式–菜单选择功能

26_taocan.sh
下载
#!/bin/bash
##########################################
# File Name:26_taocan.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例26:case语句格式–菜单选择功能
###########################################
#1.输出信息供用户选择
cat <<EOF
- 1 138套餐) 吃饱套餐
- 2 443套餐) 吃饱喝足套餐
- 3 888套餐) 吃喝拉撒套餐
- 4 1688套餐) 你想干啥就干啥套餐
EOF
read -p "请选择套餐: " taocan
case "$taocan" in
	1)
		echo "in 1"
		;;
	2)echo "in 2" ;;
	3)echo "in 3" ;;
	4)echo "in 4" ;;
	5)echo "in 5" ;;
	*)echo "error pls run again"
esac

案例27:判断用户输入的是yes还是no(选项中| 的使用)

27_yes_no.sh
下载
#!/bin/bash
##########################################
# File Name:27_yes_no.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例27:判断用户输入的是yes还是no(case菜单选项中| 的使用)
###########################################
read -p "please input yes or no: " yesno
case "$yesno" in
#)前可以用|分割多个同义词,结果都指向)后执行的操作
	yes|Yes|y|Y) echo yes;;
	no|n|N|No) echo no;;
	*) echo ???
esac

案例28:函数基本格式及使用

28_test_func.sh
下载
#!/bin/bash
##########################################
# File Name:28_test_func.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例28:函数基本格式及使用
###########################################
function show() {
echo "welcome to oldboy linux lidao996 class"
echo "你的目标:拿下15k offer"
echo "你的目标:拿下100+ shell脚本"
echo "你的目标:书写总共超过5000行脚本。"
return 0
}
show
#这行表示运行上面刚定义的show函数,作用同下面这种
#function main(){
#    show
#}
#main

案例29:函数传参的使用

29_show_test.sh
下载
#!/bin/bash
##########################################
# File Name:29_show_test.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例29:函数传参的使用
###########################################
function show() {
cat <<EOF
show函数的参数个数:$#
show函数的所有参数:$*
$1.com
$1.cn
$1.org
$1.企业
$1.icu
$1.我爱你
EOF
}
show $*
#使用方法:运行脚本时 sh 29_show_test.sh a b c d e
#命令行传参到函数外部show $* 函数内部$n调用此参数
#显示如下:
#show函数的参数个数:5
#show函数的所有参数:a b c d e
#a.com
#a.cn
#a.org
#a.企业
#a.icu
#a.我爱你

案例30:已有脚本函数化:检查ip是否能访问,将每一步设置为一个函数

30_check_ip_func.sh
下载
#!/bin/bash
##########################################
# File Name:10_ping_url.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例30:已有脚本函数化
###########################################


#1.vars:
function input_urls(){
read  -p "please input domains: " urls
}
#2.检查参数是否为空
function check_urls(){

if [ -z "$urls" ];then
	echo "Help: sh $0 ip/domains"
	exit 1
fi
}
#2.执行ping命令并判断返回值检测此域名是否能ping通
function ping_if(){
	ping -c1 ${url} &>/dev/null
	if [ $? -eq 0 ]
	then
		echo "${url} is yes"
	else
		echo "${url} is no"
	fi
}
#3.for
function for_urls(){
for url in ${urls}
do
	ping_if
done
return 0
}

#4.运行上面的函数
function main(){
input_urls
check_urls
for_urls
}
main

案例31:个人颜色函数库搭建,不同显示效果用不同的函数表示

31_color_func.sh
下载
#!/bin/bash
##########################################
# File Name:31_color_func.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例31:个人颜色函数库搭建,不同显示效果用不同的函数表示
###########################################
function redecho(){
	input="$@"
	echo -e "\E[1;31m${input}\E[0m"
}
function greenecho(){
	input="$@"
	echo -e "\E[1;32m${input}\E[0m"
}
function blueecho(){
	input="$@"
	echo -e "\E[1;36m${input}\E[0m"
}
function yellowecho(){
	input="$@"
	echo -e "\E[1;33m${input}\E[0m"
}

function redstrongecho(){
	input="$@"
	echo -e "\E[1;41m${input}\E[0m"
}
function greenstrongecho(){
	input="$@"
	echo -e "\E[1;42m${input}\E[0m"
}

#以下为测试,使用时redecho "内容"
	redecho 1
	greenecho 1
	yellowecho 1
	blueecho 1
	redstrongecho 1
	greenstrongecho 1

案例32:给个人颜色函数库脚本中加入日志方便以后调用

32_func_diy.sh
下载
#!/bin/bash
##########################################
# File Name:/funcs/func_diy.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例32:给个人颜色函数库脚本中加入日志方便以后调用:
###########################################
#1.颜色函数
function redecho(){
        input="$@"
        echo -e "\E[1;31m${input}\E[0m"
}
function greenecho(){
        input="$@"
        echo -e "\E[1;32m${input}\E[0m"
}
function blueecho(){
        input="$@"
        echo -e "\E[1;36m${input}\E[0m"
}
function yellowecho(){
        input="$@"
        echo -e "\E[1;33m${input}\E[0m"
}
function redstrongecho(){
        input="$@"
        echo -e "\E[1;41m${input}\E[0m"
}
function greenstrongecho(){
        input="$@"
        echo -e "\E[1;42m${input}\E[0m"
}
#2.日志函数
function log() {
  log_file=$0.log
  level=$1
  msg=$2
  time=$(date +%F_%T)
  echo "$time [${level}] ${msg}" >> $log_file
}

案例33:检查指定地址的端口是否可以访问

33_check_port.sh
下载
#!/bin/bash
##########################################
# File Name:check_port.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例33:检查指定地址的端口是否可以访问
#use color funcs
source /funcs/func_diy.sh
###########################################
#1.vars
ip=$1
port=$2
#2.检查参数数量是否为2(ip+端口)
#这一步涉及到传参所以需要在主函数里加上$@
num_part(){
if [ $# -ne 2 ];then
redecho "Help: sh $0 IP PORT  "
exit 1
fi
}

#检查nc/telnet命令是否存在,不存在则安装
use_yum(){
if ! which nc &>/dev/null ;then
yum install -y nc &>/dev/null
fi
#yum install -y telnet &>/dev/null
}

#使用ping命令检查到目标ip之间是否通路
use_ping(){
if ! ping -c1 $ip &>/dev/null ;then
	redecho "this ip connect failed!"
	exit 2
fi
}
#检查端口格式(必须为数字)
check_port(){
if [[ ! $port =~ ^[0-9]+$ ]];then
	redecho "port $port is not exist! pls input number(1-65535) "
	exit 3
fi
}
#3.执行nc命令检查端口连接
use_nc(){
if nc -z ${ip} ${port} ;then
	greenecho "success! $ip $port is open"
else
	redecho "failed! $ip $port is closed "
fi
}


function main(){
num_part "$@"
use_yum
use_ping
check_port
use_nc
}
main "$@"

案例34:检查指定web/api是否可以访问

34_check_url.sh
下载
#!/bin/bash
##########################################
# File Name:34_check_url.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例34:检查指定web/api是否可以访问
#color func
source /funcs/func_diy.sh
###########################################
#1.vars
url=$1

#2.检查参数个数是否为1(空也退出)
check_var(){
if [ $# -ne 1 ]
then
	redecho "help: sh $0 xxx.com "
	exit 1
fi
}
#检查系统中是否有curl命令
yum_curl(){
if  ! which curl &>/dev/null ;then
	yum install -y curl &>/dev/null
fi
}

#检查到目标网站之间线路是否通畅
check_net(){
if ! ping -c1 $url &>/dev/null ;then
	echo "net connection failed! or $url is not exist! "
	exit 2
fi
}
#check [[ =~ ]] .com  可以加一步用正则匹配输入的是否为网站(xxx.com等格式)
#使用curl命令检查是否可以访问
check_url(){
if curl -s $url &>/dev/null ;then
	greenecho "$url  can see! "
else
	redecho "$url see failed! "
fi
}
main(){
check_var "$@"
yum_curl
check_net
check_url
}
main "$@"

案例35:检查域名是否过期

35_check_web_date.sh
下载
#!/bin/bash
##########################################
# File Name:35_check_web_date.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例35:检查域名是否过期 
#func
source /funcs/func_diy.sh
###########################################
#1 vars
#url=linuxjk.cn
#用下面的whois命令取出域名过期时间
# whois linuxjk.cn | egrep -i "(expiry date)|(expiration time)" | awk '{print $(NF-1),$NF}'
export LANG=en_US.UTF-8
url="$1"
if [ -z "$url" ]; then
  read -p "请输入域名(如 xxx.com): " url
fi
#2.检查参数是否为空
if [ -z "$url" ];then
	redecho "Help: sh $0 *.com/cn..."
	exit 1
fi
#取出当前的日期和域名过期日期
date_now=$(date "+%F %T")
date_check=$(whois "$url" 2>/dev/null | egrep -i "(expiry date)|(expiration time)" | awk -F'e: ' '{print $NF}')
if [ -z "$date_check" ]; then
  redecho "无法获取域名 $url 的到期时间"
  exit 2
fi
#3.用date +%s -d将两个日期都转化为秒
date_now_second=$(date +%s -d "$date_now")
date_check_second=$(date +%s -d "$date_check")

#4.测试是否成功转化为秒,此处如果有负数或空值说明转化失败
#echo $date_now_second
#echo $date_check_second


#5.用 awk/bc计算两个日期之间的差值(单位秒)
diff_second=$(awk -v a=$date_now_second -v b=$date_check_second 'BEGIN{print b-a}')
#6.差值转化为天
diff_day=$(awk -v a=$diff_second 'BEGIN{print a/60/60/24}')
diff_month=$(awk -v a=$diff_second 'BEGIN{print a/60/60/24/30}')
diff_year=$(awk -v a=$diff_second 'BEGIN{print a/60/60/24/30/12}')
#7.输出信息
#echo "$url have $diff_day day, =$diff_month month, = $diff_year year"
#if [ $diff_day -ge 60 ];then
if (( $(echo "$diff_day >= 60" | bc -l) )); then
	greenecho "域名$url  还有$diff_day 天到期, 还有 $diff_month月到期, 还有$diff_year年到期"
else
	redecho "请及时续费;"
	redecho "域名$url  还有$diff_day 天到期, 还有 $diff_month月到期, 还有$diff_year年到期"
fi

案例36:使用for循环在/oldboy目录下通过随机的10个小写字母加固定字符oldboy批量创建十个html文件

36_random_file.sh
下载
#!/bin/bash
##########################################
# File Name:36_random_file.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例36:使用for循环在/oldboy目录下通过随的10个小写字母加固定字符oldboy批量创建十个html文件
###########################################
#1.vars
fixed=linux
dir=/oldboy/
#检查目录是否为空,为空则创建
if [ ! -d ${dir} ];then
	mkdir -p $dir
fi
#2.run for
for i in {1..10}
do
#利用两种方法取出10个随机小写字母
file=$(mkpasswd-expect -l 10 -d 0 -s 0 -C 0 )
  #file=$(tr -cd 'a-zA-Z0-9' </dev/urandom | head -c10)
  touch ${dir}${file}_${fixed}.html
done

用for循环打印99乘法表

99.sh
下载
#!/bin/bash
##########################################
# File Name:99.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:利用简单的for循环打印九九乘法表
###########################################
#vars
i=1
j=1

for i in {1..9}
do
	for j in {1..9}
	do
		#printf "%d*%d=%-2d " $i $j $((i*j))
		result=`echo -n "$i*$j"|xargs |bc`
		echo -n "$i*$j=$result "
	done
	echo 
done

案例37:输出1到10并计算总和(条件:循环次数等于10)

37_while_for.sh
下载
#!/bin/bash
##########################################
# File Name:37_while_for.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例37:输出1到10并计算总和(条件:循环次数等于10)
###########################################
#vars
i=1
sum=0
#循环执行条件:i<=10,不满足则结束循环
while [ $i -le 10 ]
do
	echo $i
	let sum=sum+i
	let i++  #控制循环次数
done

echo "总和: $sum"

#for i in {1..10}
#do
#echo $i
#done

案例39:生成随机数字(1-100),判断数字是什么

39_guess_number.sh
下载
#!/bin/bash
##########################################
# File Name:39_guess_number.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例39:生成随机数字(1-100),判断数字是什么
###########################################
#vars
correct_answer=$(echo "$RANDOM%100+1" | bc)
guess=0
#可以用while后面的条件控制循环,当满足猜的数不等于正确答案时进行循环
#while [ $guess -ne $correct_answer ];
#或者用下面的死循环表示,while true,但是当猜的数等于正确答案时输出信息并退出脚本
while true
do
	#read
	read -p "pls input a number: " guess
	#check input ? number
	if  [[ ! $guess =~ [0-9]+ ]];then
		echo "please input number! "
		#continue只跳过这一次输入错误的情况,重新输入,break退出循环,exit退出脚本
		continue
	fi
	let i++
	if [ $guess -lt $correct_answer ];then
		echo "your number is small "
	elif [ $guess -gt $correct_answer ];then
		echo "your number is big "
	else
		echo "correct !!! answer is $correct_answer"
		echo "total guess $i times"
		#下面的exit退出脚本可以改为在这里用break退出循环,下面的判断和输出放在循环外执行
	if [ $i -ge 1 ] && [ $i -le 3 ] ;then	
		echo "better than 99.99% person "
	elif [ $i -ge 4 ] && [ $i -le 6 ];then
		echo "better than 80% person "
	else 
		echo "better than 70% person "
	fi
	exit
	fi	
done

案例40:通过while read方式统计ip.txt文件,并ping文件中的ip(以后ping改成firewalld屏蔽)

40_while_ip_ping.sh
下载
#!/bin/bash
##########################################
# File Name:40_while_ip_ping.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例40:通过while read方式统计ip.txt文件,并ping文件中的ip(以后ping改成firewalld屏蔽)
#funcs
source /funcs/func_diy.sh
###########################################
#vars
src_file=/oldboy/files/ip.txt
#while
while read line
do
	ip=`echo $line | awk -F' ' '{print $1}'`
	num=`echo $line | awk -F' ' '{print $2}'`
       if [ $num -ge 5 ];then
	       ping -c1 $ip &>/dev/null
	       if [ $? -eq 0 ];then
		       greenecho "ping $ip successed"
	       else
		       redecho "ping $ip failed"
	       fi
       fi 

done <$src_file
#while read ip num  只有空格分隔的两列可以这样只定义两个变量,如本案例中的ip 次数
#do
#       #echo "ip address: $ip"
#       if [ $num -ge 8 ];then
#	       ping -c1 $ip &>/dev/null
#       fi 
#done <$src_file

案例41:了解方法2和方法3区别:在while前读取命令和在done后用重定向符<读取文件

41_test_while_read.sh
下载
#!/bin/bash
##########################################
# File Name:41_test_while_read.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:了解方法2和方法3区别:在while前读取命令和在done后用重定向符<读取文件
###########################################
#vars
file=/oldboy/files/ip.txt

i=0
j=0
#方法2,利用管道传递,while处理管道内容,循环次数为0
echo "method 2: while + cat"
cat $file | while read ip 
do
	echo $ip
	let i++
done
echo "times: $i"


#方法3,用输入重定向<输入至while中,循环次数为文件行数
echo "method 3: while + <"
while read ipaddr
do
       echo $ipaddr
       let j++
done <$file
echo "times: $j"

案例41:for/while/ until三种循环格式区别及循环条件分析

41_do_until.sh
下载
#!/bin/bash
##########################################
# File Name:do_until.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例41:for/while/ until三种循环格式区别及循环条件分析
###########################################
#vars

echo "until"
#直到变量i大于10时停止,输出1-10
i=1
until [ $i -gt 10 ]
do
	echo $i
	let i++
done
echo "while"
#满足变量j小于等于10的条件时循环,输出1-10
j=1
while [ $j -le 10 ]
do
	echo $j
	let j++
done
echo "for"
#变量m在1-10的范围内进行循环,输出1-10
for m in {1..10}
do
	echo $m
done

案例42:测试read命令赋值数组并输出数组中的内容

42_read_create_array.sh
下载
#!/bin/bash
##########################################
# File Name:42_read_create_array.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例42:测试read赋值数组并输出数组中的内容
###########################################
#定义数组变量
read -p "请输入数组,空格分隔: " -a array
#测试刚才输入的数组是否可以正常输出
echo ${array[@]}
#测试分割情况(是否一次输出一个)
for i in  ${array[@]}
do
	echo $i
done

案例43:试编写一个shell计算器,求出用户输入所有数字的以下计算结果:总和,平均值,最大值,最小值

43_array_calculate.sh
下载
#!/bin/bash
##########################################
# File Name:43_array_calculate.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例43:求出数组中的值的总和,平均值,最大值,最小值
source /funcs/func_diy.sh
###########################################

#1.vars
function input(){
read -p "请输入需要计算的数字,以空格分割,不限制个数:  " -a array
}

#2.检查数组是否为空
function check_z(){
if [ -z $array ];then
	redecho "未获取到内容,请重新输入! "
	exit 1
fi
}

#易错提示:检查输入的数组是否为数字
#(错误,这里的正则匹配会将整个数组合成一个整体的字符串进行正则匹配,
#无法逐个检测数组中的元素是否为数字)
#if [[ ! ${array[@]} =~ ^[+-]?[0-9]+\.?[0-9]+$ ]];then
#	echo "格式错误,请输入数字! "
#	exit 2
#fi

#下面的错误为如果碰到异常数据会直接退出脚本,不会继续运算
#function check_isnumber(){
#for num in "${array[@]}"
#do
#    # 允许整数、小数、负数,排除空值
#    if [[ ! $num =~ ^[+-]?[0-9]+([.][0-9]+)?$ ]] || [[ $num == '.'* ]] || [[ $num == *'.' ]]; then
#        redecho "错误:'$num' 不是有效的数字!"
#        exit 2
#
#    fi
#done
#}

#3.检查数组中的每个值是否为数字,如果有不是数字的进行提示并跳过这一项,继续进行下面的值的计算,
#得到一个过滤异常数据之后的新数组
i=0
#从下标0开始传入数据
function check_isnumber(){
for num in "${array[@]}"
do
	if [[ ! $num =~ ^[+-]?[0-9]+([.][0-9]+)?$ ]] || [[ $num == '.'* ]] || [[ $num == *'.' ]]; then
		redecho "错误!$num 不是有效的数字,此项无法参与运算"
		continue
	else
		newarray[i]=$num
		let i++
	fi
done
}
echo ${newarray[@]}
#4.开始计算
function  calculate(){
total=$(echo ${newarray[@]} | tr -s ' ' '+' |bc -l)
averavg=$(awk -v a=${total} -v b=${#newarray[@]} 'BEGIN{print a/b}')
max=$(echo ${newarray[@]} | sed 's# #\n#g' | sort -rn | head -n1)
min=$(echo ${newarray[@]} | sed 's# #\n#g' | sort -n | head -n1)
}

#5.输出结果
function output(){
cat<<EOF
数组中的值的计算结果如下:
总和:$total
平均值:$averavg
最大值:$max
最小值:$min
EOF
}


function main(){
	input "$@"
	check_z
	check_isnumber
	calculate
	output
}
main

案例44:把案例30改为数组形式,从server/files/urls.txt读取内容

44_check_ip_func.sh
下载
#!/bin/bash
##########################################
# File Name:42_check_ip_func.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例42:将案例30改为数组形式,从指定文件/server/files/urls.txt读取内容
#cat /server/files/urls.txt
#10.0.0.200
#jd.com
#baidu.com
#taobao.com
#linuxjk.cn
#12306.cn
source /funcs/func_diy.sh
###########################################


#1.vars:
function input_urls(){
urls=(`cat /server/files/urls.txt`)
}
#2.检查参数个数是否为0(是否为空),数组用于检查是否为空时可以和变量用法相同

function check_urls(){

if [ -z $urls ];then
	echo "error"
	exit 1
fi

#if [ ${#urls[@]} -eq 0 ];then
#	echo "Help: 未取出正确的url供本脚本检测,请检查脚本! "
#	exit 1
#fi
}
#2.执行ping命令并判断返回值检测此域名是否能ping通
function ping_if(){
	ping -c1 ${url} &>/dev/null
	if [ $? -eq 0 ]
	then
		greenecho "$url 可以访问"
	else
		redecho "$url 不可以访问"
	fi
}
#3.for
function for_urls(){
for url in ${urls[@]}
do
	ping_if
done
return 0
}

#4.运行上面的函数
function main(){
input_urls
check_urls
for_urls
}
main

案例53:用awk统计ip和每个ip对应的流量,取流量排行前50名进行地址查询和单位换算

53_uniq_ip_times.sh
下载
#!/bin/bash
##########################################
# File Name: 53_uniq_ip_times.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:用awk统计ip和每个ip对应的流量,取流量排行前50名进行地址查询和单位换算
###########################################

#1.vars
file=/server/files/access.log
awk_deal=(`awk '{url[$1]=url[$1]+$10}END{for(n in url)print n,url[n]}' $file | sort -rnk2 | head -50`)
count=0
for i in ${awk_deal[@]}
do
        if (( count % 2 == 0 ));then
                echo -n "ipaddress: $i   "
                echo `curl -s cip.cc/${i} | sed -n '2p'`
                sleep 1.5
        else
                echo -n `awk -v a=$i 'BEGIN{print a/1000/1000}'`
                echo " MB"
        fi
        let count++
done
滚动至顶部