Shell脚本编写及常见面试题(一)
来源:互联网 发布:网络销售每天做什么 编辑:程序博客网 时间:2024/05/16 17:46
注意事项
1)开头加解释器:#!/bin/bash
2)语法缩进,使用四个空格;多加注释说明。
3)命名建议规则:变量名大写、局部变量小写,函数名小写,名字体现出实际作用。
4)默认变量是全局的,在函数中变量local指定为局部变量,避免污染其他作用域。
5)有两个命令能帮助我调试脚本:set -e 遇到执行非0时退出脚本,set-x 打印执行过程。
6)写脚本一定先测试再到生产上。
本章目录:
12.1 获取随机字符串或数字
获取随机8位字符串:
1
2
3
4
5
6
7
8
9
方法1:
# echo $RANDOM |md5sum |cut -c 1-8
471b94f2
方法2:
# openssl rand -base64 4
vg3BEg==
方法3:
# cat /proc/sys/kernel/random/uuid |cut -c 1-8
ed9e032c
获取随机8位数字:
1
2
3
4
5
6
7
8
9
方法1:
# echo $RANDOM |cksum |cut -c 1-8
23648321
方法2:
# openssl rand -base64 4 |cksum |cut -c 1-8
38571131
方法3:
# date +%N |cut -c 1-8
69024815
cksum:打印CRC效验和统计字节
12.2 定义一个颜色输出字符串函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
方法1:
function
echo_color() {
if
[ $1 ==
"green"
];
then
echo
-e
"\033[32;40m$2\033[0m"
elif
[ $1 ==
"red"
];
then
echo
-e
"\033[31;40m$2\033[0m"
fi
}
方法2:
function
echo_color() {
case
$1
in
green)
echo
-e
"\033[32;40m$2\033[0m"
;;
red)
echo
-e
"\033[31;40m$2\033[0m"
;;
*)
echo
"Example: echo_color red string"
esac
}
使用方法:echo_color green
"test"
function关键字定义一个函数,可加或不加。
12.3 批量创建用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash
DATE=$(
date
+%F_%T)
USER_FILE=user.txt
echo_color(){
if
[ $1 ==
"green"
];
then
echo
-e
"\033[32;40m$2\033[0m"
elif
[ $1 ==
"red"
];
then
echo
-e
"\033[31;40m$2\033[0m"
fi
}
# 如果用户文件存在并且大小大于0就备份
if
[ -s $USER_FILE ];
then
mv
$USER_FILE ${USER_FILE}-${DATE}.bak
echo_color green
"$USER_FILE exist, rename ${USER_FILE}-${DATE}.bak"
fi
echo
-e
"User\tPassword"
>> $USER_FILE
echo
"----------------"
>> $USER_FILE
for
USER
in
user{1..10};
do
if
!
id
$USER &>
/dev/null
;
then
PASS=$(
echo
$RANDOM |md5sum |
cut
-c 1-8)
useradd
$USER
echo
$PASS |
passwd
--stdin $USER &>
/dev/null
echo
-e
"$USER\t$PASS"
>> $USER_FILE
echo
"$USER User create successful."
else
echo_color red
"$USER User already exists!"
fi
done
12.4 检查软件包是否安装
1
2
3
4
5
6
#!/bin/bash
if
rpm -q sysstat &>
/dev/null
;
then
echo
"sysstat is already installed."
else
echo
"sysstat is not installed!"
fi
12.5 检查服务状态
1
2
3
4
5
6
#!/bin/bash
PORT_C=$(ss -anu |
grep
-c 123)
PS_C=$(
ps
-ef |
grep
ntpd |
grep
-vc
grep
)
if
[ $PORT_C -
eq
0 -o $PS_C -
eq
0 ];
then
echo
"内容"
| mail -s
"主题"
dst@example.com
fi
12.6 检查主机存活状态
方法1:将错误IP放到数组里面判断是否ping失败三次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
IP_LIST=
"192.168.18.1 192.168.1.1 192.168.18.2"
for
IP
in
$IP_LIST;
do
NUM=1
while
[ $NUM -
le
3 ];
do
if
ping
-c 1 $IP >
/dev/null
;
then
echo
"$IP Ping is successful."
break
else
# echo "$IP Ping is failure $NUM"
FAIL_COUNT[$NUM]=$IP
let
NUM++
fi
done
if
[ ${
#FAIL_COUNT[*]} -eq 3 ];then
echo
"${FAIL_COUNT[1]} Ping is failure!"
unset
FAIL_COUNT[*]
fi
done
方法2:将错误次数放到FAIL_COUNT变量里面判断是否ping失败三次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
IP_LIST=
"192.168.18.1 192.168.1.1 192.168.18.2"
for
IP
in
$IP_LIST;
do
FAIL_COUNT=0
for
((i=1;i<=3;i++));
do
if
ping
-c 1 $IP >
/dev/null
;
then
echo
"$IP Ping is successful."
break
else
# echo "$IP Ping is failure $i"
let
FAIL_COUNT++
fi
done
if
[ $FAIL_COUNT -
eq
3 ];
then
echo
"$IP Ping is failure!"
fi
done
方法3:利用for循环将ping通就跳出循环继续,如果不跳出就会走到打印ping失败
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
ping_success_status() {
if
ping
-c 1 $IP >
/dev/null
;
then
echo
"$IP Ping is successful."
continue
fi
}
IP_LIST=
"192.168.18.1 192.168.1.1 192.168.18.2"
for
IP
in
$IP_LIST;
do
ping_success_status
ping_success_status
ping_success_status
echo
"$IP Ping is failure!"
done
12.7 监控CPU、内存和硬盘利用率
1)CPU
借助vmstat工具来分析CPU统计信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
DATE=$(
date
+%F
" "
%H:%M)
IP=$(
ifconfig
eth0 |
awk
-F
'[ :]+'
'/inet addr/{print $4}'
)
# 只支持CentOS6
MAIL=
"example@mail.com"
if
!
which
vmstat &>
/dev/null
;
then
echo
"vmstat command no found, Please install procps package."
exit
1
fi
US=$(vmstat |
awk
'NR==3{print $13}'
)
SY=$(vmstat |
awk
'NR==3{print $14}'
)
IDLE=$(vmstat |
awk
'NR==3{print $15}'
)
WAIT=$(vmstat |
awk
'NR==3{print $16}'
)
USE=$(($US+$SY))
if
[ $USE -
ge
50 ];
then
echo
"
Date: $DATE
Host: $IP
Problem: CPU utilization $USE
" | mail -s "
CPU Monitor" $MAIL
fi
2)内存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
DATE=$(
date
+%F
" "
%H:%M)
IP=$(
ifconfig
eth0 |
awk
-F
'[ :]+'
'/inet addr/{print $4}'
)
MAIL=
"example@mail.com"
TOTAL=$(
free
-m |
awk
'/Mem/{print $2}'
)
USE=$(
free
-m |
awk
'/Mem/{print $3-$6-$7}'
)
FREE=$(($TOTAL-$USE))
# 内存小于1G发送报警邮件
if
[ $FREE -lt 1024 ];
then
echo
"
Date: $DATE
Host: $IP
Problem: Total=$TOTAL,Use=$USE,Free=$FREE
" | mail -s "
Memory Monitor" $MAIL
fi
3)硬盘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
DATE=$(
date
+%F
" "
%H:%M)
IP=$(
ifconfig
eth0 |
awk
-F
'[ :]+'
'/inet addr/{print $4}'
)
MAIL=
"example@mail.com"
TOTAL=$(
fdisk
-l |
awk
-F
'[: ]+'
'BEGIN{OFS="="}/^Disk \/dev/{printf "%s=%sG,",$2,$3}'
)
PART_USE=$(
df
-h |
awk
'BEGIN{OFS="="}/^\/dev/{print $1,int($5),$6}'
)
for
i
in
$PART_USE;
do
PART=$(
echo
$i |
cut
-d
"="
-f1)
USE=$(
echo
$i |
cut
-d
"="
-f2)
MOUNT=$(
echo
$i |
cut
-d
"="
-f3)
if
[ $USE -gt 80 ];
then
echo
"
Date: $DATE
Host: $IP
Total: $TOTAL
Problem: $PART=$USE($MOUNT)
" | mail -s "
Disk Monitor" $MAIL
fi
done
12.8 批量主机磁盘利用率监控
前提监控端和被监控端SSH免交互登录或者密钥登录。
写一个配置文件保存被监控主机SSH连接信息,文件内容格式:IP User Port
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
HOST_INFO=host.info
for
IP
in
$(
awk
'/^[^#]/{print $1}'
$HOST_INFO);
do
USER=$(
awk
-
v
ip=$IP
'ip==$1{print $2}'
$HOST_INFO)
PORT=$(
awk
-
v
ip=$IP
'ip==$1{print $3}'
$HOST_INFO)
TMP_FILE=
/tmp/disk
.tmp
ssh
-p $PORT $USER@$IP
'df -h'
> $TMP_FILE
USE_RATE_LIST=$(
awk
'BEGIN{OFS="="}/^\/dev/{print $1,int($5)}'
$TMP_FILE)
for
USE_RATE
in
$USE_RATE_LIST;
do
PART_NAME=${USE_RATE%=*}
USE_RATE=${USE_RATE
#*=}
if
[ $USE_RATE -
ge
80 ];
then
echo
"Warning: $PART_NAME Partition usage $USE_RATE%!"
fi
done
done
12.9 检查网站可用性
1)检查URL可用性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
方法1:
check_url() {
HTTP_CODE=$(curl -o
/dev/null
--connect-timeout 3 -s -w
"%{http_code}"
$1)
if
[ $HTTP_CODE -
ne
200 ];
then
echo
"Warning: $1 Access failure!"
fi
}
方法2:
check_url() {
if
! wget -T 10 --tries=1 --spider $1 >
/dev/null
2>&1;
then
#-T超时时间,--tries尝试1次,--spider爬虫模式
echo
"Warning: $1 Access failure!"
fi
}
使用方法:check_url www.baidu.com
2)判断三次URL可用性
思路与上面检查主机存活状态一样。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
方法1:利用循环技巧,如果成功就跳出当前循环,否则执行到最后一行
#!/bin/bash
check_url() {
HTTP_CODE=$(curl -o
/dev/null
--connect-timeout 3 -s -w
"%{http_code}"
$1)
if
[ $HTTP_CODE -
eq
200 ];
then
continue
fi
}
URL_LIST=
"www.baidu.com www.agasgf.com"
for
URL
in
$URL_LIST;
do
check_url $URL
check_url $URL
check_url $URL
echo
"Warning: $URL Access failure!"
done
方法2:错误次数保存到变量
#!/bin/bash
URL_LIST=
"www.baidu.com www.agasgf.com"
for
URL
in
$URL_LIST;
do
FAIL_COUNT=0
for
((i=1;i<=3;i++));
do
HTTP_CODE=$(curl -o
/dev/null
--connect-timeout 3 -s -w
"%{http_code}"
$URL)
if
[ $HTTP_CODE -
ne
200 ];
then
let
FAIL_COUNT++
else
break
fi
done
if
[ $FAIL_COUNT -
eq
3 ];
then
echo
"Warning: $URL Access failure!"
fi
done
方法3:错误次数保存到数组
#!/bin/bash
URL_LIST=
"www.baidu.com www.agasgf.com"
for
URL
in
$URL_LIST;
do
NUM=1
while
[ $NUM -
le
3 ];
do
HTTP_CODE=$(curl -o
/dev/null
--connect-timeout 3 -s -w
"%{http_code}"
$URL)
if
[ $HTTP_CODE -
ne
200 ];
then
FAIL_COUNT[$NUM]=$IP
#创建数组,以$NUM下标,$IP元素
let
NUM++
else
break
fi
done
if
[ ${
#FAIL_COUNT[*]} -eq 3 ]; then
echo
"Warning: $URL Access failure!"
unset
FAIL_COUNT[*]
#清空数组
fi
done
12.10 检查MySQL主从同步状态
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
USER=bak
PASSWD=123456
IO_SQL_STATUS=$(mysql -u$USER -p$PASSWD -e
'show slave status\G'
|
awk
-F:
'/Slave_.*_Running/{gsub(": ",":");print $0}'
)
#gsub去除冒号后面的空格
for
i
in
$IO_SQL_STATUS;
do
THREAD_STATUS_NAME=${i%:*}
THREAD_STATUS=${i
#*:}
if
[
"$THREAD_STATUS"
!=
"Yes"
];
then
echo
"Error: MySQL Master-Slave $THREAD_STATUS_NAME status is $THREAD_STATUS!"
fi
done
阅读全文
0 0
- Shell脚本编写及常见面试题(一)
- Shell脚本编写及常见面试题(二)
- Shell脚本编写及常见面试题(三)
- Shell脚本常见面试题
- 常见面试题及答案(一)
- shell 常见面试题及答案(1)
- shell 常见面试题及答案(2)
- shell 常见面试题及答案(3)
- shell 常见面试题及答案(4)
- 几个shell脚本的面试题(一)
- [ 面试题 ] 常见面试题 (一)
- shell脚本编写(一)
- shell 脚本 面试题
- 常见面试题(一)
- 常见面试题(一)
- java常见面试题及答案(一)
- HTML5常见面试题及答案(一)
- 常见C++面试题及基本知识点总结(一)
- Name for argument type [java.lang.String] not available, and parameter name information not found in
- 轮播
- Eclipse中tomcat访问本地文件
- Leetcode 题目记录:231,342,191, 190,172,258,292
- 软件建设与城市建设的相似性
- Shell脚本编写及常见面试题(一)
- c++设计模式
- 判断线段相交并求交点
- vue自定义过滤器
- 极大似然估计
- MFC_CListCtrl 列表控件(常用)
- 加入键盘鼠标控制的代码
- BZOJ 4385 Wilcze doły
- Shell脚本编写及常见面试题(二)